ActivityManagerService.java revision a1b79bfd7a15006a93da933695359765e0fee495
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.DEBUG_WHITELISTS;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
349import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
350import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
351import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
352import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
353import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
354import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
355import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
356import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
357import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
360import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
362import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
366import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
367import static org.xmlpull.v1.XmlPullParser.START_TAG;
368
369public final class ActivityManagerService extends ActivityManagerNative
370        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
371
372    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
373    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
374    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
375    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
376    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
377    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
378    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
379    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
380    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
381    private static final String TAG_LRU = TAG + POSTFIX_LRU;
382    private static final String TAG_MU = TAG + POSTFIX_MU;
383    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
384    private static final String TAG_POWER = TAG + POSTFIX_POWER;
385    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
386    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
387    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
388    private static final String TAG_PSS = TAG + POSTFIX_PSS;
389    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
390    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
391    private static final String TAG_STACK = TAG + POSTFIX_STACK;
392    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
393    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
394    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
395    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
396    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
397
398    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
399    // here so that while the job scheduler can depend on AMS, the other way around
400    // need not be the case.
401    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
402
403    /** Control over CPU and battery monitoring */
404    // write battery stats every 30 minutes.
405    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
406    static final boolean MONITOR_CPU_USAGE = true;
407    // don't sample cpu less than every 5 seconds.
408    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
409    // wait possibly forever for next cpu sample.
410    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
411    static final boolean MONITOR_THREAD_CPU_USAGE = false;
412
413    // The flags that are set for all calls we make to the package manager.
414    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
415
416    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
417
418    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
419
420    // Amount of time after a call to stopAppSwitches() during which we will
421    // prevent further untrusted switches from happening.
422    static final long APP_SWITCH_DELAY_TIME = 5*1000;
423
424    // How long we wait for a launched process to attach to the activity manager
425    // before we decide it's never going to come up for real.
426    static final int PROC_START_TIMEOUT = 10*1000;
427    // How long we wait for an attached process to publish its content providers
428    // before we decide it must be hung.
429    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
430
431    // How long we will retain processes hosting content providers in the "last activity"
432    // state before allowing them to drop down to the regular cached LRU list.  This is
433    // to avoid thrashing of provider processes under low memory situations.
434    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
435
436    // How long we wait for a launched process to attach to the activity manager
437    // before we decide it's never going to come up for real, when the process was
438    // started with a wrapper for instrumentation (such as Valgrind) because it
439    // could take much longer than usual.
440    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
441
442    // How long to wait after going idle before forcing apps to GC.
443    static final int GC_TIMEOUT = 5*1000;
444
445    // The minimum amount of time between successive GC requests for a process.
446    static final int GC_MIN_INTERVAL = 60*1000;
447
448    // The minimum amount of time between successive PSS requests for a process.
449    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process
452    // when the request is due to the memory state being lowered.
453    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
454
455    // The rate at which we check for apps using excessive power -- 15 mins.
456    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
457
458    // The minimum sample duration we will allow before deciding we have
459    // enough data on wake locks to start killing things.
460    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on CPU usage to start killing things.
464    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // How long we allow a receiver to run before giving up on it.
467    static final int BROADCAST_FG_TIMEOUT = 10*1000;
468    static final int BROADCAST_BG_TIMEOUT = 60*1000;
469
470    // How long we wait until we timeout on key dispatching.
471    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
472
473    // How long we wait until we timeout on key dispatching during instrumentation.
474    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
475
476    // This is the amount of time an app needs to be running a foreground service before
477    // we will consider it to be doing interaction for usage stats.
478    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
479
480    // Maximum amount of time we will allow to elapse before re-reporting usage stats
481    // interaction with foreground processes.
482    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
483
484    // This is the amount of time we allow an app to settle after it goes into the background,
485    // before we start restricting what it can do.
486    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
487
488    // How long to wait in getAssistContextExtras for the activity and foreground services
489    // to respond with the result.
490    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
491
492    // How long top wait when going through the modern assist (which doesn't need to block
493    // on getting this result before starting to launch its UI).
494    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
495
496    // Maximum number of persisted Uri grants a package is allowed
497    static final int MAX_PERSISTED_URI_GRANTS = 128;
498
499    static final int MY_PID = Process.myPid();
500
501    static final String[] EMPTY_STRING_ARRAY = new String[0];
502
503    // How many bytes to write into the dropbox log before truncating
504    static final int DROPBOX_MAX_SIZE = 256 * 1024;
505
506    // Access modes for handleIncomingUser.
507    static final int ALLOW_NON_FULL = 0;
508    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
509    static final int ALLOW_FULL_ONLY = 2;
510
511    // Delay in notifying task stack change listeners (in millis)
512    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
513
514    // Necessary ApplicationInfo flags to mark an app as persistent
515    private static final int PERSISTENT_MASK =
516            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
517
518    // Intent sent when remote bugreport collection has been completed
519    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
520            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
521
522    // Delay to disable app launch boost
523    static final int APP_BOOST_MESSAGE_DELAY = 3000;
524    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
525    static final int APP_BOOST_TIMEOUT = 2500;
526
527    // Used to indicate that a task is removed it should also be removed from recents.
528    private static final boolean REMOVE_FROM_RECENTS = true;
529    // Used to indicate that an app transition should be animated.
530    static final boolean ANIMATE = true;
531
532    // Determines whether to take full screen screenshots
533    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
534    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
535
536    private static native int nativeMigrateToBoost();
537    private static native int nativeMigrateFromBoost();
538    private boolean mIsBoosted = false;
539    private long mBoostStartTime = 0;
540
541    /** All system services */
542    SystemServiceManager mSystemServiceManager;
543
544    private Installer mInstaller;
545
546    /** Run all ActivityStacks through this */
547    final ActivityStackSupervisor mStackSupervisor;
548
549    final ActivityStarter mActivityStarter;
550
551    /** Task stack change listeners. */
552    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
553            new RemoteCallbackList<ITaskStackListener>();
554
555    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
556
557    public IntentFirewall mIntentFirewall;
558
559    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
560    // default actuion automatically.  Important for devices without direct input
561    // devices.
562    private boolean mShowDialogs = true;
563    private boolean mInVrMode = false;
564
565    BroadcastQueue mFgBroadcastQueue;
566    BroadcastQueue mBgBroadcastQueue;
567    // Convenient for easy iteration over the queues. Foreground is first
568    // so that dispatch of foreground broadcasts gets precedence.
569    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
570
571    BroadcastQueue broadcastQueueForIntent(Intent intent) {
572        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
573        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
574                "Broadcast intent " + intent + " on "
575                + (isFg ? "foreground" : "background") + " queue");
576        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
577    }
578
579    /**
580     * Activity we have told the window manager to have key focus.
581     */
582    ActivityRecord mFocusedActivity = null;
583
584    /**
585     * User id of the last activity mFocusedActivity was set to.
586     */
587    private int mLastFocusedUserId;
588
589    /**
590     * If non-null, we are tracking the time the user spends in the currently focused app.
591     */
592    private AppTimeTracker mCurAppTimeTracker;
593
594    /**
595     * List of intents that were used to start the most recent tasks.
596     */
597    final RecentTasks mRecentTasks;
598
599    /**
600     * For addAppTask: cached of the last activity component that was added.
601     */
602    ComponentName mLastAddedTaskComponent;
603
604    /**
605     * For addAppTask: cached of the last activity uid that was added.
606     */
607    int mLastAddedTaskUid;
608
609    /**
610     * For addAppTask: cached of the last ActivityInfo that was added.
611     */
612    ActivityInfo mLastAddedTaskActivity;
613
614    /**
615     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
616     */
617    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
618
619    /**
620     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
621     */
622    String mDeviceOwnerName;
623
624    final UserController mUserController;
625
626    final AppErrors mAppErrors;
627
628    boolean mDoingSetFocusedActivity;
629
630    public boolean canShowErrorDialogs() {
631        return mShowDialogs && !mSleeping && !mShuttingDown;
632    }
633
634    // it's a semaphore; boost when 0->1, reset when 1->0
635    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
636        @Override protected Integer initialValue() {
637            return 0;
638        }
639    };
640
641    static void boostPriorityForLockedSection() {
642        if (sIsBoosted.get() == 0) {
643            // boost to prio 118 while holding a global lock
644            Process.setThreadPriority(Process.myTid(), -2);
645            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
646        }
647        int cur = sIsBoosted.get();
648        sIsBoosted.set(cur + 1);
649    }
650
651    static void resetPriorityAfterLockedSection() {
652        sIsBoosted.set(sIsBoosted.get() - 1);
653        if (sIsBoosted.get() == 0) {
654            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
655            Process.setThreadPriority(Process.myTid(), 0);
656        }
657    }
658    public class PendingAssistExtras extends Binder implements Runnable {
659        public final ActivityRecord activity;
660        public final Bundle extras;
661        public final Intent intent;
662        public final String hint;
663        public final IResultReceiver receiver;
664        public final int userHandle;
665        public boolean haveResult = false;
666        public Bundle result = null;
667        public AssistStructure structure = null;
668        public AssistContent content = null;
669        public Bundle receiverExtras;
670
671        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
672                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
673            activity = _activity;
674            extras = _extras;
675            intent = _intent;
676            hint = _hint;
677            receiver = _receiver;
678            receiverExtras = _receiverExtras;
679            userHandle = _userHandle;
680        }
681        @Override
682        public void run() {
683            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
684            synchronized (this) {
685                haveResult = true;
686                notifyAll();
687            }
688            pendingAssistExtrasTimedOut(this);
689        }
690    }
691
692    final ArrayList<PendingAssistExtras> mPendingAssistExtras
693            = new ArrayList<PendingAssistExtras>();
694
695    /**
696     * Process management.
697     */
698    final ProcessList mProcessList = new ProcessList();
699
700    /**
701     * All of the applications we currently have running organized by name.
702     * The keys are strings of the application package name (as
703     * returned by the package manager), and the keys are ApplicationRecord
704     * objects.
705     */
706    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
707
708    /**
709     * Tracking long-term execution of processes to look for abuse and other
710     * bad app behavior.
711     */
712    final ProcessStatsService mProcessStats;
713
714    /**
715     * The currently running isolated processes.
716     */
717    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
718
719    /**
720     * Counter for assigning isolated process uids, to avoid frequently reusing the
721     * same ones.
722     */
723    int mNextIsolatedProcessUid = 0;
724
725    /**
726     * The currently running heavy-weight process, if any.
727     */
728    ProcessRecord mHeavyWeightProcess = null;
729
730    /**
731     * All of the processes we currently have running organized by pid.
732     * The keys are the pid running the application.
733     *
734     * <p>NOTE: This object is protected by its own lock, NOT the global
735     * activity manager lock!
736     */
737    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
738
739    /**
740     * All of the processes that have been forced to be foreground.  The key
741     * is the pid of the caller who requested it (we hold a death
742     * link on it).
743     */
744    abstract class ForegroundToken implements IBinder.DeathRecipient {
745        int pid;
746        IBinder token;
747    }
748    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
749
750    /**
751     * List of records for processes that someone had tried to start before the
752     * system was ready.  We don't start them at that point, but ensure they
753     * are started by the time booting is complete.
754     */
755    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
756
757    /**
758     * List of persistent applications that are in the process
759     * of being started.
760     */
761    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
762
763    /**
764     * Processes that are being forcibly torn down.
765     */
766    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
767
768    /**
769     * List of running applications, sorted by recent usage.
770     * The first entry in the list is the least recently used.
771     */
772    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
773
774    /**
775     * Where in mLruProcesses that the processes hosting activities start.
776     */
777    int mLruProcessActivityStart = 0;
778
779    /**
780     * Where in mLruProcesses that the processes hosting services start.
781     * This is after (lower index) than mLruProcessesActivityStart.
782     */
783    int mLruProcessServiceStart = 0;
784
785    /**
786     * List of processes that should gc as soon as things are idle.
787     */
788    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
789
790    /**
791     * Processes we want to collect PSS data from.
792     */
793    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
794
795    private boolean mBinderTransactionTrackingEnabled = false;
796
797    /**
798     * Last time we requested PSS data of all processes.
799     */
800    long mLastFullPssTime = SystemClock.uptimeMillis();
801
802    /**
803     * If set, the next time we collect PSS data we should do a full collection
804     * with data from native processes and the kernel.
805     */
806    boolean mFullPssPending = false;
807
808    /**
809     * This is the process holding what we currently consider to be
810     * the "home" activity.
811     */
812    ProcessRecord mHomeProcess;
813
814    /**
815     * This is the process holding the activity the user last visited that
816     * is in a different process from the one they are currently in.
817     */
818    ProcessRecord mPreviousProcess;
819
820    /**
821     * The time at which the previous process was last visible.
822     */
823    long mPreviousProcessVisibleTime;
824
825    /**
826     * Track all uids that have actively running processes.
827     */
828    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
829
830    /**
831     * This is for verifying the UID report flow.
832     */
833    static final boolean VALIDATE_UID_STATES = true;
834    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
835
836    /**
837     * Packages that the user has asked to have run in screen size
838     * compatibility mode instead of filling the screen.
839     */
840    final CompatModePackages mCompatModePackages;
841
842    /**
843     * Set of IntentSenderRecord objects that are currently active.
844     */
845    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
846            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
847
848    /**
849     * Fingerprints (hashCode()) of stack traces that we've
850     * already logged DropBox entries for.  Guarded by itself.  If
851     * something (rogue user app) forces this over
852     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
853     */
854    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
855    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
856
857    /**
858     * Strict Mode background batched logging state.
859     *
860     * The string buffer is guarded by itself, and its lock is also
861     * used to determine if another batched write is already
862     * in-flight.
863     */
864    private final StringBuilder mStrictModeBuffer = new StringBuilder();
865
866    /**
867     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
868     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
869     */
870    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
871
872    /**
873     * Resolver for broadcast intents to registered receivers.
874     * Holds BroadcastFilter (subclass of IntentFilter).
875     */
876    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
877            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
878        @Override
879        protected boolean allowFilterResult(
880                BroadcastFilter filter, List<BroadcastFilter> dest) {
881            IBinder target = filter.receiverList.receiver.asBinder();
882            for (int i = dest.size() - 1; i >= 0; i--) {
883                if (dest.get(i).receiverList.receiver.asBinder() == target) {
884                    return false;
885                }
886            }
887            return true;
888        }
889
890        @Override
891        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
892            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
893                    || userId == filter.owningUserId) {
894                return super.newResult(filter, match, userId);
895            }
896            return null;
897        }
898
899        @Override
900        protected BroadcastFilter[] newArray(int size) {
901            return new BroadcastFilter[size];
902        }
903
904        @Override
905        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
906            return packageName.equals(filter.packageName);
907        }
908    };
909
910    /**
911     * State of all active sticky broadcasts per user.  Keys are the action of the
912     * sticky Intent, values are an ArrayList of all broadcasted intents with
913     * that action (which should usually be one).  The SparseArray is keyed
914     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
915     * for stickies that are sent to all users.
916     */
917    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
918            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
919
920    final ActiveServices mServices;
921
922    final static class Association {
923        final int mSourceUid;
924        final String mSourceProcess;
925        final int mTargetUid;
926        final ComponentName mTargetComponent;
927        final String mTargetProcess;
928
929        int mCount;
930        long mTime;
931
932        int mNesting;
933        long mStartTime;
934
935        // states of the source process when the bind occurred.
936        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
937        long mLastStateUptime;
938        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
939                - ActivityManager.MIN_PROCESS_STATE+1];
940
941        Association(int sourceUid, String sourceProcess, int targetUid,
942                ComponentName targetComponent, String targetProcess) {
943            mSourceUid = sourceUid;
944            mSourceProcess = sourceProcess;
945            mTargetUid = targetUid;
946            mTargetComponent = targetComponent;
947            mTargetProcess = targetProcess;
948        }
949    }
950
951    /**
952     * When service association tracking is enabled, this is all of the associations we
953     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
954     * -> association data.
955     */
956    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
957            mAssociations = new SparseArray<>();
958    boolean mTrackingAssociations;
959
960    /**
961     * Backup/restore process management
962     */
963    String mBackupAppName = null;
964    BackupRecord mBackupTarget = null;
965
966    final ProviderMap mProviderMap;
967
968    /**
969     * List of content providers who have clients waiting for them.  The
970     * application is currently being launched and the provider will be
971     * removed from this list once it is published.
972     */
973    final ArrayList<ContentProviderRecord> mLaunchingProviders
974            = new ArrayList<ContentProviderRecord>();
975
976    /**
977     * File storing persisted {@link #mGrantedUriPermissions}.
978     */
979    private final AtomicFile mGrantFile;
980
981    /** XML constants used in {@link #mGrantFile} */
982    private static final String TAG_URI_GRANTS = "uri-grants";
983    private static final String TAG_URI_GRANT = "uri-grant";
984    private static final String ATTR_USER_HANDLE = "userHandle";
985    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
986    private static final String ATTR_TARGET_USER_ID = "targetUserId";
987    private static final String ATTR_SOURCE_PKG = "sourcePkg";
988    private static final String ATTR_TARGET_PKG = "targetPkg";
989    private static final String ATTR_URI = "uri";
990    private static final String ATTR_MODE_FLAGS = "modeFlags";
991    private static final String ATTR_CREATED_TIME = "createdTime";
992    private static final String ATTR_PREFIX = "prefix";
993
994    /**
995     * Global set of specific {@link Uri} permissions that have been granted.
996     * This optimized lookup structure maps from {@link UriPermission#targetUid}
997     * to {@link UriPermission#uri} to {@link UriPermission}.
998     */
999    @GuardedBy("this")
1000    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1001            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1002
1003    public static class GrantUri {
1004        public final int sourceUserId;
1005        public final Uri uri;
1006        public boolean prefix;
1007
1008        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1009            this.sourceUserId = sourceUserId;
1010            this.uri = uri;
1011            this.prefix = prefix;
1012        }
1013
1014        @Override
1015        public int hashCode() {
1016            int hashCode = 1;
1017            hashCode = 31 * hashCode + sourceUserId;
1018            hashCode = 31 * hashCode + uri.hashCode();
1019            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1020            return hashCode;
1021        }
1022
1023        @Override
1024        public boolean equals(Object o) {
1025            if (o instanceof GrantUri) {
1026                GrantUri other = (GrantUri) o;
1027                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1028                        && prefix == other.prefix;
1029            }
1030            return false;
1031        }
1032
1033        @Override
1034        public String toString() {
1035            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1036            if (prefix) result += " [prefix]";
1037            return result;
1038        }
1039
1040        public String toSafeString() {
1041            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1042            if (prefix) result += " [prefix]";
1043            return result;
1044        }
1045
1046        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1047            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1048                    ContentProvider.getUriWithoutUserId(uri), false);
1049        }
1050    }
1051
1052    CoreSettingsObserver mCoreSettingsObserver;
1053
1054    FontScaleSettingObserver mFontScaleSettingObserver;
1055
1056    private final class FontScaleSettingObserver extends ContentObserver {
1057        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1058
1059        public FontScaleSettingObserver() {
1060            super(mHandler);
1061            ContentResolver resolver = mContext.getContentResolver();
1062            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1063        }
1064
1065        @Override
1066        public void onChange(boolean selfChange, Uri uri) {
1067            if (mFontScaleUri.equals(uri)) {
1068                updateFontScaleIfNeeded();
1069            }
1070        }
1071    }
1072
1073    /**
1074     * Thread-local storage used to carry caller permissions over through
1075     * indirect content-provider access.
1076     */
1077    private class Identity {
1078        public final IBinder token;
1079        public final int pid;
1080        public final int uid;
1081
1082        Identity(IBinder _token, int _pid, int _uid) {
1083            token = _token;
1084            pid = _pid;
1085            uid = _uid;
1086        }
1087    }
1088
1089    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1090
1091    /**
1092     * All information we have collected about the runtime performance of
1093     * any user id that can impact battery performance.
1094     */
1095    final BatteryStatsService mBatteryStatsService;
1096
1097    /**
1098     * Information about component usage
1099     */
1100    UsageStatsManagerInternal mUsageStatsService;
1101
1102    /**
1103     * Access to DeviceIdleController service.
1104     */
1105    DeviceIdleController.LocalService mLocalDeviceIdleController;
1106
1107    /**
1108     * Information about and control over application operations
1109     */
1110    final AppOpsService mAppOpsService;
1111
1112    /**
1113     * Current configuration information.  HistoryRecord objects are given
1114     * a reference to this object to indicate which configuration they are
1115     * currently running in, so this object must be kept immutable.
1116     */
1117    Configuration mConfiguration = new Configuration();
1118
1119    /**
1120     * Current sequencing integer of the configuration, for skipping old
1121     * configurations.
1122     */
1123    int mConfigurationSeq = 0;
1124
1125    boolean mSuppressResizeConfigChanges = false;
1126
1127    /**
1128     * Hardware-reported OpenGLES version.
1129     */
1130    final int GL_ES_VERSION;
1131
1132    /**
1133     * List of initialization arguments to pass to all processes when binding applications to them.
1134     * For example, references to the commonly used services.
1135     */
1136    HashMap<String, IBinder> mAppBindArgs;
1137
1138    /**
1139     * Temporary to avoid allocations.  Protected by main lock.
1140     */
1141    final StringBuilder mStringBuilder = new StringBuilder(256);
1142
1143    /**
1144     * Used to control how we initialize the service.
1145     */
1146    ComponentName mTopComponent;
1147    String mTopAction = Intent.ACTION_MAIN;
1148    String mTopData;
1149
1150    volatile boolean mProcessesReady = false;
1151    volatile boolean mSystemReady = false;
1152    volatile boolean mOnBattery = false;
1153    volatile int mFactoryTest;
1154
1155    @GuardedBy("this") boolean mBooting = false;
1156    @GuardedBy("this") boolean mCallFinishBooting = false;
1157    @GuardedBy("this") boolean mBootAnimationComplete = false;
1158    @GuardedBy("this") boolean mLaunchWarningShown = false;
1159    @GuardedBy("this") boolean mCheckedForSetup = false;
1160
1161    Context mContext;
1162
1163    /**
1164     * The time at which we will allow normal application switches again,
1165     * after a call to {@link #stopAppSwitches()}.
1166     */
1167    long mAppSwitchesAllowedTime;
1168
1169    /**
1170     * This is set to true after the first switch after mAppSwitchesAllowedTime
1171     * is set; any switches after that will clear the time.
1172     */
1173    boolean mDidAppSwitch;
1174
1175    /**
1176     * Last time (in realtime) at which we checked for power usage.
1177     */
1178    long mLastPowerCheckRealtime;
1179
1180    /**
1181     * Last time (in uptime) at which we checked for power usage.
1182     */
1183    long mLastPowerCheckUptime;
1184
1185    /**
1186     * Set while we are wanting to sleep, to prevent any
1187     * activities from being started/resumed.
1188     */
1189    private boolean mSleeping = false;
1190
1191    /**
1192     * The process state used for processes that are running the top activities.
1193     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1194     */
1195    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1196
1197    /**
1198     * Set while we are running a voice interaction.  This overrides
1199     * sleeping while it is active.
1200     */
1201    private IVoiceInteractionSession mRunningVoice;
1202
1203    /**
1204     * For some direct access we need to power manager.
1205     */
1206    PowerManagerInternal mLocalPowerManager;
1207
1208    /**
1209     * We want to hold a wake lock while running a voice interaction session, since
1210     * this may happen with the screen off and we need to keep the CPU running to
1211     * be able to continue to interact with the user.
1212     */
1213    PowerManager.WakeLock mVoiceWakeLock;
1214
1215    /**
1216     * State of external calls telling us if the device is awake or asleep.
1217     */
1218    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1219
1220    /**
1221     * A list of tokens that cause the top activity to be put to sleep.
1222     * They are used by components that may hide and block interaction with underlying
1223     * activities.
1224     */
1225    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1226
1227    static final int LOCK_SCREEN_HIDDEN = 0;
1228    static final int LOCK_SCREEN_LEAVING = 1;
1229    static final int LOCK_SCREEN_SHOWN = 2;
1230    /**
1231     * State of external call telling us if the lock screen is shown.
1232     */
1233    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1234
1235    /**
1236     * Set if we are shutting down the system, similar to sleeping.
1237     */
1238    boolean mShuttingDown = false;
1239
1240    /**
1241     * Current sequence id for oom_adj computation traversal.
1242     */
1243    int mAdjSeq = 0;
1244
1245    /**
1246     * Current sequence id for process LRU updating.
1247     */
1248    int mLruSeq = 0;
1249
1250    /**
1251     * Keep track of the non-cached/empty process we last found, to help
1252     * determine how to distribute cached/empty processes next time.
1253     */
1254    int mNumNonCachedProcs = 0;
1255
1256    /**
1257     * Keep track of the number of cached hidden procs, to balance oom adj
1258     * distribution between those and empty procs.
1259     */
1260    int mNumCachedHiddenProcs = 0;
1261
1262    /**
1263     * Keep track of the number of service processes we last found, to
1264     * determine on the next iteration which should be B services.
1265     */
1266    int mNumServiceProcs = 0;
1267    int mNewNumAServiceProcs = 0;
1268    int mNewNumServiceProcs = 0;
1269
1270    /**
1271     * Allow the current computed overall memory level of the system to go down?
1272     * This is set to false when we are killing processes for reasons other than
1273     * memory management, so that the now smaller process list will not be taken as
1274     * an indication that memory is tighter.
1275     */
1276    boolean mAllowLowerMemLevel = false;
1277
1278    /**
1279     * The last computed memory level, for holding when we are in a state that
1280     * processes are going away for other reasons.
1281     */
1282    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1283
1284    /**
1285     * The last total number of process we have, to determine if changes actually look
1286     * like a shrinking number of process due to lower RAM.
1287     */
1288    int mLastNumProcesses;
1289
1290    /**
1291     * The uptime of the last time we performed idle maintenance.
1292     */
1293    long mLastIdleTime = SystemClock.uptimeMillis();
1294
1295    /**
1296     * Total time spent with RAM that has been added in the past since the last idle time.
1297     */
1298    long mLowRamTimeSinceLastIdle = 0;
1299
1300    /**
1301     * If RAM is currently low, when that horrible situation started.
1302     */
1303    long mLowRamStartTime = 0;
1304
1305    /**
1306     * For reporting to battery stats the current top application.
1307     */
1308    private String mCurResumedPackage = null;
1309    private int mCurResumedUid = -1;
1310
1311    /**
1312     * For reporting to battery stats the apps currently running foreground
1313     * service.  The ProcessMap is package/uid tuples; each of these contain
1314     * an array of the currently foreground processes.
1315     */
1316    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1317            = new ProcessMap<ArrayList<ProcessRecord>>();
1318
1319    /**
1320     * This is set if we had to do a delayed dexopt of an app before launching
1321     * it, to increase the ANR timeouts in that case.
1322     */
1323    boolean mDidDexOpt;
1324
1325    /**
1326     * Set if the systemServer made a call to enterSafeMode.
1327     */
1328    boolean mSafeMode;
1329
1330    /**
1331     * If true, we are running under a test environment so will sample PSS from processes
1332     * much more rapidly to try to collect better data when the tests are rapidly
1333     * running through apps.
1334     */
1335    boolean mTestPssMode = false;
1336
1337    String mDebugApp = null;
1338    boolean mWaitForDebugger = false;
1339    boolean mDebugTransient = false;
1340    String mOrigDebugApp = null;
1341    boolean mOrigWaitForDebugger = false;
1342    boolean mAlwaysFinishActivities = false;
1343    boolean mLenientBackgroundCheck = false;
1344    boolean mForceResizableActivities;
1345    boolean mSupportsMultiWindow;
1346    boolean mSupportsFreeformWindowManagement;
1347    boolean mSupportsPictureInPicture;
1348    Rect mDefaultPinnedStackBounds;
1349    IActivityController mController = null;
1350    boolean mControllerIsAMonkey = false;
1351    String mProfileApp = null;
1352    ProcessRecord mProfileProc = null;
1353    String mProfileFile;
1354    ParcelFileDescriptor mProfileFd;
1355    int mSamplingInterval = 0;
1356    boolean mAutoStopProfiler = false;
1357    int mProfileType = 0;
1358    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1359    String mMemWatchDumpProcName;
1360    String mMemWatchDumpFile;
1361    int mMemWatchDumpPid;
1362    int mMemWatchDumpUid;
1363    String mTrackAllocationApp = null;
1364    String mNativeDebuggingApp = null;
1365
1366    final long[] mTmpLong = new long[2];
1367
1368    static final class ProcessChangeItem {
1369        static final int CHANGE_ACTIVITIES = 1<<0;
1370        static final int CHANGE_PROCESS_STATE = 1<<1;
1371        int changes;
1372        int uid;
1373        int pid;
1374        int processState;
1375        boolean foregroundActivities;
1376    }
1377
1378    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1379    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1380
1381    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1382    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1383
1384    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1385    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1386
1387    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1388    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1389
1390    /**
1391     * Runtime CPU use collection thread.  This object's lock is used to
1392     * perform synchronization with the thread (notifying it to run).
1393     */
1394    final Thread mProcessCpuThread;
1395
1396    /**
1397     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1398     * Must acquire this object's lock when accessing it.
1399     * NOTE: this lock will be held while doing long operations (trawling
1400     * through all processes in /proc), so it should never be acquired by
1401     * any critical paths such as when holding the main activity manager lock.
1402     */
1403    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1404            MONITOR_THREAD_CPU_USAGE);
1405    final AtomicLong mLastCpuTime = new AtomicLong(0);
1406    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1407
1408    long mLastWriteTime = 0;
1409
1410    /**
1411     * Used to retain an update lock when the foreground activity is in
1412     * immersive mode.
1413     */
1414    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1415
1416    /**
1417     * Set to true after the system has finished booting.
1418     */
1419    boolean mBooted = false;
1420
1421    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1422    int mProcessLimitOverride = -1;
1423
1424    WindowManagerService mWindowManager;
1425    final ActivityThread mSystemThread;
1426
1427    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1428        final ProcessRecord mApp;
1429        final int mPid;
1430        final IApplicationThread mAppThread;
1431
1432        AppDeathRecipient(ProcessRecord app, int pid,
1433                IApplicationThread thread) {
1434            if (DEBUG_ALL) Slog.v(
1435                TAG, "New death recipient " + this
1436                + " for thread " + thread.asBinder());
1437            mApp = app;
1438            mPid = pid;
1439            mAppThread = thread;
1440        }
1441
1442        @Override
1443        public void binderDied() {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "Death received in " + this
1446                + " for thread " + mAppThread.asBinder());
1447            synchronized(ActivityManagerService.this) {
1448                appDiedLocked(mApp, mPid, mAppThread, true);
1449            }
1450        }
1451    }
1452
1453    static final int SHOW_ERROR_UI_MSG = 1;
1454    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1455    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1456    static final int UPDATE_CONFIGURATION_MSG = 4;
1457    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1458    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1459    static final int SERVICE_TIMEOUT_MSG = 12;
1460    static final int UPDATE_TIME_ZONE = 13;
1461    static final int SHOW_UID_ERROR_UI_MSG = 14;
1462    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1463    static final int PROC_START_TIMEOUT_MSG = 20;
1464    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1465    static final int KILL_APPLICATION_MSG = 22;
1466    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1467    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1468    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1469    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1470    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1471    static final int CLEAR_DNS_CACHE_MSG = 28;
1472    static final int UPDATE_HTTP_PROXY_MSG = 29;
1473    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1474    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1475    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1476    static final int REPORT_MEM_USAGE_MSG = 33;
1477    static final int REPORT_USER_SWITCH_MSG = 34;
1478    static final int CONTINUE_USER_SWITCH_MSG = 35;
1479    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1480    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1481    static final int PERSIST_URI_GRANTS_MSG = 38;
1482    static final int REQUEST_ALL_PSS_MSG = 39;
1483    static final int START_PROFILES_MSG = 40;
1484    static final int UPDATE_TIME = 41;
1485    static final int SYSTEM_USER_START_MSG = 42;
1486    static final int SYSTEM_USER_CURRENT_MSG = 43;
1487    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1488    static final int FINISH_BOOTING_MSG = 45;
1489    static final int START_USER_SWITCH_UI_MSG = 46;
1490    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1491    static final int DISMISS_DIALOG_UI_MSG = 48;
1492    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1493    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1494    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1495    static final int DELETE_DUMPHEAP_MSG = 52;
1496    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1497    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1498    static final int REPORT_TIME_TRACKER_MSG = 55;
1499    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1500    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1501    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1502    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1503    static final int IDLE_UIDS_MSG = 60;
1504    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1505    static final int LOG_STACK_STATE = 62;
1506    static final int VR_MODE_CHANGE_MSG = 63;
1507    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1508    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1509    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1510    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1511    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1512    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1513
1514    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1515    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1516    static final int FIRST_COMPAT_MODE_MSG = 300;
1517    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1518
1519    static ServiceThread sKillThread = null;
1520    static KillHandler sKillHandler = null;
1521
1522    CompatModeDialog mCompatModeDialog;
1523    long mLastMemUsageReportTime = 0;
1524
1525    /**
1526     * Flag whether the current user is a "monkey", i.e. whether
1527     * the UI is driven by a UI automation tool.
1528     */
1529    private boolean mUserIsMonkey;
1530
1531    /** Flag whether the device has a Recents UI */
1532    boolean mHasRecents;
1533
1534    /** The dimensions of the thumbnails in the Recents UI. */
1535    int mThumbnailWidth;
1536    int mThumbnailHeight;
1537    float mFullscreenThumbnailScale;
1538
1539    final ServiceThread mHandlerThread;
1540    final MainHandler mHandler;
1541    final UiHandler mUiHandler;
1542
1543    PackageManagerInternal mPackageManagerInt;
1544
1545    // VoiceInteraction session ID that changes for each new request except when
1546    // being called for multiwindow assist in a single session.
1547    private int mViSessionId = 1000;
1548
1549    final class KillHandler extends Handler {
1550        static final int KILL_PROCESS_GROUP_MSG = 4000;
1551
1552        public KillHandler(Looper looper) {
1553            super(looper, null, true);
1554        }
1555
1556        @Override
1557        public void handleMessage(Message msg) {
1558            switch (msg.what) {
1559                case KILL_PROCESS_GROUP_MSG:
1560                {
1561                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1562                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1563                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1564                }
1565                break;
1566
1567                default:
1568                    super.handleMessage(msg);
1569            }
1570        }
1571    }
1572
1573    final class UiHandler extends Handler {
1574        public UiHandler() {
1575            super(com.android.server.UiThread.get().getLooper(), null, true);
1576        }
1577
1578        @Override
1579        public void handleMessage(Message msg) {
1580            switch (msg.what) {
1581            case SHOW_ERROR_UI_MSG: {
1582                mAppErrors.handleShowAppErrorUi(msg);
1583                ensureBootCompleted();
1584            } break;
1585            case SHOW_NOT_RESPONDING_UI_MSG: {
1586                mAppErrors.handleShowAnrUi(msg);
1587                ensureBootCompleted();
1588            } break;
1589            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1590                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1591                synchronized (ActivityManagerService.this) {
1592                    ProcessRecord proc = (ProcessRecord) data.get("app");
1593                    if (proc == null) {
1594                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1595                        break;
1596                    }
1597                    if (proc.crashDialog != null) {
1598                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1599                        return;
1600                    }
1601                    AppErrorResult res = (AppErrorResult) data.get("result");
1602                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1603                        Dialog d = new StrictModeViolationDialog(mContext,
1604                                ActivityManagerService.this, res, proc);
1605                        d.show();
1606                        proc.crashDialog = d;
1607                    } else {
1608                        // The device is asleep, so just pretend that the user
1609                        // saw a crash dialog and hit "force quit".
1610                        res.set(0);
1611                    }
1612                }
1613                ensureBootCompleted();
1614            } break;
1615            case SHOW_FACTORY_ERROR_UI_MSG: {
1616                Dialog d = new FactoryErrorDialog(
1617                    mContext, msg.getData().getCharSequence("msg"));
1618                d.show();
1619                ensureBootCompleted();
1620            } break;
1621            case WAIT_FOR_DEBUGGER_UI_MSG: {
1622                synchronized (ActivityManagerService.this) {
1623                    ProcessRecord app = (ProcessRecord)msg.obj;
1624                    if (msg.arg1 != 0) {
1625                        if (!app.waitedForDebugger) {
1626                            Dialog d = new AppWaitingForDebuggerDialog(
1627                                    ActivityManagerService.this,
1628                                    mContext, app);
1629                            app.waitDialog = d;
1630                            app.waitedForDebugger = true;
1631                            d.show();
1632                        }
1633                    } else {
1634                        if (app.waitDialog != null) {
1635                            app.waitDialog.dismiss();
1636                            app.waitDialog = null;
1637                        }
1638                    }
1639                }
1640            } break;
1641            case SHOW_UID_ERROR_UI_MSG: {
1642                if (mShowDialogs) {
1643                    AlertDialog d = new BaseErrorDialog(mContext);
1644                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1645                    d.setCancelable(false);
1646                    d.setTitle(mContext.getText(R.string.android_system_label));
1647                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1648                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1649                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1650                    d.show();
1651                }
1652            } break;
1653            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1654                if (mShowDialogs) {
1655                    AlertDialog d = new BaseErrorDialog(mContext);
1656                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                    d.setCancelable(false);
1658                    d.setTitle(mContext.getText(R.string.android_system_label));
1659                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1660                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                    d.show();
1663                }
1664            } break;
1665            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1666                synchronized (ActivityManagerService.this) {
1667                    ActivityRecord ar = (ActivityRecord) msg.obj;
1668                    if (mCompatModeDialog != null) {
1669                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1670                                ar.info.applicationInfo.packageName)) {
1671                            return;
1672                        }
1673                        mCompatModeDialog.dismiss();
1674                        mCompatModeDialog = null;
1675                    }
1676                    if (ar != null && false) {
1677                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1678                                ar.packageName)) {
1679                            int mode = mCompatModePackages.computeCompatModeLocked(
1680                                    ar.info.applicationInfo);
1681                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1682                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1683                                mCompatModeDialog = new CompatModeDialog(
1684                                        ActivityManagerService.this, mContext,
1685                                        ar.info.applicationInfo);
1686                                mCompatModeDialog.show();
1687                            }
1688                        }
1689                    }
1690                }
1691                break;
1692            }
1693            case START_USER_SWITCH_UI_MSG: {
1694                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1695                break;
1696            }
1697            case DISMISS_DIALOG_UI_MSG: {
1698                final Dialog d = (Dialog) msg.obj;
1699                d.dismiss();
1700                break;
1701            }
1702            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1703                dispatchProcessesChanged();
1704                break;
1705            }
1706            case DISPATCH_PROCESS_DIED_UI_MSG: {
1707                final int pid = msg.arg1;
1708                final int uid = msg.arg2;
1709                dispatchProcessDied(pid, uid);
1710                break;
1711            }
1712            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1713                dispatchUidsChanged();
1714            } break;
1715            }
1716        }
1717    }
1718
1719    final class MainHandler extends Handler {
1720        public MainHandler(Looper looper) {
1721            super(looper, null, true);
1722        }
1723
1724        @Override
1725        public void handleMessage(Message msg) {
1726            switch (msg.what) {
1727            case UPDATE_CONFIGURATION_MSG: {
1728                final ContentResolver resolver = mContext.getContentResolver();
1729                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1730                        msg.arg1);
1731            } break;
1732            case GC_BACKGROUND_PROCESSES_MSG: {
1733                synchronized (ActivityManagerService.this) {
1734                    performAppGcsIfAppropriateLocked();
1735                }
1736            } break;
1737            case SERVICE_TIMEOUT_MSG: {
1738                if (mDidDexOpt) {
1739                    mDidDexOpt = false;
1740                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1741                    nmsg.obj = msg.obj;
1742                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1743                    return;
1744                }
1745                mServices.serviceTimeout((ProcessRecord)msg.obj);
1746            } break;
1747            case UPDATE_TIME_ZONE: {
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.updateTimeZone();
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1756                            }
1757                        }
1758                    }
1759                }
1760            } break;
1761            case CLEAR_DNS_CACHE_MSG: {
1762                synchronized (ActivityManagerService.this) {
1763                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764                        ProcessRecord r = mLruProcesses.get(i);
1765                        if (r.thread != null) {
1766                            try {
1767                                r.thread.clearDnsCache();
1768                            } catch (RemoteException ex) {
1769                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1770                            }
1771                        }
1772                    }
1773                }
1774            } break;
1775            case UPDATE_HTTP_PROXY_MSG: {
1776                ProxyInfo proxy = (ProxyInfo)msg.obj;
1777                String host = "";
1778                String port = "";
1779                String exclList = "";
1780                Uri pacFileUrl = Uri.EMPTY;
1781                if (proxy != null) {
1782                    host = proxy.getHost();
1783                    port = Integer.toString(proxy.getPort());
1784                    exclList = proxy.getExclusionListAsString();
1785                    pacFileUrl = proxy.getPacFileUrl();
1786                }
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update http proxy for: " +
1795                                        r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800            } break;
1801            case PROC_START_TIMEOUT_MSG: {
1802                if (mDidDexOpt) {
1803                    mDidDexOpt = false;
1804                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1805                    nmsg.obj = msg.obj;
1806                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1807                    return;
1808                }
1809                ProcessRecord app = (ProcessRecord)msg.obj;
1810                synchronized (ActivityManagerService.this) {
1811                    processStartTimedOutLocked(app);
1812                }
1813            } break;
1814            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1815                ProcessRecord app = (ProcessRecord)msg.obj;
1816                synchronized (ActivityManagerService.this) {
1817                    processContentProviderPublishTimedOutLocked(app);
1818                }
1819            } break;
1820            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1821                synchronized (ActivityManagerService.this) {
1822                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1823                }
1824            } break;
1825            case KILL_APPLICATION_MSG: {
1826                synchronized (ActivityManagerService.this) {
1827                    int appid = msg.arg1;
1828                    boolean restart = (msg.arg2 == 1);
1829                    Bundle bundle = (Bundle)msg.obj;
1830                    String pkg = bundle.getString("pkg");
1831                    String reason = bundle.getString("reason");
1832                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1833                            false, UserHandle.USER_ALL, reason);
1834                }
1835            } break;
1836            case FINALIZE_PENDING_INTENT_MSG: {
1837                ((PendingIntentRecord)msg.obj).completeFinalize();
1838            } break;
1839            case POST_HEAVY_NOTIFICATION_MSG: {
1840                INotificationManager inm = NotificationManager.getService();
1841                if (inm == null) {
1842                    return;
1843                }
1844
1845                ActivityRecord root = (ActivityRecord)msg.obj;
1846                ProcessRecord process = root.app;
1847                if (process == null) {
1848                    return;
1849                }
1850
1851                try {
1852                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1853                    String text = mContext.getString(R.string.heavy_weight_notification,
1854                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1855                    Notification notification = new Notification.Builder(context)
1856                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1857                            .setWhen(0)
1858                            .setOngoing(true)
1859                            .setTicker(text)
1860                            .setColor(mContext.getColor(
1861                                    com.android.internal.R.color.system_notification_accent_color))
1862                            .setContentTitle(text)
1863                            .setContentText(
1864                                    mContext.getText(R.string.heavy_weight_notification_detail))
1865                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1866                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1867                                    new UserHandle(root.userId)))
1868                            .build();
1869                    try {
1870                        int[] outId = new int[1];
1871                        inm.enqueueNotificationWithTag("android", "android", null,
1872                                R.string.heavy_weight_notification,
1873                                notification, outId, root.userId);
1874                    } catch (RuntimeException e) {
1875                        Slog.w(ActivityManagerService.TAG,
1876                                "Error showing notification for heavy-weight app", e);
1877                    } catch (RemoteException e) {
1878                    }
1879                } catch (NameNotFoundException e) {
1880                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1881                }
1882            } break;
1883            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1884                INotificationManager inm = NotificationManager.getService();
1885                if (inm == null) {
1886                    return;
1887                }
1888                try {
1889                    inm.cancelNotificationWithTag("android", null,
1890                            R.string.heavy_weight_notification,  msg.arg1);
1891                } catch (RuntimeException e) {
1892                    Slog.w(ActivityManagerService.TAG,
1893                            "Error canceling notification for service", e);
1894                } catch (RemoteException e) {
1895                }
1896            } break;
1897            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1898                synchronized (ActivityManagerService.this) {
1899                    checkExcessivePowerUsageLocked(true);
1900                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1902                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1903                }
1904            } break;
1905            case REPORT_MEM_USAGE_MSG: {
1906                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1907                Thread thread = new Thread() {
1908                    @Override public void run() {
1909                        reportMemUsage(memInfos);
1910                    }
1911                };
1912                thread.start();
1913                break;
1914            }
1915            case REPORT_USER_SWITCH_MSG: {
1916                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1917                break;
1918            }
1919            case CONTINUE_USER_SWITCH_MSG: {
1920                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1921                break;
1922            }
1923            case USER_SWITCH_TIMEOUT_MSG: {
1924                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1925                break;
1926            }
1927            case IMMERSIVE_MODE_LOCK_MSG: {
1928                final boolean nextState = (msg.arg1 != 0);
1929                if (mUpdateLock.isHeld() != nextState) {
1930                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1931                            "Applying new update lock state '" + nextState
1932                            + "' for " + (ActivityRecord)msg.obj);
1933                    if (nextState) {
1934                        mUpdateLock.acquire();
1935                    } else {
1936                        mUpdateLock.release();
1937                    }
1938                }
1939                break;
1940            }
1941            case PERSIST_URI_GRANTS_MSG: {
1942                writeGrantedUriPermissions();
1943                break;
1944            }
1945            case REQUEST_ALL_PSS_MSG: {
1946                synchronized (ActivityManagerService.this) {
1947                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1948                }
1949                break;
1950            }
1951            case START_PROFILES_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    mUserController.startProfilesLocked();
1954                }
1955                break;
1956            }
1957            case UPDATE_TIME: {
1958                synchronized (ActivityManagerService.this) {
1959                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1960                        ProcessRecord r = mLruProcesses.get(i);
1961                        if (r.thread != null) {
1962                            try {
1963                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1964                            } catch (RemoteException ex) {
1965                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1966                            }
1967                        }
1968                    }
1969                }
1970                break;
1971            }
1972            case SYSTEM_USER_START_MSG: {
1973                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1974                        Integer.toString(msg.arg1), msg.arg1);
1975                mSystemServiceManager.startUser(msg.arg1);
1976                break;
1977            }
1978            case SYSTEM_USER_UNLOCK_MSG: {
1979                final int userId = msg.arg1;
1980                mSystemServiceManager.unlockUser(userId);
1981                synchronized (ActivityManagerService.this) {
1982                    mRecentTasks.loadUserRecentsLocked(userId);
1983                }
1984                if (userId == UserHandle.USER_SYSTEM) {
1985                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1986                }
1987                installEncryptionUnawareProviders(userId);
1988                mUserController.finishUserUnlocked((UserState) msg.obj);
1989                break;
1990            }
1991            case SYSTEM_USER_CURRENT_MSG: {
1992                mBatteryStatsService.noteEvent(
1993                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1994                        Integer.toString(msg.arg2), msg.arg2);
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1997                        Integer.toString(msg.arg1), msg.arg1);
1998                mSystemServiceManager.switchUser(msg.arg1);
1999                break;
2000            }
2001            case ENTER_ANIMATION_COMPLETE_MSG: {
2002                synchronized (ActivityManagerService.this) {
2003                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2004                    if (r != null && r.app != null && r.app.thread != null) {
2005                        try {
2006                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2007                        } catch (RemoteException e) {
2008                        }
2009                    }
2010                }
2011                break;
2012            }
2013            case FINISH_BOOTING_MSG: {
2014                if (msg.arg1 != 0) {
2015                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2016                    finishBooting();
2017                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2018                }
2019                if (msg.arg2 != 0) {
2020                    enableScreenAfterBoot();
2021                }
2022                break;
2023            }
2024            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2025                try {
2026                    Locale l = (Locale) msg.obj;
2027                    IBinder service = ServiceManager.getService("mount");
2028                    IMountService mountService = IMountService.Stub.asInterface(service);
2029                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2030                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2031                } catch (RemoteException e) {
2032                    Log.e(TAG, "Error storing locale for decryption UI", e);
2033                }
2034                break;
2035            }
2036            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2037                synchronized (ActivityManagerService.this) {
2038                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                        try {
2040                            // Make a one-way callback to the listener
2041                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2042                        } catch (RemoteException e){
2043                            // Handled by the RemoteCallbackList
2044                        }
2045                    }
2046                    mTaskStackListeners.finishBroadcast();
2047                }
2048                break;
2049            }
2050            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                        try {
2054                            // Make a one-way callback to the listener
2055                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_FORCED_RESIZABLE_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2098                                    (String) msg.obj, msg.arg1);
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2108                    synchronized (ActivityManagerService.this) {
2109                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                            try {
2111                                // Make a one-way callback to the listener
2112                                mTaskStackListeners.getBroadcastItem(i)
2113                                        .onActivityDismissingDockedStack();
2114                            } catch (RemoteException e){
2115                                // Handled by the RemoteCallbackList
2116                            }
2117                        }
2118                        mTaskStackListeners.finishBroadcast();
2119                    }
2120                    break;
2121                }
2122            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2123                final int uid = msg.arg1;
2124                final byte[] firstPacket = (byte[]) msg.obj;
2125
2126                synchronized (mPidsSelfLocked) {
2127                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2128                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2129                        if (p.uid == uid) {
2130                            try {
2131                                p.thread.notifyCleartextNetwork(firstPacket);
2132                            } catch (RemoteException ignored) {
2133                            }
2134                        }
2135                    }
2136                }
2137                break;
2138            }
2139            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2140                final String procName;
2141                final int uid;
2142                final long memLimit;
2143                final String reportPackage;
2144                synchronized (ActivityManagerService.this) {
2145                    procName = mMemWatchDumpProcName;
2146                    uid = mMemWatchDumpUid;
2147                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2148                    if (val == null) {
2149                        val = mMemWatchProcesses.get(procName, 0);
2150                    }
2151                    if (val != null) {
2152                        memLimit = val.first;
2153                        reportPackage = val.second;
2154                    } else {
2155                        memLimit = 0;
2156                        reportPackage = null;
2157                    }
2158                }
2159                if (procName == null) {
2160                    return;
2161                }
2162
2163                if (DEBUG_PSS) Slog.d(TAG_PSS,
2164                        "Showing dump heap notification from " + procName + "/" + uid);
2165
2166                INotificationManager inm = NotificationManager.getService();
2167                if (inm == null) {
2168                    return;
2169                }
2170
2171                String text = mContext.getString(R.string.dump_heap_notification, procName);
2172
2173
2174                Intent deleteIntent = new Intent();
2175                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2176                Intent intent = new Intent();
2177                intent.setClassName("android", DumpHeapActivity.class.getName());
2178                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2179                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2180                if (reportPackage != null) {
2181                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2182                }
2183                int userId = UserHandle.getUserId(uid);
2184                Notification notification = new Notification.Builder(mContext)
2185                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2186                        .setWhen(0)
2187                        .setOngoing(true)
2188                        .setAutoCancel(true)
2189                        .setTicker(text)
2190                        .setColor(mContext.getColor(
2191                                com.android.internal.R.color.system_notification_accent_color))
2192                        .setContentTitle(text)
2193                        .setContentText(
2194                                mContext.getText(R.string.dump_heap_notification_detail))
2195                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2196                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2197                                new UserHandle(userId)))
2198                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2199                                deleteIntent, 0, UserHandle.SYSTEM))
2200                        .build();
2201
2202                try {
2203                    int[] outId = new int[1];
2204                    inm.enqueueNotificationWithTag("android", "android", null,
2205                            R.string.dump_heap_notification,
2206                            notification, outId, userId);
2207                } catch (RuntimeException e) {
2208                    Slog.w(ActivityManagerService.TAG,
2209                            "Error showing notification for dump heap", e);
2210                } catch (RemoteException e) {
2211                }
2212            } break;
2213            case DELETE_DUMPHEAP_MSG: {
2214                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2215                        DumpHeapActivity.JAVA_URI,
2216                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2217                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2218                        UserHandle.myUserId());
2219                synchronized (ActivityManagerService.this) {
2220                    mMemWatchDumpFile = null;
2221                    mMemWatchDumpProcName = null;
2222                    mMemWatchDumpPid = -1;
2223                    mMemWatchDumpUid = -1;
2224                }
2225            } break;
2226            case FOREGROUND_PROFILE_CHANGED_MSG: {
2227                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2228            } break;
2229            case REPORT_TIME_TRACKER_MSG: {
2230                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2231                tracker.deliverResult(mContext);
2232            } break;
2233            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2234                mUserController.dispatchUserSwitchComplete(msg.arg1);
2235            } break;
2236            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2237                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2238                try {
2239                    connection.shutdown();
2240                } catch (RemoteException e) {
2241                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2242                }
2243                // Only a UiAutomation can set this flag and now that
2244                // it is finished we make sure it is reset to its default.
2245                mUserIsMonkey = false;
2246            } break;
2247            case APP_BOOST_DEACTIVATE_MSG: {
2248                synchronized(ActivityManagerService.this) {
2249                    if (mIsBoosted) {
2250                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2251                            nativeMigrateFromBoost();
2252                            mIsBoosted = false;
2253                            mBoostStartTime = 0;
2254                        } else {
2255                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2256                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2257                        }
2258                    }
2259                }
2260            } break;
2261            case IDLE_UIDS_MSG: {
2262                idleUids();
2263            } break;
2264            case LOG_STACK_STATE: {
2265                synchronized (ActivityManagerService.this) {
2266                    mStackSupervisor.logStackState();
2267                }
2268            } break;
2269            case VR_MODE_CHANGE_MSG: {
2270                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2271                final ActivityRecord r = (ActivityRecord) msg.obj;
2272                boolean vrMode;
2273                ComponentName requestedPackage;
2274                ComponentName callingPackage;
2275                int userId;
2276                synchronized (ActivityManagerService.this) {
2277                    vrMode = r.requestedVrComponent != null;
2278                    requestedPackage = r.requestedVrComponent;
2279                    userId = r.userId;
2280                    callingPackage = r.info.getComponentName();
2281                    if (mInVrMode != vrMode) {
2282                        mInVrMode = vrMode;
2283                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2284                    }
2285                }
2286                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2287            } break;
2288            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2289                final ActivityRecord r = (ActivityRecord) msg.obj;
2290                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2291                if (needsVrMode) {
2292                    VrManagerInternal vrService =
2293                            LocalServices.getService(VrManagerInternal.class);
2294                    boolean enable = msg.arg1 == 1;
2295                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2296                            r.info.getComponentName());
2297                }
2298            } break;
2299            }
2300        }
2301    };
2302
2303    static final int COLLECT_PSS_BG_MSG = 1;
2304
2305    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2306        @Override
2307        public void handleMessage(Message msg) {
2308            switch (msg.what) {
2309            case COLLECT_PSS_BG_MSG: {
2310                long start = SystemClock.uptimeMillis();
2311                MemInfoReader memInfo = null;
2312                synchronized (ActivityManagerService.this) {
2313                    if (mFullPssPending) {
2314                        mFullPssPending = false;
2315                        memInfo = new MemInfoReader();
2316                    }
2317                }
2318                if (memInfo != null) {
2319                    updateCpuStatsNow();
2320                    long nativeTotalPss = 0;
2321                    synchronized (mProcessCpuTracker) {
2322                        final int N = mProcessCpuTracker.countStats();
2323                        for (int j=0; j<N; j++) {
2324                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326                                // This is definitely an application process; skip it.
2327                                continue;
2328                            }
2329                            synchronized (mPidsSelfLocked) {
2330                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331                                    // This is one of our own processes; skip it.
2332                                    continue;
2333                                }
2334                            }
2335                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2336                        }
2337                    }
2338                    memInfo.readMemInfo();
2339                    synchronized (ActivityManagerService.this) {
2340                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341                                + (SystemClock.uptimeMillis()-start) + "ms");
2342                        final long cachedKb = memInfo.getCachedSizeKb();
2343                        final long freeKb = memInfo.getFreeSizeKb();
2344                        final long zramKb = memInfo.getZramTotalSizeKb();
2345                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2346                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347                                kernelKb*1024, nativeTotalPss*1024);
2348                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2349                                nativeTotalPss);
2350                    }
2351                }
2352
2353                int num = 0;
2354                long[] tmp = new long[2];
2355                do {
2356                    ProcessRecord proc;
2357                    int procState;
2358                    int pid;
2359                    long lastPssTime;
2360                    synchronized (ActivityManagerService.this) {
2361                        if (mPendingPssProcesses.size() <= 0) {
2362                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363                                    "Collected PSS of " + num + " processes in "
2364                                    + (SystemClock.uptimeMillis() - start) + "ms");
2365                            mPendingPssProcesses.clear();
2366                            return;
2367                        }
2368                        proc = mPendingPssProcesses.remove(0);
2369                        procState = proc.pssProcState;
2370                        lastPssTime = proc.lastPssTime;
2371                        if (proc.thread != null && procState == proc.setProcState
2372                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373                                        < SystemClock.uptimeMillis()) {
2374                            pid = proc.pid;
2375                        } else {
2376                            proc = null;
2377                            pid = 0;
2378                        }
2379                    }
2380                    if (proc != null) {
2381                        long pss = Debug.getPss(pid, tmp, null);
2382                        synchronized (ActivityManagerService.this) {
2383                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2385                                num++;
2386                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387                                        SystemClock.uptimeMillis());
2388                            }
2389                        }
2390                    }
2391                } while (true);
2392            }
2393            }
2394        }
2395    };
2396
2397    public void setSystemProcess() {
2398        try {
2399            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401            ServiceManager.addService("meminfo", new MemBinder(this));
2402            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403            ServiceManager.addService("dbinfo", new DbBinder(this));
2404            if (MONITOR_CPU_USAGE) {
2405                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2406            }
2407            ServiceManager.addService("permission", new PermissionController(this));
2408            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2409
2410            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2413
2414            synchronized (this) {
2415                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416                app.persistent = true;
2417                app.pid = MY_PID;
2418                app.maxAdj = ProcessList.SYSTEM_ADJ;
2419                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420                synchronized (mPidsSelfLocked) {
2421                    mPidsSelfLocked.put(app.pid, app);
2422                }
2423                updateLruProcessLocked(app, false, null);
2424                updateOomAdjLocked();
2425            }
2426        } catch (PackageManager.NameNotFoundException e) {
2427            throw new RuntimeException(
2428                    "Unable to find android system package", e);
2429        }
2430    }
2431
2432    public void setWindowManager(WindowManagerService wm) {
2433        mWindowManager = wm;
2434        mStackSupervisor.setWindowManager(wm);
2435        mActivityStarter.setWindowManager(wm);
2436    }
2437
2438    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439        mUsageStatsService = usageStatsManager;
2440    }
2441
2442    public void startObservingNativeCrashes() {
2443        final NativeCrashListener ncl = new NativeCrashListener(this);
2444        ncl.start();
2445    }
2446
2447    public IAppOpsService getAppOpsService() {
2448        return mAppOpsService;
2449    }
2450
2451    static class MemBinder extends Binder {
2452        ActivityManagerService mActivityManagerService;
2453        MemBinder(ActivityManagerService activityManagerService) {
2454            mActivityManagerService = activityManagerService;
2455        }
2456
2457        @Override
2458        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460                    != PackageManager.PERMISSION_GRANTED) {
2461                pw.println("Permission Denial: can't dump meminfo from from pid="
2462                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463                        + " without permission " + android.Manifest.permission.DUMP);
2464                return;
2465            }
2466
2467            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2468        }
2469    }
2470
2471    static class GraphicsBinder extends Binder {
2472        ActivityManagerService mActivityManagerService;
2473        GraphicsBinder(ActivityManagerService activityManagerService) {
2474            mActivityManagerService = activityManagerService;
2475        }
2476
2477        @Override
2478        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480                    != PackageManager.PERMISSION_GRANTED) {
2481                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483                        + " without permission " + android.Manifest.permission.DUMP);
2484                return;
2485            }
2486
2487            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2488        }
2489    }
2490
2491    static class DbBinder extends Binder {
2492        ActivityManagerService mActivityManagerService;
2493        DbBinder(ActivityManagerService activityManagerService) {
2494            mActivityManagerService = activityManagerService;
2495        }
2496
2497        @Override
2498        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500                    != PackageManager.PERMISSION_GRANTED) {
2501                pw.println("Permission Denial: can't dump dbinfo from from pid="
2502                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503                        + " without permission " + android.Manifest.permission.DUMP);
2504                return;
2505            }
2506
2507            mActivityManagerService.dumpDbInfo(fd, pw, args);
2508        }
2509    }
2510
2511    static class CpuBinder extends Binder {
2512        ActivityManagerService mActivityManagerService;
2513        CpuBinder(ActivityManagerService activityManagerService) {
2514            mActivityManagerService = activityManagerService;
2515        }
2516
2517        @Override
2518        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520                    != PackageManager.PERMISSION_GRANTED) {
2521                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523                        + " without permission " + android.Manifest.permission.DUMP);
2524                return;
2525            }
2526
2527            synchronized (mActivityManagerService.mProcessCpuTracker) {
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530                        SystemClock.uptimeMillis()));
2531            }
2532        }
2533    }
2534
2535    public static final class Lifecycle extends SystemService {
2536        private final ActivityManagerService mService;
2537
2538        public Lifecycle(Context context) {
2539            super(context);
2540            mService = new ActivityManagerService(context);
2541        }
2542
2543        @Override
2544        public void onStart() {
2545            mService.start();
2546        }
2547
2548        public ActivityManagerService getService() {
2549            return mService;
2550        }
2551    }
2552
2553    // Note: This method is invoked on the main thread but may need to attach various
2554    // handlers to other threads.  So take care to be explicit about the looper.
2555    public ActivityManagerService(Context systemContext) {
2556        mContext = systemContext;
2557        mFactoryTest = FactoryTest.getMode();
2558        mSystemThread = ActivityThread.currentActivityThread();
2559
2560        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2561
2562        mHandlerThread = new ServiceThread(TAG,
2563                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564        mHandlerThread.start();
2565        mHandler = new MainHandler(mHandlerThread.getLooper());
2566        mUiHandler = new UiHandler();
2567
2568        /* static; one-time init here */
2569        if (sKillHandler == null) {
2570            sKillThread = new ServiceThread(TAG + ":kill",
2571                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572            sKillThread.start();
2573            sKillHandler = new KillHandler(sKillThread.getLooper());
2574        }
2575
2576        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577                "foreground", BROADCAST_FG_TIMEOUT, false);
2578        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579                "background", BROADCAST_BG_TIMEOUT, true);
2580        mBroadcastQueues[0] = mFgBroadcastQueue;
2581        mBroadcastQueues[1] = mBgBroadcastQueue;
2582
2583        mServices = new ActiveServices(this);
2584        mProviderMap = new ProviderMap(this);
2585        mAppErrors = new AppErrors(mContext, this);
2586
2587        // TODO: Move creation of battery stats service outside of activity manager service.
2588        File dataDir = Environment.getDataDirectory();
2589        File systemDir = new File(dataDir, "system");
2590        systemDir.mkdirs();
2591        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592        mBatteryStatsService.getActiveStatistics().readLocked();
2593        mBatteryStatsService.scheduleWriteToDisk();
2594        mOnBattery = DEBUG_POWER ? true
2595                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596        mBatteryStatsService.getActiveStatistics().setCallback(this);
2597
2598        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2599
2600        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602                new IAppOpsCallback.Stub() {
2603                    @Override public void opChanged(int op, int uid, String packageName) {
2604                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605                            if (mAppOpsService.checkOperation(op, uid, packageName)
2606                                    != AppOpsManager.MODE_ALLOWED) {
2607                                runInBackgroundDisabled(uid);
2608                            }
2609                        }
2610                    }
2611                });
2612
2613        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2614
2615        mUserController = new UserController(this);
2616
2617        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2619
2620        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2621
2622        mConfiguration.setToDefaults();
2623        mConfiguration.setLocales(LocaleList.getDefault());
2624
2625        mConfigurationSeq = mConfiguration.seq = 1;
2626        mProcessCpuTracker.init();
2627
2628        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630        mStackSupervisor = new ActivityStackSupervisor(this);
2631        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2633
2634        mProcessCpuThread = new Thread("CpuTracker") {
2635            @Override
2636            public void run() {
2637                while (true) {
2638                    try {
2639                        try {
2640                            synchronized(this) {
2641                                final long now = SystemClock.uptimeMillis();
2642                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645                                //        + ", write delay=" + nextWriteDelay);
2646                                if (nextWriteDelay < nextCpuDelay) {
2647                                    nextCpuDelay = nextWriteDelay;
2648                                }
2649                                if (nextCpuDelay > 0) {
2650                                    mProcessCpuMutexFree.set(true);
2651                                    this.wait(nextCpuDelay);
2652                                }
2653                            }
2654                        } catch (InterruptedException e) {
2655                        }
2656                        updateCpuStatsNow();
2657                    } catch (Exception e) {
2658                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2659                    }
2660                }
2661            }
2662        };
2663
2664        Watchdog.getInstance().addMonitor(this);
2665        Watchdog.getInstance().addThread(mHandler);
2666    }
2667
2668    public void setSystemServiceManager(SystemServiceManager mgr) {
2669        mSystemServiceManager = mgr;
2670    }
2671
2672    public void setInstaller(Installer installer) {
2673        mInstaller = installer;
2674    }
2675
2676    private void start() {
2677        Process.removeAllProcessGroups();
2678        mProcessCpuThread.start();
2679
2680        mBatteryStatsService.publish(mContext);
2681        mAppOpsService.publish(mContext);
2682        Slog.d("AppOps", "AppOpsService published");
2683        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2684    }
2685
2686    void onUserStoppedLocked(int userId) {
2687        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2688    }
2689
2690    public void initPowerManagement() {
2691        mStackSupervisor.initPowerManagement();
2692        mBatteryStatsService.initPowerManagement();
2693        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696        mVoiceWakeLock.setReferenceCounted(false);
2697    }
2698
2699    @Override
2700    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701            throws RemoteException {
2702        if (code == SYSPROPS_TRANSACTION) {
2703            // We need to tell all apps about the system property change.
2704            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705            synchronized(this) {
2706                final int NP = mProcessNames.getMap().size();
2707                for (int ip=0; ip<NP; ip++) {
2708                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709                    final int NA = apps.size();
2710                    for (int ia=0; ia<NA; ia++) {
2711                        ProcessRecord app = apps.valueAt(ia);
2712                        if (app.thread != null) {
2713                            procs.add(app.thread.asBinder());
2714                        }
2715                    }
2716                }
2717            }
2718
2719            int N = procs.size();
2720            for (int i=0; i<N; i++) {
2721                Parcel data2 = Parcel.obtain();
2722                try {
2723                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724                } catch (RemoteException e) {
2725                }
2726                data2.recycle();
2727            }
2728        }
2729        try {
2730            return super.onTransact(code, data, reply, flags);
2731        } catch (RuntimeException e) {
2732            // The activity manager only throws security exceptions, so let's
2733            // log all others.
2734            if (!(e instanceof SecurityException)) {
2735                Slog.wtf(TAG, "Activity Manager Crash", e);
2736            }
2737            throw e;
2738        }
2739    }
2740
2741    void updateCpuStats() {
2742        final long now = SystemClock.uptimeMillis();
2743        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2744            return;
2745        }
2746        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747            synchronized (mProcessCpuThread) {
2748                mProcessCpuThread.notify();
2749            }
2750        }
2751    }
2752
2753    void updateCpuStatsNow() {
2754        synchronized (mProcessCpuTracker) {
2755            mProcessCpuMutexFree.set(false);
2756            final long now = SystemClock.uptimeMillis();
2757            boolean haveNewCpuStats = false;
2758
2759            if (MONITOR_CPU_USAGE &&
2760                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761                mLastCpuTime.set(now);
2762                mProcessCpuTracker.update();
2763                if (mProcessCpuTracker.hasGoodLastStats()) {
2764                    haveNewCpuStats = true;
2765                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2766                    //Slog.i(TAG, "Total CPU usage: "
2767                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2768
2769                    // Slog the cpu usage if the property is set.
2770                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2771                        int user = mProcessCpuTracker.getLastUserTime();
2772                        int system = mProcessCpuTracker.getLastSystemTime();
2773                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774                        int irq = mProcessCpuTracker.getLastIrqTime();
2775                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776                        int idle = mProcessCpuTracker.getLastIdleTime();
2777
2778                        int total = user + system + iowait + irq + softIrq + idle;
2779                        if (total == 0) total = 1;
2780
2781                        EventLog.writeEvent(EventLogTags.CPU,
2782                                ((user+system+iowait+irq+softIrq) * 100) / total,
2783                                (user * 100) / total,
2784                                (system * 100) / total,
2785                                (iowait * 100) / total,
2786                                (irq * 100) / total,
2787                                (softIrq * 100) / total);
2788                    }
2789                }
2790            }
2791
2792            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793            synchronized(bstats) {
2794                synchronized(mPidsSelfLocked) {
2795                    if (haveNewCpuStats) {
2796                        if (bstats.startAddingCpuLocked()) {
2797                            int totalUTime = 0;
2798                            int totalSTime = 0;
2799                            final int N = mProcessCpuTracker.countStats();
2800                            for (int i=0; i<N; i++) {
2801                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2802                                if (!st.working) {
2803                                    continue;
2804                                }
2805                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806                                totalUTime += st.rel_utime;
2807                                totalSTime += st.rel_stime;
2808                                if (pr != null) {
2809                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810                                    if (ps == null || !ps.isActive()) {
2811                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812                                                pr.info.uid, pr.processName);
2813                                    }
2814                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2816                                } else {
2817                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818                                    if (ps == null || !ps.isActive()) {
2819                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2820                                                bstats.mapUid(st.uid), st.name);
2821                                    }
2822                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2823                                }
2824                            }
2825                            final int userTime = mProcessCpuTracker.getLastUserTime();
2826                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2833                        }
2834                    }
2835                }
2836
2837                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838                    mLastWriteTime = now;
2839                    mBatteryStatsService.scheduleWriteToDisk();
2840                }
2841            }
2842        }
2843    }
2844
2845    @Override
2846    public void batteryNeedsCpuUpdate() {
2847        updateCpuStatsNow();
2848    }
2849
2850    @Override
2851    public void batteryPowerChanged(boolean onBattery) {
2852        // When plugging in, update the CPU stats first before changing
2853        // the plug state.
2854        updateCpuStatsNow();
2855        synchronized (this) {
2856            synchronized(mPidsSelfLocked) {
2857                mOnBattery = DEBUG_POWER ? true : onBattery;
2858            }
2859        }
2860    }
2861
2862    @Override
2863    public void batterySendBroadcast(Intent intent) {
2864        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865                AppOpsManager.OP_NONE, null, false, false,
2866                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2867    }
2868
2869    /**
2870     * Initialize the application bind args. These are passed to each
2871     * process when the bindApplication() IPC is sent to the process. They're
2872     * lazily setup to make sure the services are running when they're asked for.
2873     */
2874    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875        if (mAppBindArgs == null) {
2876            mAppBindArgs = new HashMap<>();
2877
2878            // Isolated processes won't get this optimization, so that we don't
2879            // violate the rules about which services they have access to.
2880            if (!isolated) {
2881                // Setup the application init args
2882                mAppBindArgs.put("package", ServiceManager.getService("package"));
2883                mAppBindArgs.put("window", ServiceManager.getService("window"));
2884                mAppBindArgs.put(Context.ALARM_SERVICE,
2885                        ServiceManager.getService(Context.ALARM_SERVICE));
2886            }
2887        }
2888        return mAppBindArgs;
2889    }
2890
2891    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892        if (r == null || mFocusedActivity == r) {
2893            return false;
2894        }
2895
2896        if (!r.isFocusable()) {
2897            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2898            return false;
2899        }
2900
2901        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2902
2903        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906        mDoingSetFocusedActivity = true;
2907
2908        final ActivityRecord last = mFocusedActivity;
2909        mFocusedActivity = r;
2910        if (r.task.isApplicationTask()) {
2911            if (mCurAppTimeTracker != r.appTimeTracker) {
2912                // We are switching app tracking.  Complete the current one.
2913                if (mCurAppTimeTracker != null) {
2914                    mCurAppTimeTracker.stop();
2915                    mHandler.obtainMessage(
2916                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918                    mCurAppTimeTracker = null;
2919                }
2920                if (r.appTimeTracker != null) {
2921                    mCurAppTimeTracker = r.appTimeTracker;
2922                    startTimeTrackingFocusedActivityLocked();
2923                }
2924            } else {
2925                startTimeTrackingFocusedActivityLocked();
2926            }
2927        } else {
2928            r.appTimeTracker = null;
2929        }
2930        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931        // TODO: Probably not, because we don't want to resume voice on switching
2932        // back to this activity
2933        if (r.task.voiceInteractor != null) {
2934            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2935        } else {
2936            finishRunningVoiceLocked();
2937            IVoiceInteractionSession session;
2938            if (last != null && ((session = last.task.voiceSession) != null
2939                    || (session = last.voiceSession) != null)) {
2940                // We had been in a voice interaction session, but now focused has
2941                // move to something different.  Just finish the session, we can't
2942                // return to it and retain the proper state and synchronization with
2943                // the voice interaction service.
2944                finishVoiceTask(session);
2945            }
2946        }
2947        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948            mWindowManager.setFocusedApp(r.appToken, true);
2949        }
2950        applyUpdateLockStateLocked(r);
2951        applyUpdateVrModeLocked(r);
2952        if (mFocusedActivity.userId != mLastFocusedUserId) {
2953            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954            mHandler.obtainMessage(
2955                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956            mLastFocusedUserId = mFocusedActivity.userId;
2957        }
2958
2959        // Log a warning if the focused app is changed during the process. This could
2960        // indicate a problem of the focus setting logic!
2961        if (mFocusedActivity != r) Slog.w(TAG,
2962                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2964
2965        EventLogTags.writeAmFocusedActivity(
2966                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2968                reason);
2969        return true;
2970    }
2971
2972    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973        if (mFocusedActivity != goingAway) {
2974            return;
2975        }
2976
2977        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978        if (focusedStack != null) {
2979            final ActivityRecord top = focusedStack.topActivity();
2980            if (top != null && top.userId != mLastFocusedUserId) {
2981                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982                mHandler.sendMessage(
2983                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984                mLastFocusedUserId = top.userId;
2985            }
2986        }
2987
2988        // Try to move focus to another activity if possible.
2989        if (setFocusedActivityLocked(
2990                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2991            return;
2992        }
2993
2994        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996        mFocusedActivity = null;
2997        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2998    }
2999
3000    @Override
3001    public void setFocusedStack(int stackId) {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004        final long callingId = Binder.clearCallingIdentity();
3005        try {
3006            synchronized (this) {
3007                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008                if (stack == null) {
3009                    return;
3010                }
3011                final ActivityRecord r = stack.topRunningActivityLocked();
3012                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3014                }
3015            }
3016        } finally {
3017            Binder.restoreCallingIdentity(callingId);
3018        }
3019    }
3020
3021    @Override
3022    public void setFocusedTask(int taskId) {
3023        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025        final long callingId = Binder.clearCallingIdentity();
3026        try {
3027            synchronized (this) {
3028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3029                if (task == null) {
3030                    return;
3031                }
3032                final ActivityRecord r = task.topRunningActivityLocked();
3033                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3035                }
3036            }
3037        } finally {
3038            Binder.restoreCallingIdentity(callingId);
3039        }
3040    }
3041
3042    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3043    @Override
3044    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046        synchronized (this) {
3047            if (listener != null) {
3048                mTaskStackListeners.register(listener);
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void notifyActivityDrawn(IBinder token) {
3055        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056        synchronized (this) {
3057            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3058            if (r != null) {
3059                r.task.stack.notifyActivityDrawnLocked(r);
3060            }
3061        }
3062    }
3063
3064    final void applyUpdateLockStateLocked(ActivityRecord r) {
3065        // Modifications to the UpdateLock state are done on our handler, outside
3066        // the activity manager's locks.  The new state is determined based on the
3067        // state *now* of the relevant activity record.  The object is passed to
3068        // the handler solely for logging detail, not to be consulted/modified.
3069        final boolean nextState = r != null && r.immersive;
3070        mHandler.sendMessage(
3071                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3072    }
3073
3074    final void applyUpdateVrModeLocked(ActivityRecord r) {
3075        mHandler.sendMessage(
3076                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3077    }
3078
3079    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080        mHandler.sendMessage(
3081                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3082    }
3083
3084    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3085        Message msg = Message.obtain();
3086        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3087        msg.obj = r.task.askedCompatMode ? null : r;
3088        mUiHandler.sendMessage(msg);
3089    }
3090
3091    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3092            String what, Object obj, ProcessRecord srcApp) {
3093        app.lastActivityTime = now;
3094
3095        if (app.activities.size() > 0) {
3096            // Don't want to touch dependent processes that are hosting activities.
3097            return index;
3098        }
3099
3100        int lrui = mLruProcesses.lastIndexOf(app);
3101        if (lrui < 0) {
3102            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3103                    + what + " " + obj + " from " + srcApp);
3104            return index;
3105        }
3106
3107        if (lrui >= index) {
3108            // Don't want to cause this to move dependent processes *back* in the
3109            // list as if they were less frequently used.
3110            return index;
3111        }
3112
3113        if (lrui >= mLruProcessActivityStart) {
3114            // Don't want to touch dependent processes that are hosting activities.
3115            return index;
3116        }
3117
3118        mLruProcesses.remove(lrui);
3119        if (index > 0) {
3120            index--;
3121        }
3122        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3123                + " in LRU list: " + app);
3124        mLruProcesses.add(index, app);
3125        return index;
3126    }
3127
3128    static void killProcessGroup(int uid, int pid) {
3129        if (sKillHandler != null) {
3130            sKillHandler.sendMessage(
3131                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3132        } else {
3133            Slog.w(TAG, "Asked to kill process group before system bringup!");
3134            Process.killProcessGroup(uid, pid);
3135        }
3136    }
3137
3138    final void removeLruProcessLocked(ProcessRecord app) {
3139        int lrui = mLruProcesses.lastIndexOf(app);
3140        if (lrui >= 0) {
3141            if (!app.killed) {
3142                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3143                Process.killProcessQuiet(app.pid);
3144                killProcessGroup(app.uid, app.pid);
3145            }
3146            if (lrui <= mLruProcessActivityStart) {
3147                mLruProcessActivityStart--;
3148            }
3149            if (lrui <= mLruProcessServiceStart) {
3150                mLruProcessServiceStart--;
3151            }
3152            mLruProcesses.remove(lrui);
3153        }
3154    }
3155
3156    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3157            ProcessRecord client) {
3158        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3159                || app.treatLikeActivity;
3160        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3161        if (!activityChange && hasActivity) {
3162            // The process has activities, so we are only allowing activity-based adjustments
3163            // to move it.  It should be kept in the front of the list with other
3164            // processes that have activities, and we don't want those to change their
3165            // order except due to activity operations.
3166            return;
3167        }
3168
3169        mLruSeq++;
3170        final long now = SystemClock.uptimeMillis();
3171        app.lastActivityTime = now;
3172
3173        // First a quick reject: if the app is already at the position we will
3174        // put it, then there is nothing to do.
3175        if (hasActivity) {
3176            final int N = mLruProcesses.size();
3177            if (N > 0 && mLruProcesses.get(N-1) == app) {
3178                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3179                return;
3180            }
3181        } else {
3182            if (mLruProcessServiceStart > 0
3183                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3184                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3185                return;
3186            }
3187        }
3188
3189        int lrui = mLruProcesses.lastIndexOf(app);
3190
3191        if (app.persistent && lrui >= 0) {
3192            // We don't care about the position of persistent processes, as long as
3193            // they are in the list.
3194            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3195            return;
3196        }
3197
3198        /* In progress: compute new position first, so we can avoid doing work
3199           if the process is not actually going to move.  Not yet working.
3200        int addIndex;
3201        int nextIndex;
3202        boolean inActivity = false, inService = false;
3203        if (hasActivity) {
3204            // Process has activities, put it at the very tipsy-top.
3205            addIndex = mLruProcesses.size();
3206            nextIndex = mLruProcessServiceStart;
3207            inActivity = true;
3208        } else if (hasService) {
3209            // Process has services, put it at the top of the service list.
3210            addIndex = mLruProcessActivityStart;
3211            nextIndex = mLruProcessServiceStart;
3212            inActivity = true;
3213            inService = true;
3214        } else  {
3215            // Process not otherwise of interest, it goes to the top of the non-service area.
3216            addIndex = mLruProcessServiceStart;
3217            if (client != null) {
3218                int clientIndex = mLruProcesses.lastIndexOf(client);
3219                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3220                        + app);
3221                if (clientIndex >= 0 && addIndex > clientIndex) {
3222                    addIndex = clientIndex;
3223                }
3224            }
3225            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3226        }
3227
3228        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3229                + mLruProcessActivityStart + "): " + app);
3230        */
3231
3232        if (lrui >= 0) {
3233            if (lrui < mLruProcessActivityStart) {
3234                mLruProcessActivityStart--;
3235            }
3236            if (lrui < mLruProcessServiceStart) {
3237                mLruProcessServiceStart--;
3238            }
3239            /*
3240            if (addIndex > lrui) {
3241                addIndex--;
3242            }
3243            if (nextIndex > lrui) {
3244                nextIndex--;
3245            }
3246            */
3247            mLruProcesses.remove(lrui);
3248        }
3249
3250        /*
3251        mLruProcesses.add(addIndex, app);
3252        if (inActivity) {
3253            mLruProcessActivityStart++;
3254        }
3255        if (inService) {
3256            mLruProcessActivityStart++;
3257        }
3258        */
3259
3260        int nextIndex;
3261        if (hasActivity) {
3262            final int N = mLruProcesses.size();
3263            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3264                // Process doesn't have activities, but has clients with
3265                // activities...  move it up, but one below the top (the top
3266                // should always have a real activity).
3267                if (DEBUG_LRU) Slog.d(TAG_LRU,
3268                        "Adding to second-top of LRU activity list: " + app);
3269                mLruProcesses.add(N - 1, app);
3270                // To keep it from spamming the LRU list (by making a bunch of clients),
3271                // we will push down any other entries owned by the app.
3272                final int uid = app.info.uid;
3273                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3274                    ProcessRecord subProc = mLruProcesses.get(i);
3275                    if (subProc.info.uid == uid) {
3276                        // We want to push this one down the list.  If the process after
3277                        // it is for the same uid, however, don't do so, because we don't
3278                        // want them internally to be re-ordered.
3279                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3280                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3281                                    "Pushing uid " + uid + " swapping at " + i + ": "
3282                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3283                            ProcessRecord tmp = mLruProcesses.get(i);
3284                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3285                            mLruProcesses.set(i - 1, tmp);
3286                            i--;
3287                        }
3288                    } else {
3289                        // A gap, we can stop here.
3290                        break;
3291                    }
3292                }
3293            } else {
3294                // Process has activities, put it at the very tipsy-top.
3295                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3296                mLruProcesses.add(app);
3297            }
3298            nextIndex = mLruProcessServiceStart;
3299        } else if (hasService) {
3300            // Process has services, put it at the top of the service list.
3301            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3302            mLruProcesses.add(mLruProcessActivityStart, app);
3303            nextIndex = mLruProcessServiceStart;
3304            mLruProcessActivityStart++;
3305        } else  {
3306            // Process not otherwise of interest, it goes to the top of the non-service area.
3307            int index = mLruProcessServiceStart;
3308            if (client != null) {
3309                // If there is a client, don't allow the process to be moved up higher
3310                // in the list than that client.
3311                int clientIndex = mLruProcesses.lastIndexOf(client);
3312                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3313                        + " when updating " + app);
3314                if (clientIndex <= lrui) {
3315                    // Don't allow the client index restriction to push it down farther in the
3316                    // list than it already is.
3317                    clientIndex = lrui;
3318                }
3319                if (clientIndex >= 0 && index > clientIndex) {
3320                    index = clientIndex;
3321                }
3322            }
3323            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3324            mLruProcesses.add(index, app);
3325            nextIndex = index-1;
3326            mLruProcessActivityStart++;
3327            mLruProcessServiceStart++;
3328        }
3329
3330        // If the app is currently using a content provider or service,
3331        // bump those processes as well.
3332        for (int j=app.connections.size()-1; j>=0; j--) {
3333            ConnectionRecord cr = app.connections.valueAt(j);
3334            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3335                    && cr.binding.service.app != null
3336                    && cr.binding.service.app.lruSeq != mLruSeq
3337                    && !cr.binding.service.app.persistent) {
3338                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3339                        "service connection", cr, app);
3340            }
3341        }
3342        for (int j=app.conProviders.size()-1; j>=0; j--) {
3343            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3344            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3345                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3346                        "provider reference", cpr, app);
3347            }
3348        }
3349    }
3350
3351    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3352        if (uid == Process.SYSTEM_UID) {
3353            // The system gets to run in any process.  If there are multiple
3354            // processes with the same uid, just pick the first (this
3355            // should never happen).
3356            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3357            if (procs == null) return null;
3358            final int procCount = procs.size();
3359            for (int i = 0; i < procCount; i++) {
3360                final int procUid = procs.keyAt(i);
3361                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3362                    // Don't use an app process or different user process for system component.
3363                    continue;
3364                }
3365                return procs.valueAt(i);
3366            }
3367        }
3368        ProcessRecord proc = mProcessNames.get(processName, uid);
3369        if (false && proc != null && !keepIfLarge
3370                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3371                && proc.lastCachedPss >= 4000) {
3372            // Turn this condition on to cause killing to happen regularly, for testing.
3373            if (proc.baseProcessTracker != null) {
3374                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3375            }
3376            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3377        } else if (proc != null && !keepIfLarge
3378                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3379                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3380            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3381            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3382                if (proc.baseProcessTracker != null) {
3383                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3384                }
3385                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3386            }
3387        }
3388        return proc;
3389    }
3390
3391    void notifyPackageUse(String packageName, int reason) {
3392        IPackageManager pm = AppGlobals.getPackageManager();
3393        try {
3394            pm.notifyPackageUse(packageName, reason);
3395        } catch (RemoteException e) {
3396        }
3397    }
3398
3399    boolean isNextTransitionForward() {
3400        int transit = mWindowManager.getPendingAppTransition();
3401        return transit == TRANSIT_ACTIVITY_OPEN
3402                || transit == TRANSIT_TASK_OPEN
3403                || transit == TRANSIT_TASK_TO_FRONT;
3404    }
3405
3406    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3407            String processName, String abiOverride, int uid, Runnable crashHandler) {
3408        synchronized(this) {
3409            ApplicationInfo info = new ApplicationInfo();
3410            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3411            // For isolated processes, the former contains the parent's uid and the latter the
3412            // actual uid of the isolated process.
3413            // In the special case introduced by this method (which is, starting an isolated
3414            // process directly from the SystemServer without an actual parent app process) the
3415            // closest thing to a parent's uid is SYSTEM_UID.
3416            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3417            // the |isolated| logic in the ProcessRecord constructor.
3418            info.uid = Process.SYSTEM_UID;
3419            info.processName = processName;
3420            info.className = entryPoint;
3421            info.packageName = "android";
3422            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3423                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3424                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3425                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3426                    crashHandler);
3427            return proc != null ? proc.pid : 0;
3428        }
3429    }
3430
3431    final ProcessRecord startProcessLocked(String processName,
3432            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3433            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3434            boolean isolated, boolean keepIfLarge) {
3435        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3436                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3437                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3438                null /* crashHandler */);
3439    }
3440
3441    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3442            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3443            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3444            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3445        long startTime = SystemClock.elapsedRealtime();
3446        ProcessRecord app;
3447        if (!isolated) {
3448            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3449            checkTime(startTime, "startProcess: after getProcessRecord");
3450
3451            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3452                // If we are in the background, then check to see if this process
3453                // is bad.  If so, we will just silently fail.
3454                if (mAppErrors.isBadProcessLocked(info)) {
3455                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3456                            + "/" + info.processName);
3457                    return null;
3458                }
3459            } else {
3460                // When the user is explicitly starting a process, then clear its
3461                // crash count so that we won't make it bad until they see at
3462                // least one crash dialog again, and make the process good again
3463                // if it had been bad.
3464                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3465                        + "/" + info.processName);
3466                mAppErrors.resetProcessCrashTimeLocked(info);
3467                if (mAppErrors.isBadProcessLocked(info)) {
3468                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3469                            UserHandle.getUserId(info.uid), info.uid,
3470                            info.processName);
3471                    mAppErrors.clearBadProcessLocked(info);
3472                    if (app != null) {
3473                        app.bad = false;
3474                    }
3475                }
3476            }
3477        } else {
3478            // If this is an isolated process, it can't re-use an existing process.
3479            app = null;
3480        }
3481
3482        // app launch boost for big.little configurations
3483        // use cpusets to migrate freshly launched tasks to big cores
3484        synchronized(ActivityManagerService.this) {
3485            nativeMigrateToBoost();
3486            mIsBoosted = true;
3487            mBoostStartTime = SystemClock.uptimeMillis();
3488            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3489            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3490        }
3491
3492        // We don't have to do anything more if:
3493        // (1) There is an existing application record; and
3494        // (2) The caller doesn't think it is dead, OR there is no thread
3495        //     object attached to it so we know it couldn't have crashed; and
3496        // (3) There is a pid assigned to it, so it is either starting or
3497        //     already running.
3498        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3499                + " app=" + app + " knownToBeDead=" + knownToBeDead
3500                + " thread=" + (app != null ? app.thread : null)
3501                + " pid=" + (app != null ? app.pid : -1));
3502        if (app != null && app.pid > 0) {
3503            if (!knownToBeDead || app.thread == null) {
3504                // We already have the app running, or are waiting for it to
3505                // come up (we have a pid but not yet its thread), so keep it.
3506                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3507                // If this is a new package in the process, add the package to the list
3508                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509                checkTime(startTime, "startProcess: done, added package to proc");
3510                return app;
3511            }
3512
3513            // An application record is attached to a previous process,
3514            // clean it up now.
3515            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3516            checkTime(startTime, "startProcess: bad proc running, killing");
3517            killProcessGroup(app.uid, app.pid);
3518            handleAppDiedLocked(app, true, true);
3519            checkTime(startTime, "startProcess: done killing old proc");
3520        }
3521
3522        String hostingNameStr = hostingName != null
3523                ? hostingName.flattenToShortString() : null;
3524
3525        if (app == null) {
3526            checkTime(startTime, "startProcess: creating new process record");
3527            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3528            if (app == null) {
3529                Slog.w(TAG, "Failed making new process record for "
3530                        + processName + "/" + info.uid + " isolated=" + isolated);
3531                return null;
3532            }
3533            app.crashHandler = crashHandler;
3534            checkTime(startTime, "startProcess: done creating new process record");
3535        } else {
3536            // If this is a new package in the process, add the package to the list
3537            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3538            checkTime(startTime, "startProcess: added package to existing proc");
3539        }
3540
3541        // If the system is not ready yet, then hold off on starting this
3542        // process until it is.
3543        if (!mProcessesReady
3544                && !isAllowedWhileBooting(info)
3545                && !allowWhileBooting) {
3546            if (!mProcessesOnHold.contains(app)) {
3547                mProcessesOnHold.add(app);
3548            }
3549            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3550                    "System not ready, putting on hold: " + app);
3551            checkTime(startTime, "startProcess: returning with proc on hold");
3552            return app;
3553        }
3554
3555        checkTime(startTime, "startProcess: stepping in to startProcess");
3556        startProcessLocked(
3557                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3558        checkTime(startTime, "startProcess: done starting proc!");
3559        return (app.pid != 0) ? app : null;
3560    }
3561
3562    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3563        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3564    }
3565
3566    private final void startProcessLocked(ProcessRecord app,
3567            String hostingType, String hostingNameStr) {
3568        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3569                null /* entryPoint */, null /* entryPointArgs */);
3570    }
3571
3572    private final void startProcessLocked(ProcessRecord app, String hostingType,
3573            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3574        long startTime = SystemClock.elapsedRealtime();
3575        if (app.pid > 0 && app.pid != MY_PID) {
3576            checkTime(startTime, "startProcess: removing from pids map");
3577            synchronized (mPidsSelfLocked) {
3578                mPidsSelfLocked.remove(app.pid);
3579                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3580            }
3581            checkTime(startTime, "startProcess: done removing from pids map");
3582            app.setPid(0);
3583        }
3584
3585        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3586                "startProcessLocked removing on hold: " + app);
3587        mProcessesOnHold.remove(app);
3588
3589        checkTime(startTime, "startProcess: starting to update cpu stats");
3590        updateCpuStats();
3591        checkTime(startTime, "startProcess: done updating cpu stats");
3592
3593        try {
3594            try {
3595                final int userId = UserHandle.getUserId(app.uid);
3596                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3597            } catch (RemoteException e) {
3598                throw e.rethrowAsRuntimeException();
3599            }
3600
3601            int uid = app.uid;
3602            int[] gids = null;
3603            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3604            if (!app.isolated) {
3605                int[] permGids = null;
3606                try {
3607                    checkTime(startTime, "startProcess: getting gids from package manager");
3608                    final IPackageManager pm = AppGlobals.getPackageManager();
3609                    permGids = pm.getPackageGids(app.info.packageName,
3610                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3611                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3612                            MountServiceInternal.class);
3613                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3614                            app.info.packageName);
3615                } catch (RemoteException e) {
3616                    throw e.rethrowAsRuntimeException();
3617                }
3618
3619                /*
3620                 * Add shared application and profile GIDs so applications can share some
3621                 * resources like shared libraries and access user-wide resources
3622                 */
3623                if (ArrayUtils.isEmpty(permGids)) {
3624                    gids = new int[2];
3625                } else {
3626                    gids = new int[permGids.length + 2];
3627                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3628                }
3629                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3630                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3631            }
3632            checkTime(startTime, "startProcess: building args");
3633            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3634                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3635                        && mTopComponent != null
3636                        && app.processName.equals(mTopComponent.getPackageName())) {
3637                    uid = 0;
3638                }
3639                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3640                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3641                    uid = 0;
3642                }
3643            }
3644            int debugFlags = 0;
3645            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3646                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3647                // Also turn on CheckJNI for debuggable apps. It's quite
3648                // awkward to turn on otherwise.
3649                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3650            }
3651            // Run the app in safe mode if its manifest requests so or the
3652            // system is booted in safe mode.
3653            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3654                mSafeMode == true) {
3655                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3656            }
3657            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3658                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3659            }
3660            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3661            if ("true".equals(genDebugInfoProperty)) {
3662                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3663            }
3664            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3665                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.assert"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3669            }
3670            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3671                // Enable all debug flags required by the native debugger.
3672                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3673                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3674                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3675                mNativeDebuggingApp = null;
3676            }
3677
3678            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3679            if (requiredAbi == null) {
3680                requiredAbi = Build.SUPPORTED_ABIS[0];
3681            }
3682
3683            String instructionSet = null;
3684            if (app.info.primaryCpuAbi != null) {
3685                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3686            }
3687
3688            app.gids = gids;
3689            app.requiredAbi = requiredAbi;
3690            app.instructionSet = instructionSet;
3691
3692            // Start the process.  It will either succeed and return a result containing
3693            // the PID of the new process, or else throw a RuntimeException.
3694            boolean isActivityProcess = (entryPoint == null);
3695            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3696            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3697                    app.processName);
3698            checkTime(startTime, "startProcess: asking zygote to start proc");
3699            Process.ProcessStartResult startResult = Process.start(entryPoint,
3700                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3701                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3702                    app.info.dataDir, entryPointArgs);
3703            checkTime(startTime, "startProcess: returned from zygote!");
3704            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3705
3706            if (app.isolated) {
3707                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3708            }
3709            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3710            checkTime(startTime, "startProcess: done updating battery stats");
3711
3712            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3713                    UserHandle.getUserId(uid), startResult.pid, uid,
3714                    app.processName, hostingType,
3715                    hostingNameStr != null ? hostingNameStr : "");
3716
3717            try {
3718                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3719                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3720            } catch (RemoteException ex) {
3721                // Ignore
3722            }
3723
3724            if (app.persistent) {
3725                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3726            }
3727
3728            checkTime(startTime, "startProcess: building log message");
3729            StringBuilder buf = mStringBuilder;
3730            buf.setLength(0);
3731            buf.append("Start proc ");
3732            buf.append(startResult.pid);
3733            buf.append(':');
3734            buf.append(app.processName);
3735            buf.append('/');
3736            UserHandle.formatUid(buf, uid);
3737            if (!isActivityProcess) {
3738                buf.append(" [");
3739                buf.append(entryPoint);
3740                buf.append("]");
3741            }
3742            buf.append(" for ");
3743            buf.append(hostingType);
3744            if (hostingNameStr != null) {
3745                buf.append(" ");
3746                buf.append(hostingNameStr);
3747            }
3748            Slog.i(TAG, buf.toString());
3749            app.setPid(startResult.pid);
3750            app.usingWrapper = startResult.usingWrapper;
3751            app.removed = false;
3752            app.killed = false;
3753            app.killedByAm = false;
3754            checkTime(startTime, "startProcess: starting to update pids map");
3755            synchronized (mPidsSelfLocked) {
3756                this.mPidsSelfLocked.put(startResult.pid, app);
3757                if (isActivityProcess) {
3758                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3759                    msg.obj = app;
3760                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3761                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3762                }
3763            }
3764            checkTime(startTime, "startProcess: done updating pids map");
3765        } catch (RuntimeException e) {
3766            Slog.e(TAG, "Failure starting process " + app.processName, e);
3767
3768            // Something went very wrong while trying to start this process; one
3769            // common case is when the package is frozen due to an active
3770            // upgrade. To recover, clean up any active bookkeeping related to
3771            // starting this process. (We already invoked this method once when
3772            // the package was initially frozen through KILL_APPLICATION_MSG, so
3773            // it doesn't hurt to use it again.)
3774            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3775                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3776        }
3777    }
3778
3779    void updateUsageStats(ActivityRecord component, boolean resumed) {
3780        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3781                "updateUsageStats: comp=" + component + "res=" + resumed);
3782        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3783        if (resumed) {
3784            if (mUsageStatsService != null) {
3785                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3786                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3787            }
3788            synchronized (stats) {
3789                stats.noteActivityResumedLocked(component.app.uid);
3790            }
3791        } else {
3792            if (mUsageStatsService != null) {
3793                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3794                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3795            }
3796            synchronized (stats) {
3797                stats.noteActivityPausedLocked(component.app.uid);
3798            }
3799        }
3800    }
3801
3802    Intent getHomeIntent() {
3803        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3804        intent.setComponent(mTopComponent);
3805        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3806        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3807            intent.addCategory(Intent.CATEGORY_HOME);
3808        }
3809        return intent;
3810    }
3811
3812    boolean startHomeActivityLocked(int userId, String reason) {
3813        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3814                && mTopAction == null) {
3815            // We are running in factory test mode, but unable to find
3816            // the factory test app, so just sit around displaying the
3817            // error message and don't try to start anything.
3818            return false;
3819        }
3820        Intent intent = getHomeIntent();
3821        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3822        if (aInfo != null) {
3823            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3824            // Don't do this if the home app is currently being
3825            // instrumented.
3826            aInfo = new ActivityInfo(aInfo);
3827            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3828            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3829                    aInfo.applicationInfo.uid, true);
3830            if (app == null || app.instrumentationClass == null) {
3831                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3832                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3833            }
3834        } else {
3835            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3836        }
3837
3838        return true;
3839    }
3840
3841    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3842        ActivityInfo ai = null;
3843        ComponentName comp = intent.getComponent();
3844        try {
3845            if (comp != null) {
3846                // Factory test.
3847                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3848            } else {
3849                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3850                        intent,
3851                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3852                        flags, userId);
3853
3854                if (info != null) {
3855                    ai = info.activityInfo;
3856                }
3857            }
3858        } catch (RemoteException e) {
3859            // ignore
3860        }
3861
3862        return ai;
3863    }
3864
3865    /**
3866     * Starts the "new version setup screen" if appropriate.
3867     */
3868    void startSetupActivityLocked() {
3869        // Only do this once per boot.
3870        if (mCheckedForSetup) {
3871            return;
3872        }
3873
3874        // We will show this screen if the current one is a different
3875        // version than the last one shown, and we are not running in
3876        // low-level factory test mode.
3877        final ContentResolver resolver = mContext.getContentResolver();
3878        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3879                Settings.Global.getInt(resolver,
3880                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3881            mCheckedForSetup = true;
3882
3883            // See if we should be showing the platform update setup UI.
3884            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3885            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3886                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3887            if (!ris.isEmpty()) {
3888                final ResolveInfo ri = ris.get(0);
3889                String vers = ri.activityInfo.metaData != null
3890                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3891                        : null;
3892                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3893                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3894                            Intent.METADATA_SETUP_VERSION);
3895                }
3896                String lastVers = Settings.Secure.getString(
3897                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3898                if (vers != null && !vers.equals(lastVers)) {
3899                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3900                    intent.setComponent(new ComponentName(
3901                            ri.activityInfo.packageName, ri.activityInfo.name));
3902                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3903                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3904                            null, 0, 0, 0, null, false, false, null, null, null);
3905                }
3906            }
3907        }
3908    }
3909
3910    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3911        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3912    }
3913
3914    void enforceNotIsolatedCaller(String caller) {
3915        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3916            throw new SecurityException("Isolated process not allowed to call " + caller);
3917        }
3918    }
3919
3920    void enforceShellRestriction(String restriction, int userHandle) {
3921        if (Binder.getCallingUid() == Process.SHELL_UID) {
3922            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3923                throw new SecurityException("Shell does not have permission to access user "
3924                        + userHandle);
3925            }
3926        }
3927    }
3928
3929    @Override
3930    public int getFrontActivityScreenCompatMode() {
3931        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3932        synchronized (this) {
3933            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3934        }
3935    }
3936
3937    @Override
3938    public void setFrontActivityScreenCompatMode(int mode) {
3939        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3940                "setFrontActivityScreenCompatMode");
3941        synchronized (this) {
3942            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3943        }
3944    }
3945
3946    @Override
3947    public int getPackageScreenCompatMode(String packageName) {
3948        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3949        synchronized (this) {
3950            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3951        }
3952    }
3953
3954    @Override
3955    public void setPackageScreenCompatMode(String packageName, int mode) {
3956        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3957                "setPackageScreenCompatMode");
3958        synchronized (this) {
3959            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3960        }
3961    }
3962
3963    @Override
3964    public boolean getPackageAskScreenCompat(String packageName) {
3965        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3966        synchronized (this) {
3967            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3968        }
3969    }
3970
3971    @Override
3972    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3973        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3974                "setPackageAskScreenCompat");
3975        synchronized (this) {
3976            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3977        }
3978    }
3979
3980    private boolean hasUsageStatsPermission(String callingPackage) {
3981        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3982                Binder.getCallingUid(), callingPackage);
3983        if (mode == AppOpsManager.MODE_DEFAULT) {
3984            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3985                    == PackageManager.PERMISSION_GRANTED;
3986        }
3987        return mode == AppOpsManager.MODE_ALLOWED;
3988    }
3989
3990    @Override
3991    public int getPackageProcessState(String packageName, String callingPackage) {
3992        if (!hasUsageStatsPermission(callingPackage)) {
3993            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3994                    "getPackageProcessState");
3995        }
3996
3997        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3998        synchronized (this) {
3999            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4000                final ProcessRecord proc = mLruProcesses.get(i);
4001                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4002                        || procState > proc.setProcState) {
4003                    boolean found = false;
4004                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4005                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4006                            procState = proc.setProcState;
4007                            found = true;
4008                        }
4009                    }
4010                    if (proc.pkgDeps != null && !found) {
4011                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4012                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4013                                procState = proc.setProcState;
4014                                break;
4015                            }
4016                        }
4017                    }
4018                }
4019            }
4020        }
4021        return procState;
4022    }
4023
4024    @Override
4025    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4026        synchronized (this) {
4027            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4028            if (app == null) {
4029                return false;
4030            }
4031            if (app.trimMemoryLevel < level && app.thread != null &&
4032                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4033                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4034                try {
4035                    app.thread.scheduleTrimMemory(level);
4036                    app.trimMemoryLevel = level;
4037                    return true;
4038                } catch (RemoteException e) {
4039                    // Fallthrough to failure case.
4040                }
4041            }
4042        }
4043        return false;
4044    }
4045
4046    private void dispatchProcessesChanged() {
4047        int N;
4048        synchronized (this) {
4049            N = mPendingProcessChanges.size();
4050            if (mActiveProcessChanges.length < N) {
4051                mActiveProcessChanges = new ProcessChangeItem[N];
4052            }
4053            mPendingProcessChanges.toArray(mActiveProcessChanges);
4054            mPendingProcessChanges.clear();
4055            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4056                    "*** Delivering " + N + " process changes");
4057        }
4058
4059        int i = mProcessObservers.beginBroadcast();
4060        while (i > 0) {
4061            i--;
4062            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4063            if (observer != null) {
4064                try {
4065                    for (int j=0; j<N; j++) {
4066                        ProcessChangeItem item = mActiveProcessChanges[j];
4067                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4068                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4069                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4070                                    + item.uid + ": " + item.foregroundActivities);
4071                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4072                                    item.foregroundActivities);
4073                        }
4074                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4075                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4076                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4077                                    + ": " + item.processState);
4078                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4079                        }
4080                    }
4081                } catch (RemoteException e) {
4082                }
4083            }
4084        }
4085        mProcessObservers.finishBroadcast();
4086
4087        synchronized (this) {
4088            for (int j=0; j<N; j++) {
4089                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4090            }
4091        }
4092    }
4093
4094    private void dispatchProcessDied(int pid, int uid) {
4095        int i = mProcessObservers.beginBroadcast();
4096        while (i > 0) {
4097            i--;
4098            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4099            if (observer != null) {
4100                try {
4101                    observer.onProcessDied(pid, uid);
4102                } catch (RemoteException e) {
4103                }
4104            }
4105        }
4106        mProcessObservers.finishBroadcast();
4107    }
4108
4109    private void dispatchUidsChanged() {
4110        int N;
4111        synchronized (this) {
4112            N = mPendingUidChanges.size();
4113            if (mActiveUidChanges.length < N) {
4114                mActiveUidChanges = new UidRecord.ChangeItem[N];
4115            }
4116            for (int i=0; i<N; i++) {
4117                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4118                mActiveUidChanges[i] = change;
4119                if (change.uidRecord != null) {
4120                    change.uidRecord.pendingChange = null;
4121                    change.uidRecord = null;
4122                }
4123            }
4124            mPendingUidChanges.clear();
4125            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4126                    "*** Delivering " + N + " uid changes");
4127        }
4128
4129        if (mLocalPowerManager != null) {
4130            for (int j=0; j<N; j++) {
4131                UidRecord.ChangeItem item = mActiveUidChanges[j];
4132                if (item.change == UidRecord.CHANGE_GONE
4133                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4134                    mLocalPowerManager.uidGone(item.uid);
4135                } else {
4136                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4137                }
4138            }
4139        }
4140
4141        int i = mUidObservers.beginBroadcast();
4142        while (i > 0) {
4143            i--;
4144            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4145            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4146            if (observer != null) {
4147                try {
4148                    for (int j=0; j<N; j++) {
4149                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4150                        final int change = item.change;
4151                        UidRecord validateUid = null;
4152                        if (VALIDATE_UID_STATES && i == 0) {
4153                            validateUid = mValidateUids.get(item.uid);
4154                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4155                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4156                                validateUid = new UidRecord(item.uid);
4157                                mValidateUids.put(item.uid, validateUid);
4158                            }
4159                        }
4160                        if (change == UidRecord.CHANGE_IDLE
4161                                || change == UidRecord.CHANGE_GONE_IDLE) {
4162                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4163                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4164                                        "UID idle uid=" + item.uid);
4165                                observer.onUidIdle(item.uid);
4166                            }
4167                            if (VALIDATE_UID_STATES && i == 0) {
4168                                if (validateUid != null) {
4169                                    validateUid.idle = true;
4170                                }
4171                            }
4172                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4173                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4174                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175                                        "UID active uid=" + item.uid);
4176                                observer.onUidActive(item.uid);
4177                            }
4178                            if (VALIDATE_UID_STATES && i == 0) {
4179                                validateUid.idle = false;
4180                            }
4181                        }
4182                        if (change == UidRecord.CHANGE_GONE
4183                                || change == UidRecord.CHANGE_GONE_IDLE) {
4184                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4185                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186                                        "UID gone uid=" + item.uid);
4187                                observer.onUidGone(item.uid);
4188                            }
4189                            if (VALIDATE_UID_STATES && i == 0) {
4190                                if (validateUid != null) {
4191                                    mValidateUids.remove(item.uid);
4192                                }
4193                            }
4194                        } else {
4195                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4196                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197                                        "UID CHANGED uid=" + item.uid
4198                                                + ": " + item.processState);
4199                                observer.onUidStateChanged(item.uid, item.processState);
4200                            }
4201                            if (VALIDATE_UID_STATES && i == 0) {
4202                                validateUid.curProcState = validateUid.setProcState
4203                                        = item.processState;
4204                            }
4205                        }
4206                    }
4207                } catch (RemoteException e) {
4208                }
4209            }
4210        }
4211        mUidObservers.finishBroadcast();
4212
4213        synchronized (this) {
4214            for (int j=0; j<N; j++) {
4215                mAvailUidChanges.add(mActiveUidChanges[j]);
4216            }
4217        }
4218    }
4219
4220    @Override
4221    public final int startActivity(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4224        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4225                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4226                UserHandle.getCallingUserId());
4227    }
4228
4229    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4230        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4231        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4232                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4233                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4234
4235        // TODO: Switch to user app stacks here.
4236        String mimeType = intent.getType();
4237        final Uri data = intent.getData();
4238        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4239            mimeType = getProviderMimeType(data, userId);
4240        }
4241        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4242
4243        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4244        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4245                null, 0, 0, null, null, null, null, false, userId, container, null);
4246    }
4247
4248    @Override
4249    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4250            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4251            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4252        enforceNotIsolatedCaller("startActivity");
4253        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4254                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4255        // TODO: Switch to user app stacks here.
4256        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4257                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4258                profilerInfo, null, null, bOptions, false, userId, null, null);
4259    }
4260
4261    @Override
4262    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4263            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4265            int userId) {
4266
4267        // This is very dangerous -- it allows you to perform a start activity (including
4268        // permission grants) as any app that may launch one of your own activities.  So
4269        // we will only allow this to be done from activities that are part of the core framework,
4270        // and then only when they are running as the system.
4271        final ActivityRecord sourceRecord;
4272        final int targetUid;
4273        final String targetPackage;
4274        synchronized (this) {
4275            if (resultTo == null) {
4276                throw new SecurityException("Must be called from an activity");
4277            }
4278            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4279            if (sourceRecord == null) {
4280                throw new SecurityException("Called with bad activity token: " + resultTo);
4281            }
4282            if (!sourceRecord.info.packageName.equals("android")) {
4283                throw new SecurityException(
4284                        "Must be called from an activity that is declared in the android package");
4285            }
4286            if (sourceRecord.app == null) {
4287                throw new SecurityException("Called without a process attached to activity");
4288            }
4289            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4290                // This is still okay, as long as this activity is running under the
4291                // uid of the original calling activity.
4292                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4293                    throw new SecurityException(
4294                            "Calling activity in uid " + sourceRecord.app.uid
4295                                    + " must be system uid or original calling uid "
4296                                    + sourceRecord.launchedFromUid);
4297                }
4298            }
4299            if (ignoreTargetSecurity) {
4300                if (intent.getComponent() == null) {
4301                    throw new SecurityException(
4302                            "Component must be specified with ignoreTargetSecurity");
4303                }
4304                if (intent.getSelector() != null) {
4305                    throw new SecurityException(
4306                            "Selector not allowed with ignoreTargetSecurity");
4307                }
4308            }
4309            targetUid = sourceRecord.launchedFromUid;
4310            targetPackage = sourceRecord.launchedFromPackage;
4311        }
4312
4313        if (userId == UserHandle.USER_NULL) {
4314            userId = UserHandle.getUserId(sourceRecord.app.uid);
4315        }
4316
4317        // TODO: Switch to user app stacks here.
4318        try {
4319            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4320                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4321                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4322            return ret;
4323        } catch (SecurityException e) {
4324            // XXX need to figure out how to propagate to original app.
4325            // A SecurityException here is generally actually a fault of the original
4326            // calling activity (such as a fairly granting permissions), so propagate it
4327            // back to them.
4328            /*
4329            StringBuilder msg = new StringBuilder();
4330            msg.append("While launching");
4331            msg.append(intent.toString());
4332            msg.append(": ");
4333            msg.append(e.getMessage());
4334            */
4335            throw e;
4336        }
4337    }
4338
4339    @Override
4340    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4342            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4343        enforceNotIsolatedCaller("startActivityAndWait");
4344        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4345                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4346        WaitResult res = new WaitResult();
4347        // TODO: Switch to user app stacks here.
4348        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4349                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4350                bOptions, false, userId, null, null);
4351        return res;
4352    }
4353
4354    @Override
4355    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4356            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4357            int startFlags, Configuration config, Bundle bOptions, int userId) {
4358        enforceNotIsolatedCaller("startActivityWithConfig");
4359        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4361        // TODO: Switch to user app stacks here.
4362        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4363                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4364                null, null, config, bOptions, false, userId, null, null);
4365        return ret;
4366    }
4367
4368    @Override
4369    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4370            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4371            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4372            throws TransactionTooLargeException {
4373        enforceNotIsolatedCaller("startActivityIntentSender");
4374        // Refuse possible leaked file descriptors
4375        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4376            throw new IllegalArgumentException("File descriptors passed in Intent");
4377        }
4378
4379        IIntentSender sender = intent.getTarget();
4380        if (!(sender instanceof PendingIntentRecord)) {
4381            throw new IllegalArgumentException("Bad PendingIntent object");
4382        }
4383
4384        PendingIntentRecord pir = (PendingIntentRecord)sender;
4385
4386        synchronized (this) {
4387            // If this is coming from the currently resumed activity, it is
4388            // effectively saying that app switches are allowed at this point.
4389            final ActivityStack stack = getFocusedStack();
4390            if (stack.mResumedActivity != null &&
4391                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4392                mAppSwitchesAllowedTime = 0;
4393            }
4394        }
4395        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4396                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4397        return ret;
4398    }
4399
4400    @Override
4401    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4402            Intent intent, String resolvedType, IVoiceInteractionSession session,
4403            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4404            Bundle bOptions, int userId) {
4405        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4406                != PackageManager.PERMISSION_GRANTED) {
4407            String msg = "Permission Denial: startVoiceActivity() from pid="
4408                    + Binder.getCallingPid()
4409                    + ", uid=" + Binder.getCallingUid()
4410                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4411            Slog.w(TAG, msg);
4412            throw new SecurityException(msg);
4413        }
4414        if (session == null || interactor == null) {
4415            throw new NullPointerException("null session or interactor");
4416        }
4417        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4418                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4419        // TODO: Switch to user app stacks here.
4420        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4421                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4422                null, bOptions, false, userId, null, null);
4423    }
4424
4425    @Override
4426    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4427            throws RemoteException {
4428        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4429        synchronized (this) {
4430            ActivityRecord activity = getFocusedStack().topActivity();
4431            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4432                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4433            }
4434            if (mRunningVoice != null || activity.task.voiceSession != null
4435                    || activity.voiceSession != null) {
4436                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4437                return;
4438            }
4439            if (activity.pendingVoiceInteractionStart) {
4440                Slog.w(TAG, "Pending start of voice interaction already.");
4441                return;
4442            }
4443            activity.pendingVoiceInteractionStart = true;
4444        }
4445        LocalServices.getService(VoiceInteractionManagerInternal.class)
4446                .startLocalVoiceInteraction(callingActivity, options);
4447    }
4448
4449    @Override
4450    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4451        LocalServices.getService(VoiceInteractionManagerInternal.class)
4452                .stopLocalVoiceInteraction(callingActivity);
4453    }
4454
4455    @Override
4456    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4457        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4458                .supportsLocalVoiceInteraction();
4459    }
4460
4461    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4462            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4463        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4464        if (activityToCallback == null) return;
4465        activityToCallback.setVoiceSessionLocked(voiceSession);
4466
4467        // Inform the activity
4468        try {
4469            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4470                    voiceInteractor);
4471            long token = Binder.clearCallingIdentity();
4472            try {
4473                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4474            } finally {
4475                Binder.restoreCallingIdentity(token);
4476            }
4477            // TODO: VI Should we cache the activity so that it's easier to find later
4478            // rather than scan through all the stacks and activities?
4479        } catch (RemoteException re) {
4480            activityToCallback.clearVoiceSessionLocked();
4481            // TODO: VI Should this terminate the voice session?
4482        }
4483    }
4484
4485    @Override
4486    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4487        synchronized (this) {
4488            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4489                if (keepAwake) {
4490                    mVoiceWakeLock.acquire();
4491                } else {
4492                    mVoiceWakeLock.release();
4493                }
4494            }
4495        }
4496    }
4497
4498    @Override
4499    public boolean startNextMatchingActivity(IBinder callingActivity,
4500            Intent intent, Bundle bOptions) {
4501        // Refuse possible leaked file descriptors
4502        if (intent != null && intent.hasFileDescriptors() == true) {
4503            throw new IllegalArgumentException("File descriptors passed in Intent");
4504        }
4505        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4506
4507        synchronized (this) {
4508            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4509            if (r == null) {
4510                ActivityOptions.abort(options);
4511                return false;
4512            }
4513            if (r.app == null || r.app.thread == null) {
4514                // The caller is not running...  d'oh!
4515                ActivityOptions.abort(options);
4516                return false;
4517            }
4518            intent = new Intent(intent);
4519            // The caller is not allowed to change the data.
4520            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4521            // And we are resetting to find the next component...
4522            intent.setComponent(null);
4523
4524            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4525
4526            ActivityInfo aInfo = null;
4527            try {
4528                List<ResolveInfo> resolves =
4529                    AppGlobals.getPackageManager().queryIntentActivities(
4530                            intent, r.resolvedType,
4531                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4532                            UserHandle.getCallingUserId()).getList();
4533
4534                // Look for the original activity in the list...
4535                final int N = resolves != null ? resolves.size() : 0;
4536                for (int i=0; i<N; i++) {
4537                    ResolveInfo rInfo = resolves.get(i);
4538                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4539                            && rInfo.activityInfo.name.equals(r.info.name)) {
4540                        // We found the current one...  the next matching is
4541                        // after it.
4542                        i++;
4543                        if (i<N) {
4544                            aInfo = resolves.get(i).activityInfo;
4545                        }
4546                        if (debug) {
4547                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4548                                    + "/" + r.info.name);
4549                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4550                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4551                        }
4552                        break;
4553                    }
4554                }
4555            } catch (RemoteException e) {
4556            }
4557
4558            if (aInfo == null) {
4559                // Nobody who is next!
4560                ActivityOptions.abort(options);
4561                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4562                return false;
4563            }
4564
4565            intent.setComponent(new ComponentName(
4566                    aInfo.applicationInfo.packageName, aInfo.name));
4567            intent.setFlags(intent.getFlags()&~(
4568                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4569                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4570                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4571                    Intent.FLAG_ACTIVITY_NEW_TASK));
4572
4573            // Okay now we need to start the new activity, replacing the
4574            // currently running activity.  This is a little tricky because
4575            // we want to start the new one as if the current one is finished,
4576            // but not finish the current one first so that there is no flicker.
4577            // And thus...
4578            final boolean wasFinishing = r.finishing;
4579            r.finishing = true;
4580
4581            // Propagate reply information over to the new activity.
4582            final ActivityRecord resultTo = r.resultTo;
4583            final String resultWho = r.resultWho;
4584            final int requestCode = r.requestCode;
4585            r.resultTo = null;
4586            if (resultTo != null) {
4587                resultTo.removeResultsLocked(r, resultWho, requestCode);
4588            }
4589
4590            final long origId = Binder.clearCallingIdentity();
4591            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4592                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4593                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4594                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4595                    false, false, null, null, null);
4596            Binder.restoreCallingIdentity(origId);
4597
4598            r.finishing = wasFinishing;
4599            if (res != ActivityManager.START_SUCCESS) {
4600                return false;
4601            }
4602            return true;
4603        }
4604    }
4605
4606    @Override
4607    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4608        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4609            String msg = "Permission Denial: startActivityFromRecents called without " +
4610                    START_TASKS_FROM_RECENTS;
4611            Slog.w(TAG, msg);
4612            throw new SecurityException(msg);
4613        }
4614        final long origId = Binder.clearCallingIdentity();
4615        try {
4616            synchronized (this) {
4617                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4618            }
4619        } finally {
4620            Binder.restoreCallingIdentity(origId);
4621        }
4622    }
4623
4624    final int startActivityInPackage(int uid, String callingPackage,
4625            Intent intent, String resolvedType, IBinder resultTo,
4626            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4627            IActivityContainer container, TaskRecord inTask) {
4628
4629        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4630                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4631
4632        // TODO: Switch to user app stacks here.
4633        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4634                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4635                null, null, null, bOptions, false, userId, container, inTask);
4636        return ret;
4637    }
4638
4639    @Override
4640    public final int startActivities(IApplicationThread caller, String callingPackage,
4641            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4642            int userId) {
4643        enforceNotIsolatedCaller("startActivities");
4644        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4645                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4646        // TODO: Switch to user app stacks here.
4647        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4648                resolvedTypes, resultTo, bOptions, userId);
4649        return ret;
4650    }
4651
4652    final int startActivitiesInPackage(int uid, String callingPackage,
4653            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4654            Bundle bOptions, int userId) {
4655
4656        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4657                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4658        // TODO: Switch to user app stacks here.
4659        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4660                resultTo, bOptions, userId);
4661        return ret;
4662    }
4663
4664    @Override
4665    public void reportActivityFullyDrawn(IBinder token) {
4666        synchronized (this) {
4667            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4668            if (r == null) {
4669                return;
4670            }
4671            r.reportFullyDrawnLocked();
4672        }
4673    }
4674
4675    @Override
4676    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4677        synchronized (this) {
4678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4679            if (r == null) {
4680                return;
4681            }
4682            TaskRecord task = r.task;
4683            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4684                // Fixed screen orientation isn't supported when activities aren't in full screen
4685                // mode.
4686                return;
4687            }
4688            final long origId = Binder.clearCallingIdentity();
4689            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4690            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4691                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4692            if (config != null) {
4693                r.frozenBeforeDestroy = true;
4694                if (!updateConfigurationLocked(config, r, false)) {
4695                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4696                }
4697            }
4698            Binder.restoreCallingIdentity(origId);
4699        }
4700    }
4701
4702    @Override
4703    public int getRequestedOrientation(IBinder token) {
4704        synchronized (this) {
4705            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4706            if (r == null) {
4707                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4708            }
4709            return mWindowManager.getAppOrientation(r.appToken);
4710        }
4711    }
4712
4713    /**
4714     * This is the internal entry point for handling Activity.finish().
4715     *
4716     * @param token The Binder token referencing the Activity we want to finish.
4717     * @param resultCode Result code, if any, from this Activity.
4718     * @param resultData Result data (Intent), if any, from this Activity.
4719     * @param finishTask Whether to finish the task associated with this Activity.
4720     *
4721     * @return Returns true if the activity successfully finished, or false if it is still running.
4722     */
4723    @Override
4724    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4725            int finishTask) {
4726        // Refuse possible leaked file descriptors
4727        if (resultData != null && resultData.hasFileDescriptors() == true) {
4728            throw new IllegalArgumentException("File descriptors passed in Intent");
4729        }
4730
4731        synchronized(this) {
4732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4733            if (r == null) {
4734                return true;
4735            }
4736            // Keep track of the root activity of the task before we finish it
4737            TaskRecord tr = r.task;
4738            ActivityRecord rootR = tr.getRootActivity();
4739            if (rootR == null) {
4740                Slog.w(TAG, "Finishing task with all activities already finished");
4741            }
4742            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4743            // finish.
4744            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4745                    mStackSupervisor.isLastLockedTask(tr)) {
4746                Slog.i(TAG, "Not finishing task in lock task mode");
4747                mStackSupervisor.showLockTaskToast();
4748                return false;
4749            }
4750            if (mController != null) {
4751                // Find the first activity that is not finishing.
4752                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4753                if (next != null) {
4754                    // ask watcher if this is allowed
4755                    boolean resumeOK = true;
4756                    try {
4757                        resumeOK = mController.activityResuming(next.packageName);
4758                    } catch (RemoteException e) {
4759                        mController = null;
4760                        Watchdog.getInstance().setActivityController(null);
4761                    }
4762
4763                    if (!resumeOK) {
4764                        Slog.i(TAG, "Not finishing activity because controller resumed");
4765                        return false;
4766                    }
4767                }
4768            }
4769            final long origId = Binder.clearCallingIdentity();
4770            try {
4771                boolean res;
4772                final boolean finishWithRootActivity =
4773                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4774                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4775                        || (finishWithRootActivity && r == rootR)) {
4776                    // If requested, remove the task that is associated to this activity only if it
4777                    // was the root activity in the task. The result code and data is ignored
4778                    // because we don't support returning them across task boundaries. Also, to
4779                    // keep backwards compatibility we remove the task from recents when finishing
4780                    // task with root activity.
4781                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4782                    if (!res) {
4783                        Slog.i(TAG, "Removing task failed to finish activity");
4784                    }
4785                } else {
4786                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4787                            resultData, "app-request", true);
4788                    if (!res) {
4789                        Slog.i(TAG, "Failed to finish by app-request");
4790                    }
4791                }
4792                return res;
4793            } finally {
4794                Binder.restoreCallingIdentity(origId);
4795            }
4796        }
4797    }
4798
4799    @Override
4800    public final void finishHeavyWeightApp() {
4801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4802                != PackageManager.PERMISSION_GRANTED) {
4803            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4804                    + Binder.getCallingPid()
4805                    + ", uid=" + Binder.getCallingUid()
4806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4807            Slog.w(TAG, msg);
4808            throw new SecurityException(msg);
4809        }
4810
4811        synchronized(this) {
4812            if (mHeavyWeightProcess == null) {
4813                return;
4814            }
4815
4816            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4817            for (int i = 0; i < activities.size(); i++) {
4818                ActivityRecord r = activities.get(i);
4819                if (!r.finishing && r.isInStackLocked()) {
4820                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4821                            null, "finish-heavy", true);
4822                }
4823            }
4824
4825            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                    mHeavyWeightProcess.userId, 0));
4827            mHeavyWeightProcess = null;
4828        }
4829    }
4830
4831    @Override
4832    public void crashApplication(int uid, int initialPid, String packageName,
4833            String message) {
4834        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4835                != PackageManager.PERMISSION_GRANTED) {
4836            String msg = "Permission Denial: crashApplication() from pid="
4837                    + Binder.getCallingPid()
4838                    + ", uid=" + Binder.getCallingUid()
4839                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4840            Slog.w(TAG, msg);
4841            throw new SecurityException(msg);
4842        }
4843
4844        synchronized(this) {
4845            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4846        }
4847    }
4848
4849    @Override
4850    public final void finishSubActivity(IBinder token, String resultWho,
4851            int requestCode) {
4852        synchronized(this) {
4853            final long origId = Binder.clearCallingIdentity();
4854            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4855            if (r != null) {
4856                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4857            }
4858            Binder.restoreCallingIdentity(origId);
4859        }
4860    }
4861
4862    @Override
4863    public boolean finishActivityAffinity(IBinder token) {
4864        synchronized(this) {
4865            final long origId = Binder.clearCallingIdentity();
4866            try {
4867                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4868                if (r == null) {
4869                    return false;
4870                }
4871
4872                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4873                // can finish.
4874                final TaskRecord task = r.task;
4875                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4876                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4877                    mStackSupervisor.showLockTaskToast();
4878                    return false;
4879                }
4880                return task.stack.finishActivityAffinityLocked(r);
4881            } finally {
4882                Binder.restoreCallingIdentity(origId);
4883            }
4884        }
4885    }
4886
4887    @Override
4888    public void finishVoiceTask(IVoiceInteractionSession session) {
4889        synchronized (this) {
4890            final long origId = Binder.clearCallingIdentity();
4891            try {
4892                // TODO: VI Consider treating local voice interactions and voice tasks
4893                // differently here
4894                mStackSupervisor.finishVoiceTask(session);
4895            } finally {
4896                Binder.restoreCallingIdentity(origId);
4897            }
4898        }
4899
4900    }
4901
4902    @Override
4903    public boolean releaseActivityInstance(IBinder token) {
4904        synchronized(this) {
4905            final long origId = Binder.clearCallingIdentity();
4906            try {
4907                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4908                if (r == null) {
4909                    return false;
4910                }
4911                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4912            } finally {
4913                Binder.restoreCallingIdentity(origId);
4914            }
4915        }
4916    }
4917
4918    @Override
4919    public void releaseSomeActivities(IApplicationThread appInt) {
4920        synchronized(this) {
4921            final long origId = Binder.clearCallingIdentity();
4922            try {
4923                ProcessRecord app = getRecordForAppLocked(appInt);
4924                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public boolean willActivityBeVisible(IBinder token) {
4933        synchronized(this) {
4934            ActivityStack stack = ActivityRecord.getStackLocked(token);
4935            if (stack != null) {
4936                return stack.willActivityBeVisibleLocked(token);
4937            }
4938            return false;
4939        }
4940    }
4941
4942    @Override
4943    public void overridePendingTransition(IBinder token, String packageName,
4944            int enterAnim, int exitAnim) {
4945        synchronized(this) {
4946            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4947            if (self == null) {
4948                return;
4949            }
4950
4951            final long origId = Binder.clearCallingIdentity();
4952
4953            if (self.state == ActivityState.RESUMED
4954                    || self.state == ActivityState.PAUSING) {
4955                mWindowManager.overridePendingAppTransition(packageName,
4956                        enterAnim, exitAnim, null);
4957            }
4958
4959            Binder.restoreCallingIdentity(origId);
4960        }
4961    }
4962
4963    /**
4964     * Main function for removing an existing process from the activity manager
4965     * as a result of that process going away.  Clears out all connections
4966     * to the process.
4967     */
4968    private final void handleAppDiedLocked(ProcessRecord app,
4969            boolean restarting, boolean allowRestart) {
4970        int pid = app.pid;
4971        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4972        if (!kept && !restarting) {
4973            removeLruProcessLocked(app);
4974            if (pid > 0) {
4975                ProcessList.remove(pid);
4976            }
4977        }
4978
4979        if (mProfileProc == app) {
4980            clearProfilerLocked();
4981        }
4982
4983        // Remove this application's activities from active lists.
4984        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4985
4986        app.activities.clear();
4987
4988        if (app.instrumentationClass != null) {
4989            Slog.w(TAG, "Crash of app " + app.processName
4990                  + " running instrumentation " + app.instrumentationClass);
4991            Bundle info = new Bundle();
4992            info.putString("shortMsg", "Process crashed.");
4993            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4994        }
4995
4996        if (!restarting && hasVisibleActivities
4997                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4998            // If there was nothing to resume, and we are not already restarting this process, but
4999            // there is a visible activity that is hosted by the process...  then make sure all
5000            // visible activities are running, taking care of restarting this process.
5001            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5002        }
5003    }
5004
5005    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5006        IBinder threadBinder = thread.asBinder();
5007        // Find the application record.
5008        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5009            ProcessRecord rec = mLruProcesses.get(i);
5010            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5011                return i;
5012            }
5013        }
5014        return -1;
5015    }
5016
5017    final ProcessRecord getRecordForAppLocked(
5018            IApplicationThread thread) {
5019        if (thread == null) {
5020            return null;
5021        }
5022
5023        int appIndex = getLRURecordIndexForAppLocked(thread);
5024        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5025    }
5026
5027    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5028        // If there are no longer any background processes running,
5029        // and the app that died was not running instrumentation,
5030        // then tell everyone we are now low on memory.
5031        boolean haveBg = false;
5032        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5033            ProcessRecord rec = mLruProcesses.get(i);
5034            if (rec.thread != null
5035                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5036                haveBg = true;
5037                break;
5038            }
5039        }
5040
5041        if (!haveBg) {
5042            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5043            if (doReport) {
5044                long now = SystemClock.uptimeMillis();
5045                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5046                    doReport = false;
5047                } else {
5048                    mLastMemUsageReportTime = now;
5049                }
5050            }
5051            final ArrayList<ProcessMemInfo> memInfos
5052                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5053            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5054            long now = SystemClock.uptimeMillis();
5055            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5056                ProcessRecord rec = mLruProcesses.get(i);
5057                if (rec == dyingProc || rec.thread == null) {
5058                    continue;
5059                }
5060                if (doReport) {
5061                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5062                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5063                }
5064                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5065                    // The low memory report is overriding any current
5066                    // state for a GC request.  Make sure to do
5067                    // heavy/important/visible/foreground processes first.
5068                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5069                        rec.lastRequestedGc = 0;
5070                    } else {
5071                        rec.lastRequestedGc = rec.lastLowMemory;
5072                    }
5073                    rec.reportLowMemory = true;
5074                    rec.lastLowMemory = now;
5075                    mProcessesToGc.remove(rec);
5076                    addProcessToGcListLocked(rec);
5077                }
5078            }
5079            if (doReport) {
5080                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5081                mHandler.sendMessage(msg);
5082            }
5083            scheduleAppGcsLocked();
5084        }
5085    }
5086
5087    final void appDiedLocked(ProcessRecord app) {
5088       appDiedLocked(app, app.pid, app.thread, false);
5089    }
5090
5091    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5092            boolean fromBinderDied) {
5093        // First check if this ProcessRecord is actually active for the pid.
5094        synchronized (mPidsSelfLocked) {
5095            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5096            if (curProc != app) {
5097                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5098                return;
5099            }
5100        }
5101
5102        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5103        synchronized (stats) {
5104            stats.noteProcessDiedLocked(app.info.uid, pid);
5105        }
5106
5107        if (!app.killed) {
5108            if (!fromBinderDied) {
5109                Process.killProcessQuiet(pid);
5110            }
5111            killProcessGroup(app.uid, pid);
5112            app.killed = true;
5113        }
5114
5115        // Clean up already done if the process has been re-started.
5116        if (app.pid == pid && app.thread != null &&
5117                app.thread.asBinder() == thread.asBinder()) {
5118            boolean doLowMem = app.instrumentationClass == null;
5119            boolean doOomAdj = doLowMem;
5120            if (!app.killedByAm) {
5121                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5122                        + ") has died");
5123                mAllowLowerMemLevel = true;
5124            } else {
5125                // Note that we always want to do oom adj to update our state with the
5126                // new number of procs.
5127                mAllowLowerMemLevel = false;
5128                doLowMem = false;
5129            }
5130            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5131            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5132                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5133            handleAppDiedLocked(app, false, true);
5134
5135            if (doOomAdj) {
5136                updateOomAdjLocked();
5137            }
5138            if (doLowMem) {
5139                doLowMemReportIfNeededLocked(app);
5140            }
5141        } else if (app.pid != pid) {
5142            // A new process has already been started.
5143            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5144                    + ") has died and restarted (pid " + app.pid + ").");
5145            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5146        } else if (DEBUG_PROCESSES) {
5147            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5148                    + thread.asBinder());
5149        }
5150    }
5151
5152    /**
5153     * If a stack trace dump file is configured, dump process stack traces.
5154     * @param clearTraces causes the dump file to be erased prior to the new
5155     *    traces being written, if true; when false, the new traces will be
5156     *    appended to any existing file content.
5157     * @param firstPids of dalvik VM processes to dump stack traces for first
5158     * @param lastPids of dalvik VM processes to dump stack traces for last
5159     * @param nativeProcs optional list of native process names to dump stack crawls
5160     * @return file containing stack traces, or null if no dump file is configured
5161     */
5162    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5163            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5164        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5165        if (tracesPath == null || tracesPath.length() == 0) {
5166            return null;
5167        }
5168
5169        File tracesFile = new File(tracesPath);
5170        try {
5171            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5172            tracesFile.createNewFile();
5173            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5174        } catch (IOException e) {
5175            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5176            return null;
5177        }
5178
5179        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5180        return tracesFile;
5181    }
5182
5183    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5184            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5185        // Use a FileObserver to detect when traces finish writing.
5186        // The order of traces is considered important to maintain for legibility.
5187        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5188            @Override
5189            public synchronized void onEvent(int event, String path) { notify(); }
5190        };
5191
5192        try {
5193            observer.startWatching();
5194
5195            // First collect all of the stacks of the most important pids.
5196            if (firstPids != null) {
5197                try {
5198                    int num = firstPids.size();
5199                    for (int i = 0; i < num; i++) {
5200                        synchronized (observer) {
5201                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5202                                    + firstPids.get(i));
5203                            final long sime = SystemClock.elapsedRealtime();
5204                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5205                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5206                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5207                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5208                        }
5209                    }
5210                } catch (InterruptedException e) {
5211                    Slog.wtf(TAG, e);
5212                }
5213            }
5214
5215            // Next collect the stacks of the native pids
5216            if (nativeProcs != null) {
5217                int[] pids = Process.getPidsForCommands(nativeProcs);
5218                if (pids != null) {
5219                    for (int pid : pids) {
5220                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5221                        final long sime = SystemClock.elapsedRealtime();
5222                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5223                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5224                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5225                    }
5226                }
5227            }
5228
5229            // Lastly, measure CPU usage.
5230            if (processCpuTracker != null) {
5231                processCpuTracker.init();
5232                System.gc();
5233                processCpuTracker.update();
5234                try {
5235                    synchronized (processCpuTracker) {
5236                        processCpuTracker.wait(500); // measure over 1/2 second.
5237                    }
5238                } catch (InterruptedException e) {
5239                }
5240                processCpuTracker.update();
5241
5242                // We'll take the stack crawls of just the top apps using CPU.
5243                final int N = processCpuTracker.countWorkingStats();
5244                int numProcs = 0;
5245                for (int i=0; i<N && numProcs<5; i++) {
5246                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5247                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5248                        numProcs++;
5249                        try {
5250                            synchronized (observer) {
5251                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5252                                        + stats.pid);
5253                                final long stime = SystemClock.elapsedRealtime();
5254                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5255                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5256                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5257                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5258                            }
5259                        } catch (InterruptedException e) {
5260                            Slog.wtf(TAG, e);
5261                        }
5262                    } else if (DEBUG_ANR) {
5263                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5264                                + stats.pid);
5265                    }
5266                }
5267            }
5268        } finally {
5269            observer.stopWatching();
5270        }
5271    }
5272
5273    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5274        if (true || IS_USER_BUILD) {
5275            return;
5276        }
5277        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5278        if (tracesPath == null || tracesPath.length() == 0) {
5279            return;
5280        }
5281
5282        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5283        StrictMode.allowThreadDiskWrites();
5284        try {
5285            final File tracesFile = new File(tracesPath);
5286            final File tracesDir = tracesFile.getParentFile();
5287            final File tracesTmp = new File(tracesDir, "__tmp__");
5288            try {
5289                if (tracesFile.exists()) {
5290                    tracesTmp.delete();
5291                    tracesFile.renameTo(tracesTmp);
5292                }
5293                StringBuilder sb = new StringBuilder();
5294                Time tobj = new Time();
5295                tobj.set(System.currentTimeMillis());
5296                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5297                sb.append(": ");
5298                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5299                sb.append(" since ");
5300                sb.append(msg);
5301                FileOutputStream fos = new FileOutputStream(tracesFile);
5302                fos.write(sb.toString().getBytes());
5303                if (app == null) {
5304                    fos.write("\n*** No application process!".getBytes());
5305                }
5306                fos.close();
5307                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5308            } catch (IOException e) {
5309                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5310                return;
5311            }
5312
5313            if (app != null) {
5314                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5315                firstPids.add(app.pid);
5316                dumpStackTraces(tracesPath, firstPids, null, null, null);
5317            }
5318
5319            File lastTracesFile = null;
5320            File curTracesFile = null;
5321            for (int i=9; i>=0; i--) {
5322                String name = String.format(Locale.US, "slow%02d.txt", i);
5323                curTracesFile = new File(tracesDir, name);
5324                if (curTracesFile.exists()) {
5325                    if (lastTracesFile != null) {
5326                        curTracesFile.renameTo(lastTracesFile);
5327                    } else {
5328                        curTracesFile.delete();
5329                    }
5330                }
5331                lastTracesFile = curTracesFile;
5332            }
5333            tracesFile.renameTo(curTracesFile);
5334            if (tracesTmp.exists()) {
5335                tracesTmp.renameTo(tracesFile);
5336            }
5337        } finally {
5338            StrictMode.setThreadPolicy(oldPolicy);
5339        }
5340    }
5341
5342    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5343        if (!mLaunchWarningShown) {
5344            mLaunchWarningShown = true;
5345            mUiHandler.post(new Runnable() {
5346                @Override
5347                public void run() {
5348                    synchronized (ActivityManagerService.this) {
5349                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5350                        d.show();
5351                        mUiHandler.postDelayed(new Runnable() {
5352                            @Override
5353                            public void run() {
5354                                synchronized (ActivityManagerService.this) {
5355                                    d.dismiss();
5356                                    mLaunchWarningShown = false;
5357                                }
5358                            }
5359                        }, 4000);
5360                    }
5361                }
5362            });
5363        }
5364    }
5365
5366    @Override
5367    public boolean clearApplicationUserData(final String packageName,
5368            final IPackageDataObserver observer, int userId) {
5369        enforceNotIsolatedCaller("clearApplicationUserData");
5370        int uid = Binder.getCallingUid();
5371        int pid = Binder.getCallingPid();
5372        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5373                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5374
5375        final DevicePolicyManagerInternal dpmi = LocalServices
5376                .getService(DevicePolicyManagerInternal.class);
5377        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5378            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5379        }
5380
5381        long callingId = Binder.clearCallingIdentity();
5382        try {
5383            IPackageManager pm = AppGlobals.getPackageManager();
5384            int pkgUid = -1;
5385            synchronized(this) {
5386                try {
5387                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5388                } catch (RemoteException e) {
5389                }
5390                if (pkgUid == -1) {
5391                    Slog.w(TAG, "Invalid packageName: " + packageName);
5392                    if (observer != null) {
5393                        try {
5394                            observer.onRemoveCompleted(packageName, false);
5395                        } catch (RemoteException e) {
5396                            Slog.i(TAG, "Observer no longer exists.");
5397                        }
5398                    }
5399                    return false;
5400                }
5401                if (uid == pkgUid || checkComponentPermission(
5402                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5403                        pid, uid, -1, true)
5404                        == PackageManager.PERMISSION_GRANTED) {
5405                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5406                } else {
5407                    throw new SecurityException("PID " + pid + " does not have permission "
5408                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5409                                    + " of package " + packageName);
5410                }
5411
5412                // Remove all tasks match the cleared application package and user
5413                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5414                    final TaskRecord tr = mRecentTasks.get(i);
5415                    final String taskPackageName =
5416                            tr.getBaseIntent().getComponent().getPackageName();
5417                    if (tr.userId != userId) continue;
5418                    if (!taskPackageName.equals(packageName)) continue;
5419                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5420                }
5421            }
5422
5423            final int pkgUidF = pkgUid;
5424            final int userIdF = userId;
5425            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5426                @Override
5427                public void onRemoveCompleted(String packageName, boolean succeeded)
5428                        throws RemoteException {
5429                    synchronized (ActivityManagerService.this) {
5430                        finishForceStopPackageLocked(packageName, pkgUidF);
5431                    }
5432
5433                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5434                            Uri.fromParts("package", packageName, null));
5435                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5436                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5437                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438                            null, null, 0, null, null, null, null, false, false, userIdF);
5439
5440                    if (observer != null) {
5441                        observer.onRemoveCompleted(packageName, succeeded);
5442                    }
5443                }
5444            };
5445
5446            try {
5447                // Clear application user data
5448                pm.clearApplicationUserData(packageName, localObserver, userId);
5449
5450                synchronized(this) {
5451                    // Remove all permissions granted from/to this package
5452                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5453                }
5454
5455                // Remove all zen rules created by this package; revoke it's zen access.
5456                INotificationManager inm = NotificationManager.getService();
5457                inm.removeAutomaticZenRules(packageName);
5458                inm.setNotificationPolicyAccessGranted(packageName, false);
5459
5460            } catch (RemoteException e) {
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(callingId);
5464        }
5465        return true;
5466    }
5467
5468    @Override
5469    public void killBackgroundProcesses(final String packageName, int userId) {
5470        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5471                != PackageManager.PERMISSION_GRANTED &&
5472                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5473                        != PackageManager.PERMISSION_GRANTED) {
5474            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5475                    + Binder.getCallingPid()
5476                    + ", uid=" + Binder.getCallingUid()
5477                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5478            Slog.w(TAG, msg);
5479            throw new SecurityException(msg);
5480        }
5481
5482        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5483                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5484        long callingId = Binder.clearCallingIdentity();
5485        try {
5486            IPackageManager pm = AppGlobals.getPackageManager();
5487            synchronized(this) {
5488                int appId = -1;
5489                try {
5490                    appId = UserHandle.getAppId(
5491                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5492                } catch (RemoteException e) {
5493                }
5494                if (appId == -1) {
5495                    Slog.w(TAG, "Invalid packageName: " + packageName);
5496                    return;
5497                }
5498                killPackageProcessesLocked(packageName, appId, userId,
5499                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5500            }
5501        } finally {
5502            Binder.restoreCallingIdentity(callingId);
5503        }
5504    }
5505
5506    @Override
5507    public void killAllBackgroundProcesses() {
5508        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5509                != PackageManager.PERMISSION_GRANTED) {
5510            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5511                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5512                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5513            Slog.w(TAG, msg);
5514            throw new SecurityException(msg);
5515        }
5516
5517        final long callingId = Binder.clearCallingIdentity();
5518        try {
5519            synchronized (this) {
5520                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5521                final int NP = mProcessNames.getMap().size();
5522                for (int ip = 0; ip < NP; ip++) {
5523                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524                    final int NA = apps.size();
5525                    for (int ia = 0; ia < NA; ia++) {
5526                        final ProcessRecord app = apps.valueAt(ia);
5527                        if (app.persistent) {
5528                            // We don't kill persistent processes.
5529                            continue;
5530                        }
5531                        if (app.removed) {
5532                            procs.add(app);
5533                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5534                            app.removed = true;
5535                            procs.add(app);
5536                        }
5537                    }
5538                }
5539
5540                final int N = procs.size();
5541                for (int i = 0; i < N; i++) {
5542                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5543                }
5544
5545                mAllowLowerMemLevel = true;
5546
5547                updateOomAdjLocked();
5548                doLowMemReportIfNeededLocked(null);
5549            }
5550        } finally {
5551            Binder.restoreCallingIdentity(callingId);
5552        }
5553    }
5554
5555    /**
5556     * Kills all background processes, except those matching any of the
5557     * specified properties.
5558     *
5559     * @param minTargetSdk the target SDK version at or above which to preserve
5560     *                     processes, or {@code -1} to ignore the target SDK
5561     * @param maxProcState the process state at or below which to preserve
5562     *                     processes, or {@code -1} to ignore the process state
5563     */
5564    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5565        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5566                != PackageManager.PERMISSION_GRANTED) {
5567            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5568                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5569                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5570            Slog.w(TAG, msg);
5571            throw new SecurityException(msg);
5572        }
5573
5574        final long callingId = Binder.clearCallingIdentity();
5575        try {
5576            synchronized (this) {
5577                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5578                final int NP = mProcessNames.getMap().size();
5579                for (int ip = 0; ip < NP; ip++) {
5580                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5581                    final int NA = apps.size();
5582                    for (int ia = 0; ia < NA; ia++) {
5583                        final ProcessRecord app = apps.valueAt(ia);
5584                        if (app.removed) {
5585                            procs.add(app);
5586                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5587                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5588                            app.removed = true;
5589                            procs.add(app);
5590                        }
5591                    }
5592                }
5593
5594                final int N = procs.size();
5595                for (int i = 0; i < N; i++) {
5596                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5597                }
5598            }
5599        } finally {
5600            Binder.restoreCallingIdentity(callingId);
5601        }
5602    }
5603
5604    @Override
5605    public void forceStopPackage(final String packageName, int userId) {
5606        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5607                != PackageManager.PERMISSION_GRANTED) {
5608            String msg = "Permission Denial: forceStopPackage() from pid="
5609                    + Binder.getCallingPid()
5610                    + ", uid=" + Binder.getCallingUid()
5611                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5612            Slog.w(TAG, msg);
5613            throw new SecurityException(msg);
5614        }
5615        final int callingPid = Binder.getCallingPid();
5616        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5617                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5618        long callingId = Binder.clearCallingIdentity();
5619        try {
5620            IPackageManager pm = AppGlobals.getPackageManager();
5621            synchronized(this) {
5622                int[] users = userId == UserHandle.USER_ALL
5623                        ? mUserController.getUsers() : new int[] { userId };
5624                for (int user : users) {
5625                    int pkgUid = -1;
5626                    try {
5627                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5628                                user);
5629                    } catch (RemoteException e) {
5630                    }
5631                    if (pkgUid == -1) {
5632                        Slog.w(TAG, "Invalid packageName: " + packageName);
5633                        continue;
5634                    }
5635                    try {
5636                        pm.setPackageStoppedState(packageName, true, user);
5637                    } catch (RemoteException e) {
5638                    } catch (IllegalArgumentException e) {
5639                        Slog.w(TAG, "Failed trying to unstop package "
5640                                + packageName + ": " + e);
5641                    }
5642                    if (mUserController.isUserRunningLocked(user, 0)) {
5643                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5644                        finishForceStopPackageLocked(packageName, pkgUid);
5645                    }
5646                }
5647            }
5648        } finally {
5649            Binder.restoreCallingIdentity(callingId);
5650        }
5651    }
5652
5653    @Override
5654    public void addPackageDependency(String packageName) {
5655        synchronized (this) {
5656            int callingPid = Binder.getCallingPid();
5657            if (callingPid == Process.myPid()) {
5658                //  Yeah, um, no.
5659                return;
5660            }
5661            ProcessRecord proc;
5662            synchronized (mPidsSelfLocked) {
5663                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5664            }
5665            if (proc != null) {
5666                if (proc.pkgDeps == null) {
5667                    proc.pkgDeps = new ArraySet<String>(1);
5668                }
5669                proc.pkgDeps.add(packageName);
5670            }
5671        }
5672    }
5673
5674    /*
5675     * The pkg name and app id have to be specified.
5676     */
5677    @Override
5678    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5679        if (pkg == null) {
5680            return;
5681        }
5682        // Make sure the uid is valid.
5683        if (appid < 0) {
5684            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5685            return;
5686        }
5687        int callerUid = Binder.getCallingUid();
5688        // Only the system server can kill an application
5689        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5690            // Post an aysnc message to kill the application
5691            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5692            msg.arg1 = appid;
5693            msg.arg2 = 0;
5694            Bundle bundle = new Bundle();
5695            bundle.putString("pkg", pkg);
5696            bundle.putString("reason", reason);
5697            msg.obj = bundle;
5698            mHandler.sendMessage(msg);
5699        } else {
5700            throw new SecurityException(callerUid + " cannot kill pkg: " +
5701                    pkg);
5702        }
5703    }
5704
5705    @Override
5706    public void closeSystemDialogs(String reason) {
5707        enforceNotIsolatedCaller("closeSystemDialogs");
5708
5709        final int pid = Binder.getCallingPid();
5710        final int uid = Binder.getCallingUid();
5711        final long origId = Binder.clearCallingIdentity();
5712        try {
5713            synchronized (this) {
5714                // Only allow this from foreground processes, so that background
5715                // applications can't abuse it to prevent system UI from being shown.
5716                if (uid >= Process.FIRST_APPLICATION_UID) {
5717                    ProcessRecord proc;
5718                    synchronized (mPidsSelfLocked) {
5719                        proc = mPidsSelfLocked.get(pid);
5720                    }
5721                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5722                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5723                                + " from background process " + proc);
5724                        return;
5725                    }
5726                }
5727                closeSystemDialogsLocked(reason);
5728            }
5729        } finally {
5730            Binder.restoreCallingIdentity(origId);
5731        }
5732    }
5733
5734    void closeSystemDialogsLocked(String reason) {
5735        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5736        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5737                | Intent.FLAG_RECEIVER_FOREGROUND);
5738        if (reason != null) {
5739            intent.putExtra("reason", reason);
5740        }
5741        mWindowManager.closeSystemDialogs(reason);
5742
5743        mStackSupervisor.closeSystemDialogsLocked();
5744
5745        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5746                AppOpsManager.OP_NONE, null, false, false,
5747                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5748    }
5749
5750    @Override
5751    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5752        enforceNotIsolatedCaller("getProcessMemoryInfo");
5753        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5754        for (int i=pids.length-1; i>=0; i--) {
5755            ProcessRecord proc;
5756            int oomAdj;
5757            synchronized (this) {
5758                synchronized (mPidsSelfLocked) {
5759                    proc = mPidsSelfLocked.get(pids[i]);
5760                    oomAdj = proc != null ? proc.setAdj : 0;
5761                }
5762            }
5763            infos[i] = new Debug.MemoryInfo();
5764            Debug.getMemoryInfo(pids[i], infos[i]);
5765            if (proc != null) {
5766                synchronized (this) {
5767                    if (proc.thread != null && proc.setAdj == oomAdj) {
5768                        // Record this for posterity if the process has been stable.
5769                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5770                                infos[i].getTotalUss(), false, proc.pkgList);
5771                    }
5772                }
5773            }
5774        }
5775        return infos;
5776    }
5777
5778    @Override
5779    public long[] getProcessPss(int[] pids) {
5780        enforceNotIsolatedCaller("getProcessPss");
5781        long[] pss = new long[pids.length];
5782        for (int i=pids.length-1; i>=0; i--) {
5783            ProcessRecord proc;
5784            int oomAdj;
5785            synchronized (this) {
5786                synchronized (mPidsSelfLocked) {
5787                    proc = mPidsSelfLocked.get(pids[i]);
5788                    oomAdj = proc != null ? proc.setAdj : 0;
5789                }
5790            }
5791            long[] tmpUss = new long[1];
5792            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5793            if (proc != null) {
5794                synchronized (this) {
5795                    if (proc.thread != null && proc.setAdj == oomAdj) {
5796                        // Record this for posterity if the process has been stable.
5797                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5798                    }
5799                }
5800            }
5801        }
5802        return pss;
5803    }
5804
5805    @Override
5806    public void killApplicationProcess(String processName, int uid) {
5807        if (processName == null) {
5808            return;
5809        }
5810
5811        int callerUid = Binder.getCallingUid();
5812        // Only the system server can kill an application
5813        if (callerUid == Process.SYSTEM_UID) {
5814            synchronized (this) {
5815                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5816                if (app != null && app.thread != null) {
5817                    try {
5818                        app.thread.scheduleSuicide();
5819                    } catch (RemoteException e) {
5820                        // If the other end already died, then our work here is done.
5821                    }
5822                } else {
5823                    Slog.w(TAG, "Process/uid not found attempting kill of "
5824                            + processName + " / " + uid);
5825                }
5826            }
5827        } else {
5828            throw new SecurityException(callerUid + " cannot kill app process: " +
5829                    processName);
5830        }
5831    }
5832
5833    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5834        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5835                false, true, false, false, UserHandle.getUserId(uid), reason);
5836    }
5837
5838    private void finishForceStopPackageLocked(final String packageName, int uid) {
5839        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5840                Uri.fromParts("package", packageName, null));
5841        if (!mProcessesReady) {
5842            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5843                    | Intent.FLAG_RECEIVER_FOREGROUND);
5844        }
5845        intent.putExtra(Intent.EXTRA_UID, uid);
5846        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5847        broadcastIntentLocked(null, null, intent,
5848                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5849                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5850    }
5851
5852
5853    private final boolean killPackageProcessesLocked(String packageName, int appId,
5854            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5855            boolean doit, boolean evenPersistent, String reason) {
5856        ArrayList<ProcessRecord> procs = new ArrayList<>();
5857
5858        // Remove all processes this package may have touched: all with the
5859        // same UID (except for the system or root user), and all whose name
5860        // matches the package name.
5861        final int NP = mProcessNames.getMap().size();
5862        for (int ip=0; ip<NP; ip++) {
5863            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5864            final int NA = apps.size();
5865            for (int ia=0; ia<NA; ia++) {
5866                ProcessRecord app = apps.valueAt(ia);
5867                if (app.persistent && !evenPersistent) {
5868                    // we don't kill persistent processes
5869                    continue;
5870                }
5871                if (app.removed) {
5872                    if (doit) {
5873                        procs.add(app);
5874                    }
5875                    continue;
5876                }
5877
5878                // Skip process if it doesn't meet our oom adj requirement.
5879                if (app.setAdj < minOomAdj) {
5880                    continue;
5881                }
5882
5883                // If no package is specified, we call all processes under the
5884                // give user id.
5885                if (packageName == null) {
5886                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5887                        continue;
5888                    }
5889                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5890                        continue;
5891                    }
5892                // Package has been specified, we want to hit all processes
5893                // that match it.  We need to qualify this by the processes
5894                // that are running under the specified app and user ID.
5895                } else {
5896                    final boolean isDep = app.pkgDeps != null
5897                            && app.pkgDeps.contains(packageName);
5898                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5899                        continue;
5900                    }
5901                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5902                        continue;
5903                    }
5904                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5905                        continue;
5906                    }
5907                }
5908
5909                // Process has passed all conditions, kill it!
5910                if (!doit) {
5911                    return true;
5912                }
5913                app.removed = true;
5914                procs.add(app);
5915            }
5916        }
5917
5918        int N = procs.size();
5919        for (int i=0; i<N; i++) {
5920            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5921        }
5922        updateOomAdjLocked();
5923        return N > 0;
5924    }
5925
5926    private void cleanupDisabledPackageComponentsLocked(
5927            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5928
5929        Set<String> disabledClasses = null;
5930        boolean packageDisabled = false;
5931        IPackageManager pm = AppGlobals.getPackageManager();
5932
5933        if (changedClasses == null) {
5934            // Nothing changed...
5935            return;
5936        }
5937
5938        // Determine enable/disable state of the package and its components.
5939        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5940        for (int i = changedClasses.length - 1; i >= 0; i--) {
5941            final String changedClass = changedClasses[i];
5942
5943            if (changedClass.equals(packageName)) {
5944                try {
5945                    // Entire package setting changed
5946                    enabled = pm.getApplicationEnabledSetting(packageName,
5947                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5948                } catch (Exception e) {
5949                    // No such package/component; probably racing with uninstall.  In any
5950                    // event it means we have nothing further to do here.
5951                    return;
5952                }
5953                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5954                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5955                if (packageDisabled) {
5956                    // Entire package is disabled.
5957                    // No need to continue to check component states.
5958                    disabledClasses = null;
5959                    break;
5960                }
5961            } else {
5962                try {
5963                    enabled = pm.getComponentEnabledSetting(
5964                            new ComponentName(packageName, changedClass),
5965                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5966                } catch (Exception e) {
5967                    // As above, probably racing with uninstall.
5968                    return;
5969                }
5970                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5971                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5972                    if (disabledClasses == null) {
5973                        disabledClasses = new ArraySet<>(changedClasses.length);
5974                    }
5975                    disabledClasses.add(changedClass);
5976                }
5977            }
5978        }
5979
5980        if (!packageDisabled && disabledClasses == null) {
5981            // Nothing to do here...
5982            return;
5983        }
5984
5985        // Clean-up disabled activities.
5986        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5987                packageName, disabledClasses, true, false, userId) && mBooted) {
5988            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5989            mStackSupervisor.scheduleIdleLocked();
5990        }
5991
5992        // Clean-up disabled tasks
5993        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5994
5995        // Clean-up disabled services.
5996        mServices.bringDownDisabledPackageServicesLocked(
5997                packageName, disabledClasses, userId, false, killProcess, true);
5998
5999        // Clean-up disabled providers.
6000        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6001        mProviderMap.collectPackageProvidersLocked(
6002                packageName, disabledClasses, true, false, userId, providers);
6003        for (int i = providers.size() - 1; i >= 0; i--) {
6004            removeDyingProviderLocked(null, providers.get(i), true);
6005        }
6006
6007        // Clean-up disabled broadcast receivers.
6008        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6009            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6010                    packageName, disabledClasses, userId, true);
6011        }
6012
6013    }
6014
6015    final boolean clearBroadcastQueueForUserLocked(int userId) {
6016        boolean didSomething = false;
6017        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019                    null, null, userId, true);
6020        }
6021        return didSomething;
6022    }
6023
6024    final boolean forceStopPackageLocked(String packageName, int appId,
6025            boolean callerWillRestart, boolean purgeCache, boolean doit,
6026            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6027        int i;
6028
6029        if (userId == UserHandle.USER_ALL && packageName == null) {
6030            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6031        }
6032
6033        if (appId < 0 && packageName != null) {
6034            try {
6035                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6036                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6037            } catch (RemoteException e) {
6038            }
6039        }
6040
6041        if (doit) {
6042            if (packageName != null) {
6043                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6044                        + " user=" + userId + ": " + reason);
6045            } else {
6046                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6047            }
6048
6049            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6050        }
6051
6052        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6053                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6054                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6055
6056        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6057                packageName, null, doit, evenPersistent, userId)) {
6058            if (!doit) {
6059                return true;
6060            }
6061            didSomething = true;
6062        }
6063
6064        if (mServices.bringDownDisabledPackageServicesLocked(
6065                packageName, null, userId, evenPersistent, true, doit)) {
6066            if (!doit) {
6067                return true;
6068            }
6069            didSomething = true;
6070        }
6071
6072        if (packageName == null) {
6073            // Remove all sticky broadcasts from this user.
6074            mStickyBroadcasts.remove(userId);
6075        }
6076
6077        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6078        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6079                userId, providers)) {
6080            if (!doit) {
6081                return true;
6082            }
6083            didSomething = true;
6084        }
6085        for (i = providers.size() - 1; i >= 0; i--) {
6086            removeDyingProviderLocked(null, providers.get(i), true);
6087        }
6088
6089        // Remove transient permissions granted from/to this package/user
6090        removeUriPermissionsForPackageLocked(packageName, userId, false);
6091
6092        if (doit) {
6093            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6094                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6095                        packageName, null, userId, doit);
6096            }
6097        }
6098
6099        if (packageName == null || uninstalling) {
6100            // Remove pending intents.  For now we only do this when force
6101            // stopping users, because we have some problems when doing this
6102            // for packages -- app widgets are not currently cleaned up for
6103            // such packages, so they can be left with bad pending intents.
6104            if (mIntentSenderRecords.size() > 0) {
6105                Iterator<WeakReference<PendingIntentRecord>> it
6106                        = mIntentSenderRecords.values().iterator();
6107                while (it.hasNext()) {
6108                    WeakReference<PendingIntentRecord> wpir = it.next();
6109                    if (wpir == null) {
6110                        it.remove();
6111                        continue;
6112                    }
6113                    PendingIntentRecord pir = wpir.get();
6114                    if (pir == null) {
6115                        it.remove();
6116                        continue;
6117                    }
6118                    if (packageName == null) {
6119                        // Stopping user, remove all objects for the user.
6120                        if (pir.key.userId != userId) {
6121                            // Not the same user, skip it.
6122                            continue;
6123                        }
6124                    } else {
6125                        if (UserHandle.getAppId(pir.uid) != appId) {
6126                            // Different app id, skip it.
6127                            continue;
6128                        }
6129                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6130                            // Different user, skip it.
6131                            continue;
6132                        }
6133                        if (!pir.key.packageName.equals(packageName)) {
6134                            // Different package, skip it.
6135                            continue;
6136                        }
6137                    }
6138                    if (!doit) {
6139                        return true;
6140                    }
6141                    didSomething = true;
6142                    it.remove();
6143                    pir.canceled = true;
6144                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6145                        pir.key.activity.pendingResults.remove(pir.ref);
6146                    }
6147                }
6148            }
6149        }
6150
6151        if (doit) {
6152            if (purgeCache && packageName != null) {
6153                AttributeCache ac = AttributeCache.instance();
6154                if (ac != null) {
6155                    ac.removePackage(packageName);
6156                }
6157            }
6158            if (mBooted) {
6159                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6160                mStackSupervisor.scheduleIdleLocked();
6161            }
6162        }
6163
6164        return didSomething;
6165    }
6166
6167    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6168        ProcessRecord old = mProcessNames.remove(name, uid);
6169        if (old != null) {
6170            old.uidRecord.numProcs--;
6171            if (old.uidRecord.numProcs == 0) {
6172                // No more processes using this uid, tell clients it is gone.
6173                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6174                        "No more processes in " + old.uidRecord);
6175                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6176                mActiveUids.remove(uid);
6177                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6178            }
6179            old.uidRecord = null;
6180        }
6181        mIsolatedProcesses.remove(uid);
6182        return old;
6183    }
6184
6185    private final void addProcessNameLocked(ProcessRecord proc) {
6186        // We shouldn't already have a process under this name, but just in case we
6187        // need to clean up whatever may be there now.
6188        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6189        if (old == proc && proc.persistent) {
6190            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6191            Slog.w(TAG, "Re-adding persistent process " + proc);
6192        } else if (old != null) {
6193            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6194        }
6195        UidRecord uidRec = mActiveUids.get(proc.uid);
6196        if (uidRec == null) {
6197            uidRec = new UidRecord(proc.uid);
6198            // This is the first appearance of the uid, report it now!
6199            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6200                    "Creating new process uid: " + uidRec);
6201            mActiveUids.put(proc.uid, uidRec);
6202            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6203            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6204        }
6205        proc.uidRecord = uidRec;
6206        uidRec.numProcs++;
6207        mProcessNames.put(proc.processName, proc.uid, proc);
6208        if (proc.isolated) {
6209            mIsolatedProcesses.put(proc.uid, proc);
6210        }
6211    }
6212
6213    boolean removeProcessLocked(ProcessRecord app,
6214            boolean callerWillRestart, boolean allowRestart, String reason) {
6215        final String name = app.processName;
6216        final int uid = app.uid;
6217        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6218            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6219
6220        ProcessRecord old = mProcessNames.get(name, uid);
6221        if (old != app) {
6222            // This process is no longer active, so nothing to do.
6223            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6224            return false;
6225        }
6226        removeProcessNameLocked(name, uid);
6227        if (mHeavyWeightProcess == app) {
6228            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6229                    mHeavyWeightProcess.userId, 0));
6230            mHeavyWeightProcess = null;
6231        }
6232        boolean needRestart = false;
6233        if (app.pid > 0 && app.pid != MY_PID) {
6234            int pid = app.pid;
6235            synchronized (mPidsSelfLocked) {
6236                mPidsSelfLocked.remove(pid);
6237                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6238            }
6239            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6240            if (app.isolated) {
6241                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6242            }
6243            boolean willRestart = false;
6244            if (app.persistent && !app.isolated) {
6245                if (!callerWillRestart) {
6246                    willRestart = true;
6247                } else {
6248                    needRestart = true;
6249                }
6250            }
6251            app.kill(reason, true);
6252            handleAppDiedLocked(app, willRestart, allowRestart);
6253            if (willRestart) {
6254                removeLruProcessLocked(app);
6255                addAppLocked(app.info, false, null /* ABI override */);
6256            }
6257        } else {
6258            mRemovedProcesses.add(app);
6259        }
6260
6261        return needRestart;
6262    }
6263
6264    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6265        cleanupAppInLaunchingProvidersLocked(app, true);
6266        removeProcessLocked(app, false, true, "timeout publishing content providers");
6267    }
6268
6269    private final void processStartTimedOutLocked(ProcessRecord app) {
6270        final int pid = app.pid;
6271        boolean gone = false;
6272        synchronized (mPidsSelfLocked) {
6273            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6274            if (knownApp != null && knownApp.thread == null) {
6275                mPidsSelfLocked.remove(pid);
6276                gone = true;
6277            }
6278        }
6279
6280        if (gone) {
6281            Slog.w(TAG, "Process " + app + " failed to attach");
6282            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6283                    pid, app.uid, app.processName);
6284            removeProcessNameLocked(app.processName, app.uid);
6285            if (mHeavyWeightProcess == app) {
6286                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6287                        mHeavyWeightProcess.userId, 0));
6288                mHeavyWeightProcess = null;
6289            }
6290            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6291            if (app.isolated) {
6292                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6293            }
6294            // Take care of any launching providers waiting for this process.
6295            cleanupAppInLaunchingProvidersLocked(app, true);
6296            // Take care of any services that are waiting for the process.
6297            mServices.processStartTimedOutLocked(app);
6298            app.kill("start timeout", true);
6299            removeLruProcessLocked(app);
6300            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6301                Slog.w(TAG, "Unattached app died before backup, skipping");
6302                try {
6303                    IBackupManager bm = IBackupManager.Stub.asInterface(
6304                            ServiceManager.getService(Context.BACKUP_SERVICE));
6305                    bm.agentDisconnected(app.info.packageName);
6306                } catch (RemoteException e) {
6307                    // Can't happen; the backup manager is local
6308                }
6309            }
6310            if (isPendingBroadcastProcessLocked(pid)) {
6311                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6312                skipPendingBroadcastLocked(pid);
6313            }
6314        } else {
6315            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6316        }
6317    }
6318
6319    private final boolean attachApplicationLocked(IApplicationThread thread,
6320            int pid) {
6321
6322        // Find the application record that is being attached...  either via
6323        // the pid if we are running in multiple processes, or just pull the
6324        // next app record if we are emulating process with anonymous threads.
6325        ProcessRecord app;
6326        if (pid != MY_PID && pid >= 0) {
6327            synchronized (mPidsSelfLocked) {
6328                app = mPidsSelfLocked.get(pid);
6329            }
6330        } else {
6331            app = null;
6332        }
6333
6334        if (app == null) {
6335            Slog.w(TAG, "No pending application record for pid " + pid
6336                    + " (IApplicationThread " + thread + "); dropping process");
6337            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6338            if (pid > 0 && pid != MY_PID) {
6339                Process.killProcessQuiet(pid);
6340                //TODO: killProcessGroup(app.info.uid, pid);
6341            } else {
6342                try {
6343                    thread.scheduleExit();
6344                } catch (Exception e) {
6345                    // Ignore exceptions.
6346                }
6347            }
6348            return false;
6349        }
6350
6351        // If this application record is still attached to a previous
6352        // process, clean it up now.
6353        if (app.thread != null) {
6354            handleAppDiedLocked(app, true, true);
6355        }
6356
6357        // Tell the process all about itself.
6358
6359        if (DEBUG_ALL) Slog.v(
6360                TAG, "Binding process pid " + pid + " to record " + app);
6361
6362        final String processName = app.processName;
6363        try {
6364            AppDeathRecipient adr = new AppDeathRecipient(
6365                    app, pid, thread);
6366            thread.asBinder().linkToDeath(adr, 0);
6367            app.deathRecipient = adr;
6368        } catch (RemoteException e) {
6369            app.resetPackageList(mProcessStats);
6370            startProcessLocked(app, "link fail", processName);
6371            return false;
6372        }
6373
6374        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6375
6376        app.makeActive(thread, mProcessStats);
6377        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6378        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6379        app.forcingToForeground = null;
6380        updateProcessForegroundLocked(app, false, false);
6381        app.hasShownUi = false;
6382        app.debugging = false;
6383        app.cached = false;
6384        app.killedByAm = false;
6385
6386        // We carefully use the same state that PackageManager uses for
6387        // filtering, since we use this flag to decide if we need to install
6388        // providers when user is unlocked later
6389        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6390
6391        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6392
6393        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6394        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6395
6396        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6397            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6398            msg.obj = app;
6399            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6400        }
6401
6402        if (!normalMode) {
6403            Slog.i(TAG, "Launching preboot mode app: " + app);
6404        }
6405
6406        if (DEBUG_ALL) Slog.v(
6407            TAG, "New app record " + app
6408            + " thread=" + thread.asBinder() + " pid=" + pid);
6409        try {
6410            int testMode = IApplicationThread.DEBUG_OFF;
6411            if (mDebugApp != null && mDebugApp.equals(processName)) {
6412                testMode = mWaitForDebugger
6413                    ? IApplicationThread.DEBUG_WAIT
6414                    : IApplicationThread.DEBUG_ON;
6415                app.debugging = true;
6416                if (mDebugTransient) {
6417                    mDebugApp = mOrigDebugApp;
6418                    mWaitForDebugger = mOrigWaitForDebugger;
6419                }
6420            }
6421            String profileFile = app.instrumentationProfileFile;
6422            ParcelFileDescriptor profileFd = null;
6423            int samplingInterval = 0;
6424            boolean profileAutoStop = false;
6425            if (mProfileApp != null && mProfileApp.equals(processName)) {
6426                mProfileProc = app;
6427                profileFile = mProfileFile;
6428                profileFd = mProfileFd;
6429                samplingInterval = mSamplingInterval;
6430                profileAutoStop = mAutoStopProfiler;
6431            }
6432            boolean enableTrackAllocation = false;
6433            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6434                enableTrackAllocation = true;
6435                mTrackAllocationApp = null;
6436            }
6437
6438            // If the app is being launched for restore or full backup, set it up specially
6439            boolean isRestrictedBackupMode = false;
6440            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6441                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6442                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6443                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6444                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6445            }
6446
6447            if (app.instrumentationClass != null) {
6448                notifyPackageUse(app.instrumentationClass.getPackageName(),
6449                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6450            }
6451            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6452                    + processName + " with config " + mConfiguration);
6453            ApplicationInfo appInfo = app.instrumentationInfo != null
6454                    ? app.instrumentationInfo : app.info;
6455            app.compat = compatibilityInfoForPackageLocked(appInfo);
6456            if (profileFd != null) {
6457                profileFd = profileFd.dup();
6458            }
6459            ProfilerInfo profilerInfo = profileFile == null ? null
6460                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6461            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6462                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6463                    app.instrumentationUiAutomationConnection, testMode,
6464                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6465                    isRestrictedBackupMode || !normalMode, app.persistent,
6466                    new Configuration(mConfiguration), app.compat,
6467                    getCommonServicesLocked(app.isolated),
6468                    mCoreSettingsObserver.getCoreSettingsLocked());
6469            updateLruProcessLocked(app, false, null);
6470            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6471        } catch (Exception e) {
6472            // todo: Yikes!  What should we do?  For now we will try to
6473            // start another process, but that could easily get us in
6474            // an infinite loop of restarting processes...
6475            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6476
6477            app.resetPackageList(mProcessStats);
6478            app.unlinkDeathRecipient();
6479            startProcessLocked(app, "bind fail", processName);
6480            return false;
6481        }
6482
6483        // Remove this record from the list of starting applications.
6484        mPersistentStartingProcesses.remove(app);
6485        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6486                "Attach application locked removing on hold: " + app);
6487        mProcessesOnHold.remove(app);
6488
6489        boolean badApp = false;
6490        boolean didSomething = false;
6491
6492        // See if the top visible activity is waiting to run in this process...
6493        if (normalMode) {
6494            try {
6495                if (mStackSupervisor.attachApplicationLocked(app)) {
6496                    didSomething = true;
6497                }
6498            } catch (Exception e) {
6499                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6500                badApp = true;
6501            }
6502        }
6503
6504        // Find any services that should be running in this process...
6505        if (!badApp) {
6506            try {
6507                didSomething |= mServices.attachApplicationLocked(app, processName);
6508            } catch (Exception e) {
6509                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6510                badApp = true;
6511            }
6512        }
6513
6514        // Check if a next-broadcast receiver is in this process...
6515        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6516            try {
6517                didSomething |= sendPendingBroadcastsLocked(app);
6518            } catch (Exception e) {
6519                // If the app died trying to launch the receiver we declare it 'bad'
6520                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6521                badApp = true;
6522            }
6523        }
6524
6525        // Check whether the next backup agent is in this process...
6526        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6527            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6528                    "New app is backup target, launching agent for " + app);
6529            notifyPackageUse(mBackupTarget.appInfo.packageName,
6530                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6531            try {
6532                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6533                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6534                        mBackupTarget.backupMode);
6535            } catch (Exception e) {
6536                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6537                badApp = true;
6538            }
6539        }
6540
6541        if (badApp) {
6542            app.kill("error during init", true);
6543            handleAppDiedLocked(app, false, true);
6544            return false;
6545        }
6546
6547        if (!didSomething) {
6548            updateOomAdjLocked();
6549        }
6550
6551        return true;
6552    }
6553
6554    @Override
6555    public final void attachApplication(IApplicationThread thread) {
6556        synchronized (this) {
6557            int callingPid = Binder.getCallingPid();
6558            final long origId = Binder.clearCallingIdentity();
6559            attachApplicationLocked(thread, callingPid);
6560            Binder.restoreCallingIdentity(origId);
6561        }
6562    }
6563
6564    @Override
6565    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6566        final long origId = Binder.clearCallingIdentity();
6567        synchronized (this) {
6568            ActivityStack stack = ActivityRecord.getStackLocked(token);
6569            if (stack != null) {
6570                ActivityRecord r =
6571                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6572                if (stopProfiling) {
6573                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6574                        try {
6575                            mProfileFd.close();
6576                        } catch (IOException e) {
6577                        }
6578                        clearProfilerLocked();
6579                    }
6580                }
6581            }
6582        }
6583        Binder.restoreCallingIdentity(origId);
6584    }
6585
6586    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6587        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6588                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6589    }
6590
6591    void enableScreenAfterBoot() {
6592        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6593                SystemClock.uptimeMillis());
6594        mWindowManager.enableScreenAfterBoot();
6595
6596        synchronized (this) {
6597            updateEventDispatchingLocked();
6598        }
6599    }
6600
6601    @Override
6602    public void showBootMessage(final CharSequence msg, final boolean always) {
6603        if (Binder.getCallingUid() != Process.myUid()) {
6604            // These days only the core system can call this, so apps can't get in
6605            // the way of what we show about running them.
6606        }
6607        mWindowManager.showBootMessage(msg, always);
6608    }
6609
6610    @Override
6611    public void keyguardWaitingForActivityDrawn() {
6612        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6613        final long token = Binder.clearCallingIdentity();
6614        try {
6615            synchronized (this) {
6616                if (DEBUG_LOCKSCREEN) logLockScreen("");
6617                mWindowManager.keyguardWaitingForActivityDrawn();
6618                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6619                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6620                    updateSleepIfNeededLocked();
6621                }
6622            }
6623        } finally {
6624            Binder.restoreCallingIdentity(token);
6625        }
6626    }
6627
6628    @Override
6629    public void keyguardGoingAway(int flags) {
6630        enforceNotIsolatedCaller("keyguardGoingAway");
6631        final long token = Binder.clearCallingIdentity();
6632        try {
6633            synchronized (this) {
6634                if (DEBUG_LOCKSCREEN) logLockScreen("");
6635                mWindowManager.keyguardGoingAway(flags);
6636                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6637                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6638                    updateSleepIfNeededLocked();
6639
6640                    // Some stack visibility might change (e.g. docked stack)
6641                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6642                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6643                }
6644            }
6645        } finally {
6646            Binder.restoreCallingIdentity(token);
6647        }
6648    }
6649
6650    final void finishBooting() {
6651        synchronized (this) {
6652            if (!mBootAnimationComplete) {
6653                mCallFinishBooting = true;
6654                return;
6655            }
6656            mCallFinishBooting = false;
6657        }
6658
6659        ArraySet<String> completedIsas = new ArraySet<String>();
6660        for (String abi : Build.SUPPORTED_ABIS) {
6661            Process.establishZygoteConnectionForAbi(abi);
6662            final String instructionSet = VMRuntime.getInstructionSet(abi);
6663            if (!completedIsas.contains(instructionSet)) {
6664                try {
6665                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6666                } catch (InstallerException e) {
6667                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6668                            e.getMessage() +")");
6669                }
6670                completedIsas.add(instructionSet);
6671            }
6672        }
6673
6674        IntentFilter pkgFilter = new IntentFilter();
6675        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6676        pkgFilter.addDataScheme("package");
6677        mContext.registerReceiver(new BroadcastReceiver() {
6678            @Override
6679            public void onReceive(Context context, Intent intent) {
6680                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6681                if (pkgs != null) {
6682                    for (String pkg : pkgs) {
6683                        synchronized (ActivityManagerService.this) {
6684                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6685                                    0, "query restart")) {
6686                                setResultCode(Activity.RESULT_OK);
6687                                return;
6688                            }
6689                        }
6690                    }
6691                }
6692            }
6693        }, pkgFilter);
6694
6695        IntentFilter dumpheapFilter = new IntentFilter();
6696        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6697        mContext.registerReceiver(new BroadcastReceiver() {
6698            @Override
6699            public void onReceive(Context context, Intent intent) {
6700                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6701                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6702                } else {
6703                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6704                }
6705            }
6706        }, dumpheapFilter);
6707
6708        // Let system services know.
6709        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6710
6711        synchronized (this) {
6712            // Ensure that any processes we had put on hold are now started
6713            // up.
6714            final int NP = mProcessesOnHold.size();
6715            if (NP > 0) {
6716                ArrayList<ProcessRecord> procs =
6717                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6718                for (int ip=0; ip<NP; ip++) {
6719                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6720                            + procs.get(ip));
6721                    startProcessLocked(procs.get(ip), "on-hold", null);
6722                }
6723            }
6724
6725            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6726                // Start looking for apps that are abusing wake locks.
6727                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6729                // Tell anyone interested that we are done booting!
6730                SystemProperties.set("sys.boot_completed", "1");
6731
6732                // And trigger dev.bootcomplete if we are not showing encryption progress
6733                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6734                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6735                    SystemProperties.set("dev.bootcomplete", "1");
6736                }
6737                mUserController.sendBootCompletedLocked(
6738                        new IIntentReceiver.Stub() {
6739                            @Override
6740                            public void performReceive(Intent intent, int resultCode,
6741                                    String data, Bundle extras, boolean ordered,
6742                                    boolean sticky, int sendingUser) {
6743                                synchronized (ActivityManagerService.this) {
6744                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6745                                            true, false);
6746                                }
6747                            }
6748                        });
6749                scheduleStartProfilesLocked();
6750            }
6751        }
6752    }
6753
6754    @Override
6755    public void bootAnimationComplete() {
6756        final boolean callFinishBooting;
6757        synchronized (this) {
6758            callFinishBooting = mCallFinishBooting;
6759            mBootAnimationComplete = true;
6760        }
6761        if (callFinishBooting) {
6762            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6763            finishBooting();
6764            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6765        }
6766    }
6767
6768    final void ensureBootCompleted() {
6769        boolean booting;
6770        boolean enableScreen;
6771        synchronized (this) {
6772            booting = mBooting;
6773            mBooting = false;
6774            enableScreen = !mBooted;
6775            mBooted = true;
6776        }
6777
6778        if (booting) {
6779            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6780            finishBooting();
6781            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6782        }
6783
6784        if (enableScreen) {
6785            enableScreenAfterBoot();
6786        }
6787    }
6788
6789    @Override
6790    public final void activityResumed(IBinder token) {
6791        final long origId = Binder.clearCallingIdentity();
6792        synchronized(this) {
6793            ActivityStack stack = ActivityRecord.getStackLocked(token);
6794            if (stack != null) {
6795                stack.activityResumedLocked(token);
6796            }
6797        }
6798        Binder.restoreCallingIdentity(origId);
6799    }
6800
6801    @Override
6802    public final void activityPaused(IBinder token) {
6803        final long origId = Binder.clearCallingIdentity();
6804        synchronized(this) {
6805            ActivityStack stack = ActivityRecord.getStackLocked(token);
6806            if (stack != null) {
6807                stack.activityPausedLocked(token, false);
6808            }
6809        }
6810        Binder.restoreCallingIdentity(origId);
6811    }
6812
6813    @Override
6814    public final void activityStopped(IBinder token, Bundle icicle,
6815            PersistableBundle persistentState, CharSequence description) {
6816        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6817
6818        // Refuse possible leaked file descriptors
6819        if (icicle != null && icicle.hasFileDescriptors()) {
6820            throw new IllegalArgumentException("File descriptors passed in Bundle");
6821        }
6822
6823        final long origId = Binder.clearCallingIdentity();
6824
6825        synchronized (this) {
6826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6827            if (r != null) {
6828                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6829            }
6830        }
6831
6832        trimApplications();
6833
6834        Binder.restoreCallingIdentity(origId);
6835    }
6836
6837    @Override
6838    public final void activityDestroyed(IBinder token) {
6839        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6840        synchronized (this) {
6841            ActivityStack stack = ActivityRecord.getStackLocked(token);
6842            if (stack != null) {
6843                stack.activityDestroyedLocked(token, "activityDestroyed");
6844            }
6845        }
6846    }
6847
6848    @Override
6849    public final void activityRelaunched(IBinder token) {
6850        final long origId = Binder.clearCallingIdentity();
6851        synchronized (this) {
6852            mStackSupervisor.activityRelaunchedLocked(token);
6853        }
6854        Binder.restoreCallingIdentity(origId);
6855    }
6856
6857    @Override
6858    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6859            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6860        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6861                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6862        synchronized (this) {
6863            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6864            if (record == null) {
6865                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6866                        + "found for: " + token);
6867            }
6868            record.setSizeConfigurations(horizontalSizeConfiguration,
6869                    verticalSizeConfigurations, smallestSizeConfigurations);
6870        }
6871    }
6872
6873    @Override
6874    public final void backgroundResourcesReleased(IBinder token) {
6875        final long origId = Binder.clearCallingIdentity();
6876        try {
6877            synchronized (this) {
6878                ActivityStack stack = ActivityRecord.getStackLocked(token);
6879                if (stack != null) {
6880                    stack.backgroundResourcesReleased();
6881                }
6882            }
6883        } finally {
6884            Binder.restoreCallingIdentity(origId);
6885        }
6886    }
6887
6888    @Override
6889    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6890        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6891    }
6892
6893    @Override
6894    public final void notifyEnterAnimationComplete(IBinder token) {
6895        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6896    }
6897
6898    @Override
6899    public String getCallingPackage(IBinder token) {
6900        synchronized (this) {
6901            ActivityRecord r = getCallingRecordLocked(token);
6902            return r != null ? r.info.packageName : null;
6903        }
6904    }
6905
6906    @Override
6907    public ComponentName getCallingActivity(IBinder token) {
6908        synchronized (this) {
6909            ActivityRecord r = getCallingRecordLocked(token);
6910            return r != null ? r.intent.getComponent() : null;
6911        }
6912    }
6913
6914    private ActivityRecord getCallingRecordLocked(IBinder token) {
6915        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6916        if (r == null) {
6917            return null;
6918        }
6919        return r.resultTo;
6920    }
6921
6922    @Override
6923    public ComponentName getActivityClassForToken(IBinder token) {
6924        synchronized(this) {
6925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926            if (r == null) {
6927                return null;
6928            }
6929            return r.intent.getComponent();
6930        }
6931    }
6932
6933    @Override
6934    public String getPackageForToken(IBinder token) {
6935        synchronized(this) {
6936            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6937            if (r == null) {
6938                return null;
6939            }
6940            return r.packageName;
6941        }
6942    }
6943
6944    @Override
6945    public boolean isRootVoiceInteraction(IBinder token) {
6946        synchronized(this) {
6947            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6948            if (r == null) {
6949                return false;
6950            }
6951            return r.rootVoiceInteraction;
6952        }
6953    }
6954
6955    @Override
6956    public IIntentSender getIntentSender(int type,
6957            String packageName, IBinder token, String resultWho,
6958            int requestCode, Intent[] intents, String[] resolvedTypes,
6959            int flags, Bundle bOptions, int userId) {
6960        enforceNotIsolatedCaller("getIntentSender");
6961        // Refuse possible leaked file descriptors
6962        if (intents != null) {
6963            if (intents.length < 1) {
6964                throw new IllegalArgumentException("Intents array length must be >= 1");
6965            }
6966            for (int i=0; i<intents.length; i++) {
6967                Intent intent = intents[i];
6968                if (intent != null) {
6969                    if (intent.hasFileDescriptors()) {
6970                        throw new IllegalArgumentException("File descriptors passed in Intent");
6971                    }
6972                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6973                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6974                        throw new IllegalArgumentException(
6975                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6976                    }
6977                    intents[i] = new Intent(intent);
6978                }
6979            }
6980            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6981                throw new IllegalArgumentException(
6982                        "Intent array length does not match resolvedTypes length");
6983            }
6984        }
6985        if (bOptions != null) {
6986            if (bOptions.hasFileDescriptors()) {
6987                throw new IllegalArgumentException("File descriptors passed in options");
6988            }
6989        }
6990
6991        synchronized(this) {
6992            int callingUid = Binder.getCallingUid();
6993            int origUserId = userId;
6994            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6995                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6996                    ALLOW_NON_FULL, "getIntentSender", null);
6997            if (origUserId == UserHandle.USER_CURRENT) {
6998                // We don't want to evaluate this until the pending intent is
6999                // actually executed.  However, we do want to always do the
7000                // security checking for it above.
7001                userId = UserHandle.USER_CURRENT;
7002            }
7003            try {
7004                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7005                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7006                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7007                    if (!UserHandle.isSameApp(callingUid, uid)) {
7008                        String msg = "Permission Denial: getIntentSender() from pid="
7009                            + Binder.getCallingPid()
7010                            + ", uid=" + Binder.getCallingUid()
7011                            + ", (need uid=" + uid + ")"
7012                            + " is not allowed to send as package " + packageName;
7013                        Slog.w(TAG, msg);
7014                        throw new SecurityException(msg);
7015                    }
7016                }
7017
7018                return getIntentSenderLocked(type, packageName, callingUid, userId,
7019                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7020
7021            } catch (RemoteException e) {
7022                throw new SecurityException(e);
7023            }
7024        }
7025    }
7026
7027    IIntentSender getIntentSenderLocked(int type, String packageName,
7028            int callingUid, int userId, IBinder token, String resultWho,
7029            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7030            Bundle bOptions) {
7031        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7032        ActivityRecord activity = null;
7033        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7034            activity = ActivityRecord.isInStackLocked(token);
7035            if (activity == null) {
7036                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7037                return null;
7038            }
7039            if (activity.finishing) {
7040                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7041                return null;
7042            }
7043        }
7044
7045        // We're going to be splicing together extras before sending, so we're
7046        // okay poking into any contained extras.
7047        if (intents != null) {
7048            for (int i = 0; i < intents.length; i++) {
7049                intents[i].setDefusable(true);
7050            }
7051        }
7052        Bundle.setDefusable(bOptions, true);
7053
7054        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7055        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7056        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7057        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7058                |PendingIntent.FLAG_UPDATE_CURRENT);
7059
7060        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7061                type, packageName, activity, resultWho,
7062                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7063        WeakReference<PendingIntentRecord> ref;
7064        ref = mIntentSenderRecords.get(key);
7065        PendingIntentRecord rec = ref != null ? ref.get() : null;
7066        if (rec != null) {
7067            if (!cancelCurrent) {
7068                if (updateCurrent) {
7069                    if (rec.key.requestIntent != null) {
7070                        rec.key.requestIntent.replaceExtras(intents != null ?
7071                                intents[intents.length - 1] : null);
7072                    }
7073                    if (intents != null) {
7074                        intents[intents.length-1] = rec.key.requestIntent;
7075                        rec.key.allIntents = intents;
7076                        rec.key.allResolvedTypes = resolvedTypes;
7077                    } else {
7078                        rec.key.allIntents = null;
7079                        rec.key.allResolvedTypes = null;
7080                    }
7081                }
7082                return rec;
7083            }
7084            rec.canceled = true;
7085            mIntentSenderRecords.remove(key);
7086        }
7087        if (noCreate) {
7088            return rec;
7089        }
7090        rec = new PendingIntentRecord(this, key, callingUid);
7091        mIntentSenderRecords.put(key, rec.ref);
7092        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7093            if (activity.pendingResults == null) {
7094                activity.pendingResults
7095                        = new HashSet<WeakReference<PendingIntentRecord>>();
7096            }
7097            activity.pendingResults.add(rec.ref);
7098        }
7099        return rec;
7100    }
7101
7102    @Override
7103    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7104            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7105        if (target instanceof PendingIntentRecord) {
7106            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7107                    finishedReceiver, requiredPermission, options);
7108        } else {
7109            if (intent == null) {
7110                // Weird case: someone has given us their own custom IIntentSender, and now
7111                // they have someone else trying to send to it but of course this isn't
7112                // really a PendingIntent, so there is no base Intent, and the caller isn't
7113                // supplying an Intent... but we never want to dispatch a null Intent to
7114                // a receiver, so um...  let's make something up.
7115                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7116                intent = new Intent(Intent.ACTION_MAIN);
7117            }
7118            try {
7119                target.send(code, intent, resolvedType, null, requiredPermission, options);
7120            } catch (RemoteException e) {
7121            }
7122            // Platform code can rely on getting a result back when the send is done, but if
7123            // this intent sender is from outside of the system we can't rely on it doing that.
7124            // So instead we don't give it the result receiver, and instead just directly
7125            // report the finish immediately.
7126            if (finishedReceiver != null) {
7127                try {
7128                    finishedReceiver.performReceive(intent, 0,
7129                            null, null, false, false, UserHandle.getCallingUserId());
7130                } catch (RemoteException e) {
7131                }
7132            }
7133            return 0;
7134        }
7135    }
7136
7137    /**
7138     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7139     *
7140     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7141     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7142     */
7143    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7144        if (DEBUG_WHITELISTS) {
7145            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7146                    + targetUid + ", " + duration + ")");
7147        }
7148        synchronized (mPidsSelfLocked) {
7149            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7150            if (pr == null) {
7151                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7152                return;
7153            }
7154            if (!pr.whitelistManager) {
7155                if (DEBUG_WHITELISTS) {
7156                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7157                            + callerPid + " is not allowed");
7158                }
7159                return;
7160            }
7161        }
7162
7163        final long token = Binder.clearCallingIdentity();
7164        try {
7165            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7166                    true, "pe from uid:" + callerUid);
7167        } finally {
7168            Binder.restoreCallingIdentity(token);
7169        }
7170    }
7171
7172    @Override
7173    public void cancelIntentSender(IIntentSender sender) {
7174        if (!(sender instanceof PendingIntentRecord)) {
7175            return;
7176        }
7177        synchronized(this) {
7178            PendingIntentRecord rec = (PendingIntentRecord)sender;
7179            try {
7180                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7181                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7182                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7183                    String msg = "Permission Denial: cancelIntentSender() from pid="
7184                        + Binder.getCallingPid()
7185                        + ", uid=" + Binder.getCallingUid()
7186                        + " is not allowed to cancel packges "
7187                        + rec.key.packageName;
7188                    Slog.w(TAG, msg);
7189                    throw new SecurityException(msg);
7190                }
7191            } catch (RemoteException e) {
7192                throw new SecurityException(e);
7193            }
7194            cancelIntentSenderLocked(rec, true);
7195        }
7196    }
7197
7198    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7199        rec.canceled = true;
7200        mIntentSenderRecords.remove(rec.key);
7201        if (cleanActivity && rec.key.activity != null) {
7202            rec.key.activity.pendingResults.remove(rec.ref);
7203        }
7204    }
7205
7206    @Override
7207    public String getPackageForIntentSender(IIntentSender pendingResult) {
7208        if (!(pendingResult instanceof PendingIntentRecord)) {
7209            return null;
7210        }
7211        try {
7212            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7213            return res.key.packageName;
7214        } catch (ClassCastException e) {
7215        }
7216        return null;
7217    }
7218
7219    @Override
7220    public int getUidForIntentSender(IIntentSender sender) {
7221        if (sender instanceof PendingIntentRecord) {
7222            try {
7223                PendingIntentRecord res = (PendingIntentRecord)sender;
7224                return res.uid;
7225            } catch (ClassCastException e) {
7226            }
7227        }
7228        return -1;
7229    }
7230
7231    @Override
7232    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7233        if (!(pendingResult instanceof PendingIntentRecord)) {
7234            return false;
7235        }
7236        try {
7237            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7238            if (res.key.allIntents == null) {
7239                return false;
7240            }
7241            for (int i=0; i<res.key.allIntents.length; i++) {
7242                Intent intent = res.key.allIntents[i];
7243                if (intent.getPackage() != null && intent.getComponent() != null) {
7244                    return false;
7245                }
7246            }
7247            return true;
7248        } catch (ClassCastException e) {
7249        }
7250        return false;
7251    }
7252
7253    @Override
7254    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7255        if (!(pendingResult instanceof PendingIntentRecord)) {
7256            return false;
7257        }
7258        try {
7259            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7260            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7261                return true;
7262            }
7263            return false;
7264        } catch (ClassCastException e) {
7265        }
7266        return false;
7267    }
7268
7269    @Override
7270    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7271        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7272                "getIntentForIntentSender()");
7273        if (!(pendingResult instanceof PendingIntentRecord)) {
7274            return null;
7275        }
7276        try {
7277            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7278            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7279        } catch (ClassCastException e) {
7280        }
7281        return null;
7282    }
7283
7284    @Override
7285    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7286        if (!(pendingResult instanceof PendingIntentRecord)) {
7287            return null;
7288        }
7289        try {
7290            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7291            synchronized (this) {
7292                return getTagForIntentSenderLocked(res, prefix);
7293            }
7294        } catch (ClassCastException e) {
7295        }
7296        return null;
7297    }
7298
7299    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7300        final Intent intent = res.key.requestIntent;
7301        if (intent != null) {
7302            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7303                    || res.lastTagPrefix.equals(prefix))) {
7304                return res.lastTag;
7305            }
7306            res.lastTagPrefix = prefix;
7307            final StringBuilder sb = new StringBuilder(128);
7308            if (prefix != null) {
7309                sb.append(prefix);
7310            }
7311            if (intent.getAction() != null) {
7312                sb.append(intent.getAction());
7313            } else if (intent.getComponent() != null) {
7314                intent.getComponent().appendShortString(sb);
7315            } else {
7316                sb.append("?");
7317            }
7318            return res.lastTag = sb.toString();
7319        }
7320        return null;
7321    }
7322
7323    @Override
7324    public void setProcessLimit(int max) {
7325        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7326                "setProcessLimit()");
7327        synchronized (this) {
7328            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7329            mProcessLimitOverride = max;
7330        }
7331        trimApplications();
7332    }
7333
7334    @Override
7335    public int getProcessLimit() {
7336        synchronized (this) {
7337            return mProcessLimitOverride;
7338        }
7339    }
7340
7341    void foregroundTokenDied(ForegroundToken token) {
7342        synchronized (ActivityManagerService.this) {
7343            synchronized (mPidsSelfLocked) {
7344                ForegroundToken cur
7345                    = mForegroundProcesses.get(token.pid);
7346                if (cur != token) {
7347                    return;
7348                }
7349                mForegroundProcesses.remove(token.pid);
7350                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7351                if (pr == null) {
7352                    return;
7353                }
7354                pr.forcingToForeground = null;
7355                updateProcessForegroundLocked(pr, false, false);
7356            }
7357            updateOomAdjLocked();
7358        }
7359    }
7360
7361    @Override
7362    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7363        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7364                "setProcessForeground()");
7365        synchronized(this) {
7366            boolean changed = false;
7367
7368            synchronized (mPidsSelfLocked) {
7369                ProcessRecord pr = mPidsSelfLocked.get(pid);
7370                if (pr == null && isForeground) {
7371                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7372                    return;
7373                }
7374                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7375                if (oldToken != null) {
7376                    oldToken.token.unlinkToDeath(oldToken, 0);
7377                    mForegroundProcesses.remove(pid);
7378                    if (pr != null) {
7379                        pr.forcingToForeground = null;
7380                    }
7381                    changed = true;
7382                }
7383                if (isForeground && token != null) {
7384                    ForegroundToken newToken = new ForegroundToken() {
7385                        @Override
7386                        public void binderDied() {
7387                            foregroundTokenDied(this);
7388                        }
7389                    };
7390                    newToken.pid = pid;
7391                    newToken.token = token;
7392                    try {
7393                        token.linkToDeath(newToken, 0);
7394                        mForegroundProcesses.put(pid, newToken);
7395                        pr.forcingToForeground = token;
7396                        changed = true;
7397                    } catch (RemoteException e) {
7398                        // If the process died while doing this, we will later
7399                        // do the cleanup with the process death link.
7400                    }
7401                }
7402            }
7403
7404            if (changed) {
7405                updateOomAdjLocked();
7406            }
7407        }
7408    }
7409
7410    @Override
7411    public boolean isAppForeground(int uid) throws RemoteException {
7412        synchronized (this) {
7413            UidRecord uidRec = mActiveUids.get(uid);
7414            if (uidRec == null || uidRec.idle) {
7415                return false;
7416            }
7417            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7418        }
7419    }
7420
7421    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7422    // be guarded by permission checking.
7423    int getUidState(int uid) {
7424        synchronized (this) {
7425            UidRecord uidRec = mActiveUids.get(uid);
7426            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7427        }
7428    }
7429
7430    @Override
7431    public boolean isInMultiWindowMode(IBinder token) {
7432        final long origId = Binder.clearCallingIdentity();
7433        try {
7434            synchronized(this) {
7435                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7436                if (r == null) {
7437                    return false;
7438                }
7439                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7440                return !r.task.mFullscreen;
7441            }
7442        } finally {
7443            Binder.restoreCallingIdentity(origId);
7444        }
7445    }
7446
7447    @Override
7448    public boolean isInPictureInPictureMode(IBinder token) {
7449        final long origId = Binder.clearCallingIdentity();
7450        try {
7451            synchronized(this) {
7452                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7453                if (stack == null) {
7454                    return false;
7455                }
7456                return stack.mStackId == PINNED_STACK_ID;
7457            }
7458        } finally {
7459            Binder.restoreCallingIdentity(origId);
7460        }
7461    }
7462
7463    @Override
7464    public void enterPictureInPictureMode(IBinder token) {
7465        final long origId = Binder.clearCallingIdentity();
7466        try {
7467            synchronized(this) {
7468                if (!mSupportsPictureInPicture) {
7469                    throw new IllegalStateException("enterPictureInPictureMode: "
7470                            + "Device doesn't support picture-in-picture mode.");
7471                }
7472
7473                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7474
7475                if (r == null) {
7476                    throw new IllegalStateException("enterPictureInPictureMode: "
7477                            + "Can't find activity for token=" + token);
7478                }
7479
7480                if (!r.supportsPictureInPicture()) {
7481                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7482                            + "Picture-In-Picture not supported for r=" + r);
7483                }
7484
7485                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7486                // current bounds.
7487                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7488                final Rect bounds = (pinnedStack != null)
7489                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7490
7491                mStackSupervisor.moveActivityToPinnedStackLocked(
7492                        r, "enterPictureInPictureMode", bounds);
7493            }
7494        } finally {
7495            Binder.restoreCallingIdentity(origId);
7496        }
7497    }
7498
7499    // =========================================================
7500    // PROCESS INFO
7501    // =========================================================
7502
7503    static class ProcessInfoService extends IProcessInfoService.Stub {
7504        final ActivityManagerService mActivityManagerService;
7505        ProcessInfoService(ActivityManagerService activityManagerService) {
7506            mActivityManagerService = activityManagerService;
7507        }
7508
7509        @Override
7510        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7511            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7512                    /*in*/ pids, /*out*/ states, null);
7513        }
7514
7515        @Override
7516        public void getProcessStatesAndOomScoresFromPids(
7517                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7518            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7519                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7520        }
7521    }
7522
7523    /**
7524     * For each PID in the given input array, write the current process state
7525     * for that process into the states array, or -1 to indicate that no
7526     * process with the given PID exists. If scores array is provided, write
7527     * the oom score for the process into the scores array, with INVALID_ADJ
7528     * indicating the PID doesn't exist.
7529     */
7530    public void getProcessStatesAndOomScoresForPIDs(
7531            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7532        if (scores != null) {
7533            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7534                    "getProcessStatesAndOomScoresForPIDs()");
7535        }
7536
7537        if (pids == null) {
7538            throw new NullPointerException("pids");
7539        } else if (states == null) {
7540            throw new NullPointerException("states");
7541        } else if (pids.length != states.length) {
7542            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7543        } else if (scores != null && pids.length != scores.length) {
7544            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7545        }
7546
7547        synchronized (mPidsSelfLocked) {
7548            for (int i = 0; i < pids.length; i++) {
7549                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7550                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7551                        pr.curProcState;
7552                if (scores != null) {
7553                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7554                }
7555            }
7556        }
7557    }
7558
7559    // =========================================================
7560    // PERMISSIONS
7561    // =========================================================
7562
7563    static class PermissionController extends IPermissionController.Stub {
7564        ActivityManagerService mActivityManagerService;
7565        PermissionController(ActivityManagerService activityManagerService) {
7566            mActivityManagerService = activityManagerService;
7567        }
7568
7569        @Override
7570        public boolean checkPermission(String permission, int pid, int uid) {
7571            return mActivityManagerService.checkPermission(permission, pid,
7572                    uid) == PackageManager.PERMISSION_GRANTED;
7573        }
7574
7575        @Override
7576        public String[] getPackagesForUid(int uid) {
7577            return mActivityManagerService.mContext.getPackageManager()
7578                    .getPackagesForUid(uid);
7579        }
7580
7581        @Override
7582        public boolean isRuntimePermission(String permission) {
7583            try {
7584                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7585                        .getPermissionInfo(permission, 0);
7586                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7587            } catch (NameNotFoundException nnfe) {
7588                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7589            }
7590            return false;
7591        }
7592    }
7593
7594    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7595        @Override
7596        public int checkComponentPermission(String permission, int pid, int uid,
7597                int owningUid, boolean exported) {
7598            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7599                    owningUid, exported);
7600        }
7601
7602        @Override
7603        public Object getAMSLock() {
7604            return ActivityManagerService.this;
7605        }
7606    }
7607
7608    /**
7609     * This can be called with or without the global lock held.
7610     */
7611    int checkComponentPermission(String permission, int pid, int uid,
7612            int owningUid, boolean exported) {
7613        if (pid == MY_PID) {
7614            return PackageManager.PERMISSION_GRANTED;
7615        }
7616        return ActivityManager.checkComponentPermission(permission, uid,
7617                owningUid, exported);
7618    }
7619
7620    /**
7621     * As the only public entry point for permissions checking, this method
7622     * can enforce the semantic that requesting a check on a null global
7623     * permission is automatically denied.  (Internally a null permission
7624     * string is used when calling {@link #checkComponentPermission} in cases
7625     * when only uid-based security is needed.)
7626     *
7627     * This can be called with or without the global lock held.
7628     */
7629    @Override
7630    public int checkPermission(String permission, int pid, int uid) {
7631        if (permission == null) {
7632            return PackageManager.PERMISSION_DENIED;
7633        }
7634        return checkComponentPermission(permission, pid, uid, -1, true);
7635    }
7636
7637    @Override
7638    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7639        if (permission == null) {
7640            return PackageManager.PERMISSION_DENIED;
7641        }
7642
7643        // We might be performing an operation on behalf of an indirect binder
7644        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7645        // client identity accordingly before proceeding.
7646        Identity tlsIdentity = sCallerIdentity.get();
7647        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7648            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7649                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7650            uid = tlsIdentity.uid;
7651            pid = tlsIdentity.pid;
7652        }
7653
7654        return checkComponentPermission(permission, pid, uid, -1, true);
7655    }
7656
7657    /**
7658     * Binder IPC calls go through the public entry point.
7659     * This can be called with or without the global lock held.
7660     */
7661    int checkCallingPermission(String permission) {
7662        return checkPermission(permission,
7663                Binder.getCallingPid(),
7664                UserHandle.getAppId(Binder.getCallingUid()));
7665    }
7666
7667    /**
7668     * This can be called with or without the global lock held.
7669     */
7670    void enforceCallingPermission(String permission, String func) {
7671        if (checkCallingPermission(permission)
7672                == PackageManager.PERMISSION_GRANTED) {
7673            return;
7674        }
7675
7676        String msg = "Permission Denial: " + func + " from pid="
7677                + Binder.getCallingPid()
7678                + ", uid=" + Binder.getCallingUid()
7679                + " requires " + permission;
7680        Slog.w(TAG, msg);
7681        throw new SecurityException(msg);
7682    }
7683
7684    /**
7685     * Determine if UID is holding permissions required to access {@link Uri} in
7686     * the given {@link ProviderInfo}. Final permission checking is always done
7687     * in {@link ContentProvider}.
7688     */
7689    private final boolean checkHoldingPermissionsLocked(
7690            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7691        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7692                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7693        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7694            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7695                    != PERMISSION_GRANTED) {
7696                return false;
7697            }
7698        }
7699        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7700    }
7701
7702    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7703            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7704        if (pi.applicationInfo.uid == uid) {
7705            return true;
7706        } else if (!pi.exported) {
7707            return false;
7708        }
7709
7710        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7711        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7712        try {
7713            // check if target holds top-level <provider> permissions
7714            if (!readMet && pi.readPermission != null && considerUidPermissions
7715                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7716                readMet = true;
7717            }
7718            if (!writeMet && pi.writePermission != null && considerUidPermissions
7719                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7720                writeMet = true;
7721            }
7722
7723            // track if unprotected read/write is allowed; any denied
7724            // <path-permission> below removes this ability
7725            boolean allowDefaultRead = pi.readPermission == null;
7726            boolean allowDefaultWrite = pi.writePermission == null;
7727
7728            // check if target holds any <path-permission> that match uri
7729            final PathPermission[] pps = pi.pathPermissions;
7730            if (pps != null) {
7731                final String path = grantUri.uri.getPath();
7732                int i = pps.length;
7733                while (i > 0 && (!readMet || !writeMet)) {
7734                    i--;
7735                    PathPermission pp = pps[i];
7736                    if (pp.match(path)) {
7737                        if (!readMet) {
7738                            final String pprperm = pp.getReadPermission();
7739                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7740                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7741                                    + ": match=" + pp.match(path)
7742                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7743                            if (pprperm != null) {
7744                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7745                                        == PERMISSION_GRANTED) {
7746                                    readMet = true;
7747                                } else {
7748                                    allowDefaultRead = false;
7749                                }
7750                            }
7751                        }
7752                        if (!writeMet) {
7753                            final String ppwperm = pp.getWritePermission();
7754                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7755                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7756                                    + ": match=" + pp.match(path)
7757                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7758                            if (ppwperm != null) {
7759                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7760                                        == PERMISSION_GRANTED) {
7761                                    writeMet = true;
7762                                } else {
7763                                    allowDefaultWrite = false;
7764                                }
7765                            }
7766                        }
7767                    }
7768                }
7769            }
7770
7771            // grant unprotected <provider> read/write, if not blocked by
7772            // <path-permission> above
7773            if (allowDefaultRead) readMet = true;
7774            if (allowDefaultWrite) writeMet = true;
7775
7776        } catch (RemoteException e) {
7777            return false;
7778        }
7779
7780        return readMet && writeMet;
7781    }
7782
7783    public int getAppStartMode(int uid, String packageName) {
7784        synchronized (this) {
7785            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7786        }
7787    }
7788
7789    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7790            boolean allowWhenForeground) {
7791        UidRecord uidRec = mActiveUids.get(uid);
7792        if (!mLenientBackgroundCheck) {
7793            if (!allowWhenForeground || uidRec == null
7794                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7795                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7796                        packageName) != AppOpsManager.MODE_ALLOWED) {
7797                    return ActivityManager.APP_START_MODE_DELAYED;
7798                }
7799            }
7800
7801        } else if (uidRec == null || uidRec.idle) {
7802            if (callingPid >= 0) {
7803                ProcessRecord proc;
7804                synchronized (mPidsSelfLocked) {
7805                    proc = mPidsSelfLocked.get(callingPid);
7806                }
7807                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7808                    // Whoever is instigating this is in the foreground, so we will allow it
7809                    // to go through.
7810                    return ActivityManager.APP_START_MODE_NORMAL;
7811                }
7812            }
7813            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7814                    != AppOpsManager.MODE_ALLOWED) {
7815                return ActivityManager.APP_START_MODE_DELAYED;
7816            }
7817        }
7818        return ActivityManager.APP_START_MODE_NORMAL;
7819    }
7820
7821    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7822        ProviderInfo pi = null;
7823        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7824        if (cpr != null) {
7825            pi = cpr.info;
7826        } else {
7827            try {
7828                pi = AppGlobals.getPackageManager().resolveContentProvider(
7829                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7830            } catch (RemoteException ex) {
7831            }
7832        }
7833        return pi;
7834    }
7835
7836    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7837        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7838        if (targetUris != null) {
7839            return targetUris.get(grantUri);
7840        }
7841        return null;
7842    }
7843
7844    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7845            String targetPkg, int targetUid, GrantUri grantUri) {
7846        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7847        if (targetUris == null) {
7848            targetUris = Maps.newArrayMap();
7849            mGrantedUriPermissions.put(targetUid, targetUris);
7850        }
7851
7852        UriPermission perm = targetUris.get(grantUri);
7853        if (perm == null) {
7854            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7855            targetUris.put(grantUri, perm);
7856        }
7857
7858        return perm;
7859    }
7860
7861    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7862            final int modeFlags) {
7863        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7864        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7865                : UriPermission.STRENGTH_OWNED;
7866
7867        // Root gets to do everything.
7868        if (uid == 0) {
7869            return true;
7870        }
7871
7872        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7873        if (perms == null) return false;
7874
7875        // First look for exact match
7876        final UriPermission exactPerm = perms.get(grantUri);
7877        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7878            return true;
7879        }
7880
7881        // No exact match, look for prefixes
7882        final int N = perms.size();
7883        for (int i = 0; i < N; i++) {
7884            final UriPermission perm = perms.valueAt(i);
7885            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7886                    && perm.getStrength(modeFlags) >= minStrength) {
7887                return true;
7888            }
7889        }
7890
7891        return false;
7892    }
7893
7894    /**
7895     * @param uri This uri must NOT contain an embedded userId.
7896     * @param userId The userId in which the uri is to be resolved.
7897     */
7898    @Override
7899    public int checkUriPermission(Uri uri, int pid, int uid,
7900            final int modeFlags, int userId, IBinder callerToken) {
7901        enforceNotIsolatedCaller("checkUriPermission");
7902
7903        // Another redirected-binder-call permissions check as in
7904        // {@link checkPermissionWithToken}.
7905        Identity tlsIdentity = sCallerIdentity.get();
7906        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7907            uid = tlsIdentity.uid;
7908            pid = tlsIdentity.pid;
7909        }
7910
7911        // Our own process gets to do everything.
7912        if (pid == MY_PID) {
7913            return PackageManager.PERMISSION_GRANTED;
7914        }
7915        synchronized (this) {
7916            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7917                    ? PackageManager.PERMISSION_GRANTED
7918                    : PackageManager.PERMISSION_DENIED;
7919        }
7920    }
7921
7922    /**
7923     * Check if the targetPkg can be granted permission to access uri by
7924     * the callingUid using the given modeFlags.  Throws a security exception
7925     * if callingUid is not allowed to do this.  Returns the uid of the target
7926     * if the URI permission grant should be performed; returns -1 if it is not
7927     * needed (for example targetPkg already has permission to access the URI).
7928     * If you already know the uid of the target, you can supply it in
7929     * lastTargetUid else set that to -1.
7930     */
7931    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7932            final int modeFlags, int lastTargetUid) {
7933        if (!Intent.isAccessUriMode(modeFlags)) {
7934            return -1;
7935        }
7936
7937        if (targetPkg != null) {
7938            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7939                    "Checking grant " + targetPkg + " permission to " + grantUri);
7940        }
7941
7942        final IPackageManager pm = AppGlobals.getPackageManager();
7943
7944        // If this is not a content: uri, we can't do anything with it.
7945        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7946            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7947                    "Can't grant URI permission for non-content URI: " + grantUri);
7948            return -1;
7949        }
7950
7951        final String authority = grantUri.uri.getAuthority();
7952        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7953        if (pi == null) {
7954            Slog.w(TAG, "No content provider found for permission check: " +
7955                    grantUri.uri.toSafeString());
7956            return -1;
7957        }
7958
7959        int targetUid = lastTargetUid;
7960        if (targetUid < 0 && targetPkg != null) {
7961            try {
7962                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7963                        UserHandle.getUserId(callingUid));
7964                if (targetUid < 0) {
7965                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7966                            "Can't grant URI permission no uid for: " + targetPkg);
7967                    return -1;
7968                }
7969            } catch (RemoteException ex) {
7970                return -1;
7971            }
7972        }
7973
7974        if (targetUid >= 0) {
7975            // First...  does the target actually need this permission?
7976            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7977                // No need to grant the target this permission.
7978                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7979                        "Target " + targetPkg + " already has full permission to " + grantUri);
7980                return -1;
7981            }
7982        } else {
7983            // First...  there is no target package, so can anyone access it?
7984            boolean allowed = pi.exported;
7985            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7986                if (pi.readPermission != null) {
7987                    allowed = false;
7988                }
7989            }
7990            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7991                if (pi.writePermission != null) {
7992                    allowed = false;
7993                }
7994            }
7995            if (allowed) {
7996                return -1;
7997            }
7998        }
7999
8000        /* There is a special cross user grant if:
8001         * - The target is on another user.
8002         * - Apps on the current user can access the uri without any uid permissions.
8003         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8004         * grant uri permissions.
8005         */
8006        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8007                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8008                modeFlags, false /*without considering the uid permissions*/);
8009
8010        // Second...  is the provider allowing granting of URI permissions?
8011        if (!specialCrossUserGrant) {
8012            if (!pi.grantUriPermissions) {
8013                throw new SecurityException("Provider " + pi.packageName
8014                        + "/" + pi.name
8015                        + " does not allow granting of Uri permissions (uri "
8016                        + grantUri + ")");
8017            }
8018            if (pi.uriPermissionPatterns != null) {
8019                final int N = pi.uriPermissionPatterns.length;
8020                boolean allowed = false;
8021                for (int i=0; i<N; i++) {
8022                    if (pi.uriPermissionPatterns[i] != null
8023                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8024                        allowed = true;
8025                        break;
8026                    }
8027                }
8028                if (!allowed) {
8029                    throw new SecurityException("Provider " + pi.packageName
8030                            + "/" + pi.name
8031                            + " does not allow granting of permission to path of Uri "
8032                            + grantUri);
8033                }
8034            }
8035        }
8036
8037        // Third...  does the caller itself have permission to access
8038        // this uri?
8039        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8040            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8041                // Require they hold a strong enough Uri permission
8042                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8043                    throw new SecurityException("Uid " + callingUid
8044                            + " does not have permission to uri " + grantUri);
8045                }
8046            }
8047        }
8048        return targetUid;
8049    }
8050
8051    /**
8052     * @param uri This uri must NOT contain an embedded userId.
8053     * @param userId The userId in which the uri is to be resolved.
8054     */
8055    @Override
8056    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8057            final int modeFlags, int userId) {
8058        enforceNotIsolatedCaller("checkGrantUriPermission");
8059        synchronized(this) {
8060            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8061                    new GrantUri(userId, uri, false), modeFlags, -1);
8062        }
8063    }
8064
8065    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8066            final int modeFlags, UriPermissionOwner owner) {
8067        if (!Intent.isAccessUriMode(modeFlags)) {
8068            return;
8069        }
8070
8071        // So here we are: the caller has the assumed permission
8072        // to the uri, and the target doesn't.  Let's now give this to
8073        // the target.
8074
8075        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8076                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8077
8078        final String authority = grantUri.uri.getAuthority();
8079        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8080        if (pi == null) {
8081            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8082            return;
8083        }
8084
8085        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8086            grantUri.prefix = true;
8087        }
8088        final UriPermission perm = findOrCreateUriPermissionLocked(
8089                pi.packageName, targetPkg, targetUid, grantUri);
8090        perm.grantModes(modeFlags, owner);
8091    }
8092
8093    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8094            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8095        if (targetPkg == null) {
8096            throw new NullPointerException("targetPkg");
8097        }
8098        int targetUid;
8099        final IPackageManager pm = AppGlobals.getPackageManager();
8100        try {
8101            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8102        } catch (RemoteException ex) {
8103            return;
8104        }
8105
8106        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8107                targetUid);
8108        if (targetUid < 0) {
8109            return;
8110        }
8111
8112        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8113                owner);
8114    }
8115
8116    static class NeededUriGrants extends ArrayList<GrantUri> {
8117        final String targetPkg;
8118        final int targetUid;
8119        final int flags;
8120
8121        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8122            this.targetPkg = targetPkg;
8123            this.targetUid = targetUid;
8124            this.flags = flags;
8125        }
8126    }
8127
8128    /**
8129     * Like checkGrantUriPermissionLocked, but takes an Intent.
8130     */
8131    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8132            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8133        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8135                + " clip=" + (intent != null ? intent.getClipData() : null)
8136                + " from " + intent + "; flags=0x"
8137                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8138
8139        if (targetPkg == null) {
8140            throw new NullPointerException("targetPkg");
8141        }
8142
8143        if (intent == null) {
8144            return null;
8145        }
8146        Uri data = intent.getData();
8147        ClipData clip = intent.getClipData();
8148        if (data == null && clip == null) {
8149            return null;
8150        }
8151        // Default userId for uris in the intent (if they don't specify it themselves)
8152        int contentUserHint = intent.getContentUserHint();
8153        if (contentUserHint == UserHandle.USER_CURRENT) {
8154            contentUserHint = UserHandle.getUserId(callingUid);
8155        }
8156        final IPackageManager pm = AppGlobals.getPackageManager();
8157        int targetUid;
8158        if (needed != null) {
8159            targetUid = needed.targetUid;
8160        } else {
8161            try {
8162                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8163                        targetUserId);
8164            } catch (RemoteException ex) {
8165                return null;
8166            }
8167            if (targetUid < 0) {
8168                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8169                        "Can't grant URI permission no uid for: " + targetPkg
8170                        + " on user " + targetUserId);
8171                return null;
8172            }
8173        }
8174        if (data != null) {
8175            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8176            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8177                    targetUid);
8178            if (targetUid > 0) {
8179                if (needed == null) {
8180                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8181                }
8182                needed.add(grantUri);
8183            }
8184        }
8185        if (clip != null) {
8186            for (int i=0; i<clip.getItemCount(); i++) {
8187                Uri uri = clip.getItemAt(i).getUri();
8188                if (uri != null) {
8189                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8190                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8191                            targetUid);
8192                    if (targetUid > 0) {
8193                        if (needed == null) {
8194                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8195                        }
8196                        needed.add(grantUri);
8197                    }
8198                } else {
8199                    Intent clipIntent = clip.getItemAt(i).getIntent();
8200                    if (clipIntent != null) {
8201                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8202                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8203                        if (newNeeded != null) {
8204                            needed = newNeeded;
8205                        }
8206                    }
8207                }
8208            }
8209        }
8210
8211        return needed;
8212    }
8213
8214    /**
8215     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8216     */
8217    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8218            UriPermissionOwner owner) {
8219        if (needed != null) {
8220            for (int i=0; i<needed.size(); i++) {
8221                GrantUri grantUri = needed.get(i);
8222                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8223                        grantUri, needed.flags, owner);
8224            }
8225        }
8226    }
8227
8228    void grantUriPermissionFromIntentLocked(int callingUid,
8229            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8230        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8231                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8232        if (needed == null) {
8233            return;
8234        }
8235
8236        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8237    }
8238
8239    /**
8240     * @param uri This uri must NOT contain an embedded userId.
8241     * @param userId The userId in which the uri is to be resolved.
8242     */
8243    @Override
8244    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8245            final int modeFlags, int userId) {
8246        enforceNotIsolatedCaller("grantUriPermission");
8247        GrantUri grantUri = new GrantUri(userId, uri, false);
8248        synchronized(this) {
8249            final ProcessRecord r = getRecordForAppLocked(caller);
8250            if (r == null) {
8251                throw new SecurityException("Unable to find app for caller "
8252                        + caller
8253                        + " when granting permission to uri " + grantUri);
8254            }
8255            if (targetPkg == null) {
8256                throw new IllegalArgumentException("null target");
8257            }
8258            if (grantUri == null) {
8259                throw new IllegalArgumentException("null uri");
8260            }
8261
8262            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8263                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8264                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8265                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8266
8267            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8268                    UserHandle.getUserId(r.uid));
8269        }
8270    }
8271
8272    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8273        if (perm.modeFlags == 0) {
8274            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8275                    perm.targetUid);
8276            if (perms != null) {
8277                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8278                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8279
8280                perms.remove(perm.uri);
8281                if (perms.isEmpty()) {
8282                    mGrantedUriPermissions.remove(perm.targetUid);
8283                }
8284            }
8285        }
8286    }
8287
8288    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8289        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8290                "Revoking all granted permissions to " + grantUri);
8291
8292        final IPackageManager pm = AppGlobals.getPackageManager();
8293        final String authority = grantUri.uri.getAuthority();
8294        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8295        if (pi == null) {
8296            Slog.w(TAG, "No content provider found for permission revoke: "
8297                    + grantUri.toSafeString());
8298            return;
8299        }
8300
8301        // Does the caller have this permission on the URI?
8302        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8303            // If they don't have direct access to the URI, then revoke any
8304            // ownerless URI permissions that have been granted to them.
8305            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8306            if (perms != null) {
8307                boolean persistChanged = false;
8308                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8309                    final UriPermission perm = it.next();
8310                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8311                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8312                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8313                                "Revoking non-owned " + perm.targetUid
8314                                + " permission to " + perm.uri);
8315                        persistChanged |= perm.revokeModes(
8316                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8317                        if (perm.modeFlags == 0) {
8318                            it.remove();
8319                        }
8320                    }
8321                }
8322                if (perms.isEmpty()) {
8323                    mGrantedUriPermissions.remove(callingUid);
8324                }
8325                if (persistChanged) {
8326                    schedulePersistUriGrants();
8327                }
8328            }
8329            return;
8330        }
8331
8332        boolean persistChanged = false;
8333
8334        // Go through all of the permissions and remove any that match.
8335        int N = mGrantedUriPermissions.size();
8336        for (int i = 0; i < N; i++) {
8337            final int targetUid = mGrantedUriPermissions.keyAt(i);
8338            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8339
8340            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8341                final UriPermission perm = it.next();
8342                if (perm.uri.sourceUserId == grantUri.sourceUserId
8343                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8344                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8345                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8346                    persistChanged |= perm.revokeModes(
8347                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8348                    if (perm.modeFlags == 0) {
8349                        it.remove();
8350                    }
8351                }
8352            }
8353
8354            if (perms.isEmpty()) {
8355                mGrantedUriPermissions.remove(targetUid);
8356                N--;
8357                i--;
8358            }
8359        }
8360
8361        if (persistChanged) {
8362            schedulePersistUriGrants();
8363        }
8364    }
8365
8366    /**
8367     * @param uri This uri must NOT contain an embedded userId.
8368     * @param userId The userId in which the uri is to be resolved.
8369     */
8370    @Override
8371    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8372            int userId) {
8373        enforceNotIsolatedCaller("revokeUriPermission");
8374        synchronized(this) {
8375            final ProcessRecord r = getRecordForAppLocked(caller);
8376            if (r == null) {
8377                throw new SecurityException("Unable to find app for caller "
8378                        + caller
8379                        + " when revoking permission to uri " + uri);
8380            }
8381            if (uri == null) {
8382                Slog.w(TAG, "revokeUriPermission: null uri");
8383                return;
8384            }
8385
8386            if (!Intent.isAccessUriMode(modeFlags)) {
8387                return;
8388            }
8389
8390            final String authority = uri.getAuthority();
8391            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8392            if (pi == null) {
8393                Slog.w(TAG, "No content provider found for permission revoke: "
8394                        + uri.toSafeString());
8395                return;
8396            }
8397
8398            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8399        }
8400    }
8401
8402    /**
8403     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8404     * given package.
8405     *
8406     * @param packageName Package name to match, or {@code null} to apply to all
8407     *            packages.
8408     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8409     *            to all users.
8410     * @param persistable If persistable grants should be removed.
8411     */
8412    private void removeUriPermissionsForPackageLocked(
8413            String packageName, int userHandle, boolean persistable) {
8414        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8415            throw new IllegalArgumentException("Must narrow by either package or user");
8416        }
8417
8418        boolean persistChanged = false;
8419
8420        int N = mGrantedUriPermissions.size();
8421        for (int i = 0; i < N; i++) {
8422            final int targetUid = mGrantedUriPermissions.keyAt(i);
8423            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8424
8425            // Only inspect grants matching user
8426            if (userHandle == UserHandle.USER_ALL
8427                    || userHandle == UserHandle.getUserId(targetUid)) {
8428                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8429                    final UriPermission perm = it.next();
8430
8431                    // Only inspect grants matching package
8432                    if (packageName == null || perm.sourcePkg.equals(packageName)
8433                            || perm.targetPkg.equals(packageName)) {
8434                        persistChanged |= perm.revokeModes(persistable
8435                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8436
8437                        // Only remove when no modes remain; any persisted grants
8438                        // will keep this alive.
8439                        if (perm.modeFlags == 0) {
8440                            it.remove();
8441                        }
8442                    }
8443                }
8444
8445                if (perms.isEmpty()) {
8446                    mGrantedUriPermissions.remove(targetUid);
8447                    N--;
8448                    i--;
8449                }
8450            }
8451        }
8452
8453        if (persistChanged) {
8454            schedulePersistUriGrants();
8455        }
8456    }
8457
8458    @Override
8459    public IBinder newUriPermissionOwner(String name) {
8460        enforceNotIsolatedCaller("newUriPermissionOwner");
8461        synchronized(this) {
8462            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8463            return owner.getExternalTokenLocked();
8464        }
8465    }
8466
8467    @Override
8468    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8469        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8470        synchronized(this) {
8471            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8472            if (r == null) {
8473                throw new IllegalArgumentException("Activity does not exist; token="
8474                        + activityToken);
8475            }
8476            return r.getUriPermissionsLocked().getExternalTokenLocked();
8477        }
8478    }
8479    /**
8480     * @param uri This uri must NOT contain an embedded userId.
8481     * @param sourceUserId The userId in which the uri is to be resolved.
8482     * @param targetUserId The userId of the app that receives the grant.
8483     */
8484    @Override
8485    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8486            final int modeFlags, int sourceUserId, int targetUserId) {
8487        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8488                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8489                "grantUriPermissionFromOwner", null);
8490        synchronized(this) {
8491            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8492            if (owner == null) {
8493                throw new IllegalArgumentException("Unknown owner: " + token);
8494            }
8495            if (fromUid != Binder.getCallingUid()) {
8496                if (Binder.getCallingUid() != Process.myUid()) {
8497                    // Only system code can grant URI permissions on behalf
8498                    // of other users.
8499                    throw new SecurityException("nice try");
8500                }
8501            }
8502            if (targetPkg == null) {
8503                throw new IllegalArgumentException("null target");
8504            }
8505            if (uri == null) {
8506                throw new IllegalArgumentException("null uri");
8507            }
8508
8509            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8510                    modeFlags, owner, targetUserId);
8511        }
8512    }
8513
8514    /**
8515     * @param uri This uri must NOT contain an embedded userId.
8516     * @param userId The userId in which the uri is to be resolved.
8517     */
8518    @Override
8519    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8520        synchronized(this) {
8521            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8522            if (owner == null) {
8523                throw new IllegalArgumentException("Unknown owner: " + token);
8524            }
8525
8526            if (uri == null) {
8527                owner.removeUriPermissionsLocked(mode);
8528            } else {
8529                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8530            }
8531        }
8532    }
8533
8534    private void schedulePersistUriGrants() {
8535        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8536            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8537                    10 * DateUtils.SECOND_IN_MILLIS);
8538        }
8539    }
8540
8541    private void writeGrantedUriPermissions() {
8542        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8543
8544        // Snapshot permissions so we can persist without lock
8545        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8546        synchronized (this) {
8547            final int size = mGrantedUriPermissions.size();
8548            for (int i = 0; i < size; i++) {
8549                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8550                for (UriPermission perm : perms.values()) {
8551                    if (perm.persistedModeFlags != 0) {
8552                        persist.add(perm.snapshot());
8553                    }
8554                }
8555            }
8556        }
8557
8558        FileOutputStream fos = null;
8559        try {
8560            fos = mGrantFile.startWrite();
8561
8562            XmlSerializer out = new FastXmlSerializer();
8563            out.setOutput(fos, StandardCharsets.UTF_8.name());
8564            out.startDocument(null, true);
8565            out.startTag(null, TAG_URI_GRANTS);
8566            for (UriPermission.Snapshot perm : persist) {
8567                out.startTag(null, TAG_URI_GRANT);
8568                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8569                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8570                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8571                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8572                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8573                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8574                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8575                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8576                out.endTag(null, TAG_URI_GRANT);
8577            }
8578            out.endTag(null, TAG_URI_GRANTS);
8579            out.endDocument();
8580
8581            mGrantFile.finishWrite(fos);
8582        } catch (IOException e) {
8583            if (fos != null) {
8584                mGrantFile.failWrite(fos);
8585            }
8586        }
8587    }
8588
8589    private void readGrantedUriPermissionsLocked() {
8590        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8591
8592        final long now = System.currentTimeMillis();
8593
8594        FileInputStream fis = null;
8595        try {
8596            fis = mGrantFile.openRead();
8597            final XmlPullParser in = Xml.newPullParser();
8598            in.setInput(fis, StandardCharsets.UTF_8.name());
8599
8600            int type;
8601            while ((type = in.next()) != END_DOCUMENT) {
8602                final String tag = in.getName();
8603                if (type == START_TAG) {
8604                    if (TAG_URI_GRANT.equals(tag)) {
8605                        final int sourceUserId;
8606                        final int targetUserId;
8607                        final int userHandle = readIntAttribute(in,
8608                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8609                        if (userHandle != UserHandle.USER_NULL) {
8610                            // For backwards compatibility.
8611                            sourceUserId = userHandle;
8612                            targetUserId = userHandle;
8613                        } else {
8614                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8615                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8616                        }
8617                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8618                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8619                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8620                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8621                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8622                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8623
8624                        // Sanity check that provider still belongs to source package
8625                        final ProviderInfo pi = getProviderInfoLocked(
8626                                uri.getAuthority(), sourceUserId);
8627                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8628                            int targetUid = -1;
8629                            try {
8630                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8631                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8632                            } catch (RemoteException e) {
8633                            }
8634                            if (targetUid != -1) {
8635                                final UriPermission perm = findOrCreateUriPermissionLocked(
8636                                        sourcePkg, targetPkg, targetUid,
8637                                        new GrantUri(sourceUserId, uri, prefix));
8638                                perm.initPersistedModes(modeFlags, createdTime);
8639                            }
8640                        } else {
8641                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8642                                    + " but instead found " + pi);
8643                        }
8644                    }
8645                }
8646            }
8647        } catch (FileNotFoundException e) {
8648            // Missing grants is okay
8649        } catch (IOException e) {
8650            Slog.wtf(TAG, "Failed reading Uri grants", e);
8651        } catch (XmlPullParserException e) {
8652            Slog.wtf(TAG, "Failed reading Uri grants", e);
8653        } finally {
8654            IoUtils.closeQuietly(fis);
8655        }
8656    }
8657
8658    /**
8659     * @param uri This uri must NOT contain an embedded userId.
8660     * @param userId The userId in which the uri is to be resolved.
8661     */
8662    @Override
8663    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8664        enforceNotIsolatedCaller("takePersistableUriPermission");
8665
8666        Preconditions.checkFlagsArgument(modeFlags,
8667                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8668
8669        synchronized (this) {
8670            final int callingUid = Binder.getCallingUid();
8671            boolean persistChanged = false;
8672            GrantUri grantUri = new GrantUri(userId, uri, false);
8673
8674            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8675                    new GrantUri(userId, uri, false));
8676            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8677                    new GrantUri(userId, uri, true));
8678
8679            final boolean exactValid = (exactPerm != null)
8680                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8681            final boolean prefixValid = (prefixPerm != null)
8682                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8683
8684            if (!(exactValid || prefixValid)) {
8685                throw new SecurityException("No persistable permission grants found for UID "
8686                        + callingUid + " and Uri " + grantUri.toSafeString());
8687            }
8688
8689            if (exactValid) {
8690                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8691            }
8692            if (prefixValid) {
8693                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8694            }
8695
8696            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8697
8698            if (persistChanged) {
8699                schedulePersistUriGrants();
8700            }
8701        }
8702    }
8703
8704    /**
8705     * @param uri This uri must NOT contain an embedded userId.
8706     * @param userId The userId in which the uri is to be resolved.
8707     */
8708    @Override
8709    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8710        enforceNotIsolatedCaller("releasePersistableUriPermission");
8711
8712        Preconditions.checkFlagsArgument(modeFlags,
8713                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8714
8715        synchronized (this) {
8716            final int callingUid = Binder.getCallingUid();
8717            boolean persistChanged = false;
8718
8719            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8720                    new GrantUri(userId, uri, false));
8721            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8722                    new GrantUri(userId, uri, true));
8723            if (exactPerm == null && prefixPerm == null) {
8724                throw new SecurityException("No permission grants found for UID " + callingUid
8725                        + " and Uri " + uri.toSafeString());
8726            }
8727
8728            if (exactPerm != null) {
8729                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8730                removeUriPermissionIfNeededLocked(exactPerm);
8731            }
8732            if (prefixPerm != null) {
8733                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8734                removeUriPermissionIfNeededLocked(prefixPerm);
8735            }
8736
8737            if (persistChanged) {
8738                schedulePersistUriGrants();
8739            }
8740        }
8741    }
8742
8743    /**
8744     * Prune any older {@link UriPermission} for the given UID until outstanding
8745     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8746     *
8747     * @return if any mutations occured that require persisting.
8748     */
8749    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8750        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8751        if (perms == null) return false;
8752        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8753
8754        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8755        for (UriPermission perm : perms.values()) {
8756            if (perm.persistedModeFlags != 0) {
8757                persisted.add(perm);
8758            }
8759        }
8760
8761        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8762        if (trimCount <= 0) return false;
8763
8764        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8765        for (int i = 0; i < trimCount; i++) {
8766            final UriPermission perm = persisted.get(i);
8767
8768            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8769                    "Trimming grant created at " + perm.persistedCreateTime);
8770
8771            perm.releasePersistableModes(~0);
8772            removeUriPermissionIfNeededLocked(perm);
8773        }
8774
8775        return true;
8776    }
8777
8778    @Override
8779    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8780            String packageName, boolean incoming) {
8781        enforceNotIsolatedCaller("getPersistedUriPermissions");
8782        Preconditions.checkNotNull(packageName, "packageName");
8783
8784        final int callingUid = Binder.getCallingUid();
8785        final IPackageManager pm = AppGlobals.getPackageManager();
8786        try {
8787            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8788                    UserHandle.getUserId(callingUid));
8789            if (packageUid != callingUid) {
8790                throw new SecurityException(
8791                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8792            }
8793        } catch (RemoteException e) {
8794            throw new SecurityException("Failed to verify package name ownership");
8795        }
8796
8797        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8798        synchronized (this) {
8799            if (incoming) {
8800                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8801                        callingUid);
8802                if (perms == null) {
8803                    Slog.w(TAG, "No permission grants found for " + packageName);
8804                } else {
8805                    for (UriPermission perm : perms.values()) {
8806                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8807                            result.add(perm.buildPersistedPublicApiObject());
8808                        }
8809                    }
8810                }
8811            } else {
8812                final int size = mGrantedUriPermissions.size();
8813                for (int i = 0; i < size; i++) {
8814                    final ArrayMap<GrantUri, UriPermission> perms =
8815                            mGrantedUriPermissions.valueAt(i);
8816                    for (UriPermission perm : perms.values()) {
8817                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8818                            result.add(perm.buildPersistedPublicApiObject());
8819                        }
8820                    }
8821                }
8822            }
8823        }
8824        return new ParceledListSlice<android.content.UriPermission>(result);
8825    }
8826
8827    @Override
8828    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8829            String packageName, int userId) {
8830        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8831                "getGrantedUriPermissions");
8832
8833        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8834        synchronized (this) {
8835            final int size = mGrantedUriPermissions.size();
8836            for (int i = 0; i < size; i++) {
8837                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8838                for (UriPermission perm : perms.values()) {
8839                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8840                            && perm.persistedModeFlags != 0) {
8841                        result.add(perm.buildPersistedPublicApiObject());
8842                    }
8843                }
8844            }
8845        }
8846        return new ParceledListSlice<android.content.UriPermission>(result);
8847    }
8848
8849    @Override
8850    public void clearGrantedUriPermissions(String packageName, int userId) {
8851        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8852                "clearGrantedUriPermissions");
8853        removeUriPermissionsForPackageLocked(packageName, userId, true);
8854    }
8855
8856    @Override
8857    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8858        synchronized (this) {
8859            ProcessRecord app =
8860                who != null ? getRecordForAppLocked(who) : null;
8861            if (app == null) return;
8862
8863            Message msg = Message.obtain();
8864            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8865            msg.obj = app;
8866            msg.arg1 = waiting ? 1 : 0;
8867            mUiHandler.sendMessage(msg);
8868        }
8869    }
8870
8871    @Override
8872    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8873        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8874        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8875        outInfo.availMem = Process.getFreeMemory();
8876        outInfo.totalMem = Process.getTotalMemory();
8877        outInfo.threshold = homeAppMem;
8878        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8879        outInfo.hiddenAppThreshold = cachedAppMem;
8880        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8881                ProcessList.SERVICE_ADJ);
8882        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8883                ProcessList.VISIBLE_APP_ADJ);
8884        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8885                ProcessList.FOREGROUND_APP_ADJ);
8886    }
8887
8888    // =========================================================
8889    // TASK MANAGEMENT
8890    // =========================================================
8891
8892    @Override
8893    public List<IAppTask> getAppTasks(String callingPackage) {
8894        int callingUid = Binder.getCallingUid();
8895        long ident = Binder.clearCallingIdentity();
8896
8897        synchronized(this) {
8898            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8899            try {
8900                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8901
8902                final int N = mRecentTasks.size();
8903                for (int i = 0; i < N; i++) {
8904                    TaskRecord tr = mRecentTasks.get(i);
8905                    // Skip tasks that do not match the caller.  We don't need to verify
8906                    // callingPackage, because we are also limiting to callingUid and know
8907                    // that will limit to the correct security sandbox.
8908                    if (tr.effectiveUid != callingUid) {
8909                        continue;
8910                    }
8911                    Intent intent = tr.getBaseIntent();
8912                    if (intent == null ||
8913                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8914                        continue;
8915                    }
8916                    ActivityManager.RecentTaskInfo taskInfo =
8917                            createRecentTaskInfoFromTaskRecord(tr);
8918                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8919                    list.add(taskImpl);
8920                }
8921            } finally {
8922                Binder.restoreCallingIdentity(ident);
8923            }
8924            return list;
8925        }
8926    }
8927
8928    @Override
8929    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8930        final int callingUid = Binder.getCallingUid();
8931        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8932
8933        synchronized(this) {
8934            if (DEBUG_ALL) Slog.v(
8935                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8936
8937            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8938                    callingUid);
8939
8940            // TODO: Improve with MRU list from all ActivityStacks.
8941            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8942        }
8943
8944        return list;
8945    }
8946
8947    /**
8948     * Creates a new RecentTaskInfo from a TaskRecord.
8949     */
8950    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8951        // Update the task description to reflect any changes in the task stack
8952        tr.updateTaskDescription();
8953
8954        // Compose the recent task info
8955        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8956        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8957        rti.persistentId = tr.taskId;
8958        rti.baseIntent = new Intent(tr.getBaseIntent());
8959        rti.origActivity = tr.origActivity;
8960        rti.realActivity = tr.realActivity;
8961        rti.description = tr.lastDescription;
8962        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8963        rti.userId = tr.userId;
8964        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8965        rti.firstActiveTime = tr.firstActiveTime;
8966        rti.lastActiveTime = tr.lastActiveTime;
8967        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8968        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8969        rti.numActivities = 0;
8970        if (tr.mBounds != null) {
8971            rti.bounds = new Rect(tr.mBounds);
8972        }
8973        rti.isDockable = tr.canGoInDockedStack();
8974        rti.resizeMode = tr.mResizeMode;
8975
8976        ActivityRecord base = null;
8977        ActivityRecord top = null;
8978        ActivityRecord tmp;
8979
8980        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8981            tmp = tr.mActivities.get(i);
8982            if (tmp.finishing) {
8983                continue;
8984            }
8985            base = tmp;
8986            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8987                top = base;
8988            }
8989            rti.numActivities++;
8990        }
8991
8992        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8993        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8994
8995        return rti;
8996    }
8997
8998    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8999        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9000                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9001        if (!allowed) {
9002            if (checkPermission(android.Manifest.permission.GET_TASKS,
9003                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9004                // Temporary compatibility: some existing apps on the system image may
9005                // still be requesting the old permission and not switched to the new
9006                // one; if so, we'll still allow them full access.  This means we need
9007                // to see if they are holding the old permission and are a system app.
9008                try {
9009                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9010                        allowed = true;
9011                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9012                                + " is using old GET_TASKS but privileged; allowing");
9013                    }
9014                } catch (RemoteException e) {
9015                }
9016            }
9017        }
9018        if (!allowed) {
9019            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9020                    + " does not hold REAL_GET_TASKS; limiting output");
9021        }
9022        return allowed;
9023    }
9024
9025    @Override
9026    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9027        final int callingUid = Binder.getCallingUid();
9028        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9029                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9030
9031        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9032        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9033        synchronized (this) {
9034            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9035                    callingUid);
9036            final boolean detailed = checkCallingPermission(
9037                    android.Manifest.permission.GET_DETAILED_TASKS)
9038                    == PackageManager.PERMISSION_GRANTED;
9039
9040            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9041                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9042                return Collections.emptyList();
9043            }
9044            mRecentTasks.loadUserRecentsLocked(userId);
9045
9046            final int recentsCount = mRecentTasks.size();
9047            ArrayList<ActivityManager.RecentTaskInfo> res =
9048                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9049
9050            final Set<Integer> includedUsers;
9051            if (includeProfiles) {
9052                includedUsers = mUserController.getProfileIds(userId);
9053            } else {
9054                includedUsers = new HashSet<>();
9055            }
9056            includedUsers.add(Integer.valueOf(userId));
9057
9058            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9059                TaskRecord tr = mRecentTasks.get(i);
9060                // Only add calling user or related users recent tasks
9061                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9062                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9063                    continue;
9064                }
9065
9066                if (tr.realActivitySuspended) {
9067                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9068                    continue;
9069                }
9070
9071                // Return the entry if desired by the caller.  We always return
9072                // the first entry, because callers always expect this to be the
9073                // foreground app.  We may filter others if the caller has
9074                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9075                // we should exclude the entry.
9076
9077                if (i == 0
9078                        || withExcluded
9079                        || (tr.intent == null)
9080                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9081                                == 0)) {
9082                    if (!allowed) {
9083                        // If the caller doesn't have the GET_TASKS permission, then only
9084                        // allow them to see a small subset of tasks -- their own and home.
9085                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9086                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9087                            continue;
9088                        }
9089                    }
9090                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9091                        if (tr.stack != null && tr.stack.isHomeStack()) {
9092                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9093                                    "Skipping, home stack task: " + tr);
9094                            continue;
9095                        }
9096                    }
9097                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9098                        final ActivityStack stack = tr.stack;
9099                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9100                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9101                                    "Skipping, top task in docked stack: " + tr);
9102                            continue;
9103                        }
9104                    }
9105                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9106                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9107                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9108                                    "Skipping, pinned stack task: " + tr);
9109                            continue;
9110                        }
9111                    }
9112                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9113                        // Don't include auto remove tasks that are finished or finishing.
9114                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9115                                "Skipping, auto-remove without activity: " + tr);
9116                        continue;
9117                    }
9118                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9119                            && !tr.isAvailable) {
9120                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9121                                "Skipping, unavail real act: " + tr);
9122                        continue;
9123                    }
9124
9125                    if (!tr.mUserSetupComplete) {
9126                        // Don't include task launched while user is not done setting-up.
9127                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9128                                "Skipping, user setup not complete: " + tr);
9129                        continue;
9130                    }
9131
9132                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9133                    if (!detailed) {
9134                        rti.baseIntent.replaceExtras((Bundle)null);
9135                    }
9136
9137                    res.add(rti);
9138                    maxNum--;
9139                }
9140            }
9141            return res;
9142        }
9143    }
9144
9145    @Override
9146    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9147        synchronized (this) {
9148            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9149                    "getTaskThumbnail()");
9150            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9151                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9152            if (tr != null) {
9153                return tr.getTaskThumbnailLocked();
9154            }
9155        }
9156        return null;
9157    }
9158
9159    @Override
9160    public int addAppTask(IBinder activityToken, Intent intent,
9161            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9162        final int callingUid = Binder.getCallingUid();
9163        final long callingIdent = Binder.clearCallingIdentity();
9164
9165        try {
9166            synchronized (this) {
9167                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9168                if (r == null) {
9169                    throw new IllegalArgumentException("Activity does not exist; token="
9170                            + activityToken);
9171                }
9172                ComponentName comp = intent.getComponent();
9173                if (comp == null) {
9174                    throw new IllegalArgumentException("Intent " + intent
9175                            + " must specify explicit component");
9176                }
9177                if (thumbnail.getWidth() != mThumbnailWidth
9178                        || thumbnail.getHeight() != mThumbnailHeight) {
9179                    throw new IllegalArgumentException("Bad thumbnail size: got "
9180                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9181                            + mThumbnailWidth + "x" + mThumbnailHeight);
9182                }
9183                if (intent.getSelector() != null) {
9184                    intent.setSelector(null);
9185                }
9186                if (intent.getSourceBounds() != null) {
9187                    intent.setSourceBounds(null);
9188                }
9189                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9190                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9191                        // The caller has added this as an auto-remove task...  that makes no
9192                        // sense, so turn off auto-remove.
9193                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9194                    }
9195                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9196                    // Must be a new task.
9197                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9198                }
9199                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9200                    mLastAddedTaskActivity = null;
9201                }
9202                ActivityInfo ainfo = mLastAddedTaskActivity;
9203                if (ainfo == null) {
9204                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9205                            comp, 0, UserHandle.getUserId(callingUid));
9206                    if (ainfo.applicationInfo.uid != callingUid) {
9207                        throw new SecurityException(
9208                                "Can't add task for another application: target uid="
9209                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9210                    }
9211                }
9212
9213                // Use the full screen as the context for the task thumbnail
9214                final Point displaySize = new Point();
9215                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9216                r.task.stack.getDisplaySize(displaySize);
9217                thumbnailInfo.taskWidth = displaySize.x;
9218                thumbnailInfo.taskHeight = displaySize.y;
9219                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9220
9221                TaskRecord task = new TaskRecord(this,
9222                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9223                        ainfo, intent, description, thumbnailInfo);
9224
9225                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9226                if (trimIdx >= 0) {
9227                    // If this would have caused a trim, then we'll abort because that
9228                    // means it would be added at the end of the list but then just removed.
9229                    return INVALID_TASK_ID;
9230                }
9231
9232                final int N = mRecentTasks.size();
9233                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9234                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9235                    tr.removedFromRecents();
9236                }
9237
9238                task.inRecents = true;
9239                mRecentTasks.add(task);
9240                r.task.stack.addTask(task, false, "addAppTask");
9241
9242                task.setLastThumbnailLocked(thumbnail);
9243                task.freeLastThumbnail();
9244
9245                return task.taskId;
9246            }
9247        } finally {
9248            Binder.restoreCallingIdentity(callingIdent);
9249        }
9250    }
9251
9252    @Override
9253    public Point getAppTaskThumbnailSize() {
9254        synchronized (this) {
9255            return new Point(mThumbnailWidth,  mThumbnailHeight);
9256        }
9257    }
9258
9259    @Override
9260    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9261        synchronized (this) {
9262            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9263            if (r != null) {
9264                r.setTaskDescription(td);
9265                r.task.updateTaskDescription();
9266            }
9267        }
9268    }
9269
9270    @Override
9271    public void setTaskResizeable(int taskId, int resizeableMode) {
9272        synchronized (this) {
9273            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9274                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9275            if (task == null) {
9276                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9277                return;
9278            }
9279            if (task.mResizeMode != resizeableMode) {
9280                task.mResizeMode = resizeableMode;
9281                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9282                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9283                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9284            }
9285        }
9286    }
9287
9288    @Override
9289    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9291        long ident = Binder.clearCallingIdentity();
9292        try {
9293            synchronized (this) {
9294                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9295                if (task == null) {
9296                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9297                    return;
9298                }
9299                int stackId = task.stack.mStackId;
9300                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9301                // in crop windows resize mode or if the task size is affected by the docked stack
9302                // changing size. No need to update configuration.
9303                if (bounds != null && task.inCropWindowsResizeMode()
9304                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9305                    mWindowManager.scrollTask(task.taskId, bounds);
9306                    return;
9307                }
9308
9309                // Place the task in the right stack if it isn't there already based on
9310                // the requested bounds.
9311                // The stack transition logic is:
9312                // - a null bounds on a freeform task moves that task to fullscreen
9313                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9314                //   that task to freeform
9315                // - otherwise the task is not moved
9316                if (!StackId.isTaskResizeAllowed(stackId)) {
9317                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9318                }
9319                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9320                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9321                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9322                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9323                }
9324                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9325                if (stackId != task.stack.mStackId) {
9326                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9327                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9328                    preserveWindow = false;
9329                }
9330
9331                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9332                        false /* deferResume */);
9333            }
9334        } finally {
9335            Binder.restoreCallingIdentity(ident);
9336        }
9337    }
9338
9339    @Override
9340    public Rect getTaskBounds(int taskId) {
9341        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9342        long ident = Binder.clearCallingIdentity();
9343        Rect rect = new Rect();
9344        try {
9345            synchronized (this) {
9346                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9347                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9348                if (task == null) {
9349                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9350                    return rect;
9351                }
9352                if (task.stack != null) {
9353                    // Return the bounds from window manager since it will be adjusted for various
9354                    // things like the presense of a docked stack for tasks that aren't resizeable.
9355                    mWindowManager.getTaskBounds(task.taskId, rect);
9356                } else {
9357                    // Task isn't in window manager yet since it isn't associated with a stack.
9358                    // Return the persist value from activity manager
9359                    if (task.mBounds != null) {
9360                        rect.set(task.mBounds);
9361                    } else if (task.mLastNonFullscreenBounds != null) {
9362                        rect.set(task.mLastNonFullscreenBounds);
9363                    }
9364                }
9365            }
9366        } finally {
9367            Binder.restoreCallingIdentity(ident);
9368        }
9369        return rect;
9370    }
9371
9372    @Override
9373    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9374        if (userId != UserHandle.getCallingUserId()) {
9375            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9376                    "getTaskDescriptionIcon");
9377        }
9378        final File passedIconFile = new File(filePath);
9379        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9380                passedIconFile.getName());
9381        if (!legitIconFile.getPath().equals(filePath)
9382                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9383            throw new IllegalArgumentException("Bad file path: " + filePath
9384                    + " passed for userId " + userId);
9385        }
9386        return mRecentTasks.getTaskDescriptionIcon(filePath);
9387    }
9388
9389    @Override
9390    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9391            throws RemoteException {
9392        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9393                opts.getCustomInPlaceResId() == 0) {
9394            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9395                    "with valid animation");
9396        }
9397        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9398        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9399                opts.getCustomInPlaceResId());
9400        mWindowManager.executeAppTransition();
9401    }
9402
9403    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9404            boolean removeFromRecents) {
9405        if (removeFromRecents) {
9406            mRecentTasks.remove(tr);
9407            tr.removedFromRecents();
9408        }
9409        ComponentName component = tr.getBaseIntent().getComponent();
9410        if (component == null) {
9411            Slog.w(TAG, "No component for base intent of task: " + tr);
9412            return;
9413        }
9414
9415        // Find any running services associated with this app and stop if needed.
9416        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9417
9418        if (!killProcess) {
9419            return;
9420        }
9421
9422        // Determine if the process(es) for this task should be killed.
9423        final String pkg = component.getPackageName();
9424        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9425        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9426        for (int i = 0; i < pmap.size(); i++) {
9427
9428            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9429            for (int j = 0; j < uids.size(); j++) {
9430                ProcessRecord proc = uids.valueAt(j);
9431                if (proc.userId != tr.userId) {
9432                    // Don't kill process for a different user.
9433                    continue;
9434                }
9435                if (proc == mHomeProcess) {
9436                    // Don't kill the home process along with tasks from the same package.
9437                    continue;
9438                }
9439                if (!proc.pkgList.containsKey(pkg)) {
9440                    // Don't kill process that is not associated with this task.
9441                    continue;
9442                }
9443
9444                for (int k = 0; k < proc.activities.size(); k++) {
9445                    TaskRecord otherTask = proc.activities.get(k).task;
9446                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9447                        // Don't kill process(es) that has an activity in a different task that is
9448                        // also in recents.
9449                        return;
9450                    }
9451                }
9452
9453                if (proc.foregroundServices) {
9454                    // Don't kill process(es) with foreground service.
9455                    return;
9456                }
9457
9458                // Add process to kill list.
9459                procsToKill.add(proc);
9460            }
9461        }
9462
9463        // Kill the running processes.
9464        for (int i = 0; i < procsToKill.size(); i++) {
9465            ProcessRecord pr = procsToKill.get(i);
9466            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9467                    && pr.curReceiver == null) {
9468                pr.kill("remove task", true);
9469            } else {
9470                // We delay killing processes that are not in the background or running a receiver.
9471                pr.waitingToKill = "remove task";
9472            }
9473        }
9474    }
9475
9476    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9477        // Remove all tasks with activities in the specified package from the list of recent tasks
9478        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9479            TaskRecord tr = mRecentTasks.get(i);
9480            if (tr.userId != userId) continue;
9481
9482            ComponentName cn = tr.intent.getComponent();
9483            if (cn != null && cn.getPackageName().equals(packageName)) {
9484                // If the package name matches, remove the task.
9485                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9486            }
9487        }
9488    }
9489
9490    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9491            int userId) {
9492
9493        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9494            TaskRecord tr = mRecentTasks.get(i);
9495            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9496                continue;
9497            }
9498
9499            ComponentName cn = tr.intent.getComponent();
9500            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9501                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9502            if (sameComponent) {
9503                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9504            }
9505        }
9506    }
9507
9508    /**
9509     * Removes the task with the specified task id.
9510     *
9511     * @param taskId Identifier of the task to be removed.
9512     * @param killProcess Kill any process associated with the task if possible.
9513     * @param removeFromRecents Whether to also remove the task from recents.
9514     * @return Returns true if the given task was found and removed.
9515     */
9516    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9517            boolean removeFromRecents) {
9518        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9519                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9520        if (tr != null) {
9521            tr.removeTaskActivitiesLocked();
9522            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9523            if (tr.isPersistable) {
9524                notifyTaskPersisterLocked(null, true);
9525            }
9526            return true;
9527        }
9528        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9529        return false;
9530    }
9531
9532    @Override
9533    public void removeStack(int stackId) {
9534        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9535        if (stackId == HOME_STACK_ID) {
9536            throw new IllegalArgumentException("Removing home stack is not allowed.");
9537        }
9538
9539        synchronized (this) {
9540            final long ident = Binder.clearCallingIdentity();
9541            try {
9542                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9543                if (stack == null) {
9544                    return;
9545                }
9546                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9547                for (int i = tasks.size() - 1; i >= 0; i--) {
9548                    removeTaskByIdLocked(
9549                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9550                }
9551            } finally {
9552                Binder.restoreCallingIdentity(ident);
9553            }
9554        }
9555    }
9556
9557    @Override
9558    public boolean removeTask(int taskId) {
9559        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9560        synchronized (this) {
9561            final long ident = Binder.clearCallingIdentity();
9562            try {
9563                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9564            } finally {
9565                Binder.restoreCallingIdentity(ident);
9566            }
9567        }
9568    }
9569
9570    /**
9571     * TODO: Add mController hook
9572     */
9573    @Override
9574    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9575        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9576
9577        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9578        synchronized(this) {
9579            moveTaskToFrontLocked(taskId, flags, bOptions);
9580        }
9581    }
9582
9583    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9584        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9585
9586        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9587                Binder.getCallingUid(), -1, -1, "Task to front")) {
9588            ActivityOptions.abort(options);
9589            return;
9590        }
9591        final long origId = Binder.clearCallingIdentity();
9592        try {
9593            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9594            if (task == null) {
9595                Slog.d(TAG, "Could not find task for id: "+ taskId);
9596                return;
9597            }
9598            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9599                mStackSupervisor.showLockTaskToast();
9600                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9601                return;
9602            }
9603            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9604            if (prev != null && prev.isRecentsActivity()) {
9605                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9606            }
9607            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9608                    false /* forceNonResizable */);
9609        } finally {
9610            Binder.restoreCallingIdentity(origId);
9611        }
9612        ActivityOptions.abort(options);
9613    }
9614
9615    /**
9616     * Moves an activity, and all of the other activities within the same task, to the bottom
9617     * of the history stack.  The activity's order within the task is unchanged.
9618     *
9619     * @param token A reference to the activity we wish to move
9620     * @param nonRoot If false then this only works if the activity is the root
9621     *                of a task; if true it will work for any activity in a task.
9622     * @return Returns true if the move completed, false if not.
9623     */
9624    @Override
9625    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9626        enforceNotIsolatedCaller("moveActivityTaskToBack");
9627        synchronized(this) {
9628            final long origId = Binder.clearCallingIdentity();
9629            try {
9630                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9631                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9632                if (task != null) {
9633                    if (mStackSupervisor.isLockedTask(task)) {
9634                        mStackSupervisor.showLockTaskToast();
9635                        return false;
9636                    }
9637                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9638                }
9639            } finally {
9640                Binder.restoreCallingIdentity(origId);
9641            }
9642        }
9643        return false;
9644    }
9645
9646    @Override
9647    public void moveTaskBackwards(int task) {
9648        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9649                "moveTaskBackwards()");
9650
9651        synchronized(this) {
9652            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9653                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9654                return;
9655            }
9656            final long origId = Binder.clearCallingIdentity();
9657            moveTaskBackwardsLocked(task);
9658            Binder.restoreCallingIdentity(origId);
9659        }
9660    }
9661
9662    private final void moveTaskBackwardsLocked(int task) {
9663        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9664    }
9665
9666    @Override
9667    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9668            IActivityContainerCallback callback) throws RemoteException {
9669        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9670        synchronized (this) {
9671            if (parentActivityToken == null) {
9672                throw new IllegalArgumentException("parent token must not be null");
9673            }
9674            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9675            if (r == null) {
9676                return null;
9677            }
9678            if (callback == null) {
9679                throw new IllegalArgumentException("callback must not be null");
9680            }
9681            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9682        }
9683    }
9684
9685    @Override
9686    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9687        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9688        synchronized (this) {
9689            mStackSupervisor.deleteActivityContainer(container);
9690        }
9691    }
9692
9693    @Override
9694    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9695        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9696        synchronized (this) {
9697            final int stackId = mStackSupervisor.getNextStackId();
9698            final ActivityStack stack =
9699                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9700            if (stack == null) {
9701                return null;
9702            }
9703            return stack.mActivityContainer;
9704        }
9705    }
9706
9707    @Override
9708    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9709        synchronized (this) {
9710            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9711            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9712                return stack.mActivityContainer.getDisplayId();
9713            }
9714            return Display.DEFAULT_DISPLAY;
9715        }
9716    }
9717
9718    @Override
9719    public int getActivityStackId(IBinder token) throws RemoteException {
9720        synchronized (this) {
9721            ActivityStack stack = ActivityRecord.getStackLocked(token);
9722            if (stack == null) {
9723                return INVALID_STACK_ID;
9724            }
9725            return stack.mStackId;
9726        }
9727    }
9728
9729    @Override
9730    public void exitFreeformMode(IBinder token) throws RemoteException {
9731        synchronized (this) {
9732            long ident = Binder.clearCallingIdentity();
9733            try {
9734                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9735                if (r == null) {
9736                    throw new IllegalArgumentException(
9737                            "exitFreeformMode: No activity record matching token=" + token);
9738                }
9739                final ActivityStack stack = r.getStackLocked(token);
9740                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9741                    throw new IllegalStateException(
9742                            "exitFreeformMode: You can only go fullscreen from freeform.");
9743                }
9744                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9745                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9746                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9747            } finally {
9748                Binder.restoreCallingIdentity(ident);
9749            }
9750        }
9751    }
9752
9753    @Override
9754    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9755        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9756        if (stackId == HOME_STACK_ID) {
9757            throw new IllegalArgumentException(
9758                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9759        }
9760        synchronized (this) {
9761            long ident = Binder.clearCallingIdentity();
9762            try {
9763                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9764                        + " to stackId=" + stackId + " toTop=" + toTop);
9765                if (stackId == DOCKED_STACK_ID) {
9766                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9767                            null /* initialBounds */);
9768                }
9769                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9770                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9771                if (result && stackId == DOCKED_STACK_ID) {
9772                    // If task moved to docked stack - show recents if needed.
9773                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9774                            "moveTaskToDockedStack");
9775                }
9776            } finally {
9777                Binder.restoreCallingIdentity(ident);
9778            }
9779        }
9780    }
9781
9782    @Override
9783    public void swapDockedAndFullscreenStack() throws RemoteException {
9784        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9785        synchronized (this) {
9786            long ident = Binder.clearCallingIdentity();
9787            try {
9788                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9789                        FULLSCREEN_WORKSPACE_STACK_ID);
9790                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9791                        : null;
9792                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9793                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9794                        : null;
9795                if (topTask == null || tasks == null || tasks.size() == 0) {
9796                    Slog.w(TAG,
9797                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9798                    return;
9799                }
9800
9801                // TODO: App transition
9802                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9803
9804                // Defer the resume so resume/pausing while moving stacks is dangerous.
9805                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9806                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9807                        ANIMATE, true /* deferResume */);
9808                final int size = tasks.size();
9809                for (int i = 0; i < size; i++) {
9810                    final int id = tasks.get(i).taskId;
9811                    if (id == topTask.taskId) {
9812                        continue;
9813                    }
9814                    mStackSupervisor.moveTaskToStackLocked(id,
9815                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9816                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9817                }
9818
9819                // Because we deferred the resume, to avoid conflicts with stack switches while
9820                // resuming, we need to do it after all the tasks are moved.
9821                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9822                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9823
9824                mWindowManager.executeAppTransition();
9825            } finally {
9826                Binder.restoreCallingIdentity(ident);
9827            }
9828        }
9829    }
9830
9831    /**
9832     * Moves the input task to the docked stack.
9833     *
9834     * @param taskId Id of task to move.
9835     * @param createMode The mode the docked stack should be created in if it doesn't exist
9836     *                   already. See
9837     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9838     *                   and
9839     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9840     * @param toTop If the task and stack should be moved to the top.
9841     * @param animate Whether we should play an animation for the moving the task
9842     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9843     *                      docked stack. Pass {@code null} to use default bounds.
9844     */
9845    @Override
9846    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9847            Rect initialBounds, boolean moveHomeStackFront) {
9848        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9849        synchronized (this) {
9850            long ident = Binder.clearCallingIdentity();
9851            try {
9852                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9853                        + " to createMode=" + createMode + " toTop=" + toTop);
9854                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9855                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9856                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9857                        animate, DEFER_RESUME);
9858                if (moved) {
9859                    if (moveHomeStackFront) {
9860                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9861                    }
9862                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9863                }
9864                return moved;
9865            } finally {
9866                Binder.restoreCallingIdentity(ident);
9867            }
9868        }
9869    }
9870
9871    /**
9872     * Moves the top activity in the input stackId to the pinned stack.
9873     *
9874     * @param stackId Id of stack to move the top activity to pinned stack.
9875     * @param bounds Bounds to use for pinned stack.
9876     *
9877     * @return True if the top activity of the input stack was successfully moved to the pinned
9878     *          stack.
9879     */
9880    @Override
9881    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9882        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9883        synchronized (this) {
9884            if (!mSupportsPictureInPicture) {
9885                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9886                        + "Device doesn't support picture-in-pciture mode");
9887            }
9888
9889            long ident = Binder.clearCallingIdentity();
9890            try {
9891                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9892            } finally {
9893                Binder.restoreCallingIdentity(ident);
9894            }
9895        }
9896    }
9897
9898    @Override
9899    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9900            boolean preserveWindows, boolean animate, int animationDuration) {
9901        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9902        long ident = Binder.clearCallingIdentity();
9903        try {
9904            synchronized (this) {
9905                if (animate) {
9906                    if (stackId == PINNED_STACK_ID) {
9907                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9908                    } else {
9909                        throw new IllegalArgumentException("Stack: " + stackId
9910                                + " doesn't support animated resize.");
9911                    }
9912                } else {
9913                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9914                            null /* tempTaskInsetBounds */, preserveWindows,
9915                            allowResizeInDockedMode, !DEFER_RESUME);
9916                }
9917            }
9918        } finally {
9919            Binder.restoreCallingIdentity(ident);
9920        }
9921    }
9922
9923    @Override
9924    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9925            Rect tempDockedTaskInsetBounds,
9926            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9927        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9928                "resizeDockedStack()");
9929        long ident = Binder.clearCallingIdentity();
9930        try {
9931            synchronized (this) {
9932                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9933                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9934                        PRESERVE_WINDOWS);
9935            }
9936        } finally {
9937            Binder.restoreCallingIdentity(ident);
9938        }
9939    }
9940
9941    @Override
9942    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9943        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9944                "resizePinnedStack()");
9945        final long ident = Binder.clearCallingIdentity();
9946        try {
9947            synchronized (this) {
9948                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9949            }
9950        } finally {
9951            Binder.restoreCallingIdentity(ident);
9952        }
9953    }
9954
9955    @Override
9956    public void positionTaskInStack(int taskId, int stackId, int position) {
9957        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9958        if (stackId == HOME_STACK_ID) {
9959            throw new IllegalArgumentException(
9960                    "positionTaskInStack: Attempt to change the position of task "
9961                    + taskId + " in/to home stack");
9962        }
9963        synchronized (this) {
9964            long ident = Binder.clearCallingIdentity();
9965            try {
9966                if (DEBUG_STACK) Slog.d(TAG_STACK,
9967                        "positionTaskInStack: positioning task=" + taskId
9968                        + " in stackId=" + stackId + " at position=" + position);
9969                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9970            } finally {
9971                Binder.restoreCallingIdentity(ident);
9972            }
9973        }
9974    }
9975
9976    @Override
9977    public List<StackInfo> getAllStackInfos() {
9978        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9979        long ident = Binder.clearCallingIdentity();
9980        try {
9981            synchronized (this) {
9982                return mStackSupervisor.getAllStackInfosLocked();
9983            }
9984        } finally {
9985            Binder.restoreCallingIdentity(ident);
9986        }
9987    }
9988
9989    @Override
9990    public StackInfo getStackInfo(int stackId) {
9991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9992        long ident = Binder.clearCallingIdentity();
9993        try {
9994            synchronized (this) {
9995                return mStackSupervisor.getStackInfoLocked(stackId);
9996            }
9997        } finally {
9998            Binder.restoreCallingIdentity(ident);
9999        }
10000    }
10001
10002    @Override
10003    public boolean isInHomeStack(int taskId) {
10004        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10005        long ident = Binder.clearCallingIdentity();
10006        try {
10007            synchronized (this) {
10008                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10009                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10010                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10011            }
10012        } finally {
10013            Binder.restoreCallingIdentity(ident);
10014        }
10015    }
10016
10017    @Override
10018    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10019        synchronized(this) {
10020            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10021        }
10022    }
10023
10024    @Override
10025    public void updateDeviceOwner(String packageName) {
10026        final int callingUid = Binder.getCallingUid();
10027        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10028            throw new SecurityException("updateDeviceOwner called from non-system process");
10029        }
10030        synchronized (this) {
10031            mDeviceOwnerName = packageName;
10032        }
10033    }
10034
10035    @Override
10036    public void updateLockTaskPackages(int userId, String[] packages) {
10037        final int callingUid = Binder.getCallingUid();
10038        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10039            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10040                    "updateLockTaskPackages()");
10041        }
10042        synchronized (this) {
10043            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10044                    Arrays.toString(packages));
10045            mLockTaskPackages.put(userId, packages);
10046            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10047        }
10048    }
10049
10050
10051    void startLockTaskModeLocked(TaskRecord task) {
10052        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10053        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10054            return;
10055        }
10056
10057        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10058        // is initiated by system after the pinning request was shown and locked mode is initiated
10059        // by an authorized app directly
10060        final int callingUid = Binder.getCallingUid();
10061        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10062        long ident = Binder.clearCallingIdentity();
10063        try {
10064            if (!isSystemInitiated) {
10065                task.mLockTaskUid = callingUid;
10066                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10067                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10068                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10069                    StatusBarManagerInternal statusBarManager =
10070                            LocalServices.getService(StatusBarManagerInternal.class);
10071                    if (statusBarManager != null) {
10072                        statusBarManager.showScreenPinningRequest(task.taskId);
10073                    }
10074                    return;
10075                }
10076
10077                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10078                if (stack == null || task != stack.topTask()) {
10079                    throw new IllegalArgumentException("Invalid task, not in foreground");
10080                }
10081            }
10082            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10083                    "Locking fully");
10084            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10085                    ActivityManager.LOCK_TASK_MODE_PINNED :
10086                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10087                    "startLockTask", true);
10088        } finally {
10089            Binder.restoreCallingIdentity(ident);
10090        }
10091    }
10092
10093    @Override
10094    public void startLockTaskMode(int taskId) {
10095        synchronized (this) {
10096            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10097            if (task != null) {
10098                startLockTaskModeLocked(task);
10099            }
10100        }
10101    }
10102
10103    @Override
10104    public void startLockTaskMode(IBinder token) {
10105        synchronized (this) {
10106            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10107            if (r == null) {
10108                return;
10109            }
10110            final TaskRecord task = r.task;
10111            if (task != null) {
10112                startLockTaskModeLocked(task);
10113            }
10114        }
10115    }
10116
10117    @Override
10118    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10119        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10120        // This makes inner call to look as if it was initiated by system.
10121        long ident = Binder.clearCallingIdentity();
10122        try {
10123            synchronized (this) {
10124                startLockTaskMode(taskId);
10125            }
10126        } finally {
10127            Binder.restoreCallingIdentity(ident);
10128        }
10129    }
10130
10131    @Override
10132    public void stopLockTaskMode() {
10133        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10134        if (lockTask == null) {
10135            // Our work here is done.
10136            return;
10137        }
10138
10139        final int callingUid = Binder.getCallingUid();
10140        final int lockTaskUid = lockTask.mLockTaskUid;
10141        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10142        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10143            // Done.
10144            return;
10145        } else {
10146            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10147            // It is possible lockTaskMode was started by the system process because
10148            // android:lockTaskMode is set to a locking value in the application manifest
10149            // instead of the app calling startLockTaskMode. In this case
10150            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10151            // {@link TaskRecord.effectiveUid} instead. Also caller with
10152            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10153            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10154                    && callingUid != lockTaskUid
10155                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10156                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10157                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10158            }
10159        }
10160        long ident = Binder.clearCallingIdentity();
10161        try {
10162            Log.d(TAG, "stopLockTaskMode");
10163            // Stop lock task
10164            synchronized (this) {
10165                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10166                        "stopLockTask", true);
10167            }
10168        } finally {
10169            Binder.restoreCallingIdentity(ident);
10170        }
10171    }
10172
10173    /**
10174     * This API should be called by SystemUI only when user perform certain action to dismiss
10175     * lock task mode. We should only dismiss pinned lock task mode in this case.
10176     */
10177    @Override
10178    public void stopSystemLockTaskMode() throws RemoteException {
10179        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10180            stopLockTaskMode();
10181        } else {
10182            mStackSupervisor.showLockTaskToast();
10183        }
10184    }
10185
10186    @Override
10187    public boolean isInLockTaskMode() {
10188        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10189    }
10190
10191    @Override
10192    public int getLockTaskModeState() {
10193        synchronized (this) {
10194            return mStackSupervisor.getLockTaskModeState();
10195        }
10196    }
10197
10198    @Override
10199    public void showLockTaskEscapeMessage(IBinder token) {
10200        synchronized (this) {
10201            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10202            if (r == null) {
10203                return;
10204            }
10205            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10206        }
10207    }
10208
10209    // =========================================================
10210    // CONTENT PROVIDERS
10211    // =========================================================
10212
10213    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10214        List<ProviderInfo> providers = null;
10215        try {
10216            providers = AppGlobals.getPackageManager()
10217                    .queryContentProviders(app.processName, app.uid,
10218                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10219                                    | MATCH_DEBUG_TRIAGED_MISSING)
10220                    .getList();
10221        } catch (RemoteException ex) {
10222        }
10223        if (DEBUG_MU) Slog.v(TAG_MU,
10224                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10225        int userId = app.userId;
10226        if (providers != null) {
10227            int N = providers.size();
10228            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10229            for (int i=0; i<N; i++) {
10230                // TODO: keep logic in sync with installEncryptionUnawareProviders
10231                ProviderInfo cpi =
10232                    (ProviderInfo)providers.get(i);
10233                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10234                        cpi.name, cpi.flags);
10235                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10236                    // This is a singleton provider, but a user besides the
10237                    // default user is asking to initialize a process it runs
10238                    // in...  well, no, it doesn't actually run in this process,
10239                    // it runs in the process of the default user.  Get rid of it.
10240                    providers.remove(i);
10241                    N--;
10242                    i--;
10243                    continue;
10244                }
10245
10246                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10247                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10248                if (cpr == null) {
10249                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10250                    mProviderMap.putProviderByClass(comp, cpr);
10251                }
10252                if (DEBUG_MU) Slog.v(TAG_MU,
10253                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10254                app.pubProviders.put(cpi.name, cpr);
10255                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10256                    // Don't add this if it is a platform component that is marked
10257                    // to run in multiple processes, because this is actually
10258                    // part of the framework so doesn't make sense to track as a
10259                    // separate apk in the process.
10260                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10261                            mProcessStats);
10262                }
10263                notifyPackageUse(cpi.applicationInfo.packageName,
10264                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10265            }
10266        }
10267        return providers;
10268    }
10269
10270    /**
10271     * Check if {@link ProcessRecord} has a possible chance at accessing the
10272     * given {@link ProviderInfo}. Final permission checking is always done
10273     * in {@link ContentProvider}.
10274     */
10275    private final String checkContentProviderPermissionLocked(
10276            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10277        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10278        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10279        boolean checkedGrants = false;
10280        if (checkUser) {
10281            // Looking for cross-user grants before enforcing the typical cross-users permissions
10282            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10283            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10284                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10285                    return null;
10286                }
10287                checkedGrants = true;
10288            }
10289            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10290                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10291            if (userId != tmpTargetUserId) {
10292                // When we actually went to determine the final targer user ID, this ended
10293                // up different than our initial check for the authority.  This is because
10294                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10295                // SELF.  So we need to re-check the grants again.
10296                checkedGrants = false;
10297            }
10298        }
10299        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10300                cpi.applicationInfo.uid, cpi.exported)
10301                == PackageManager.PERMISSION_GRANTED) {
10302            return null;
10303        }
10304        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10305                cpi.applicationInfo.uid, cpi.exported)
10306                == PackageManager.PERMISSION_GRANTED) {
10307            return null;
10308        }
10309
10310        PathPermission[] pps = cpi.pathPermissions;
10311        if (pps != null) {
10312            int i = pps.length;
10313            while (i > 0) {
10314                i--;
10315                PathPermission pp = pps[i];
10316                String pprperm = pp.getReadPermission();
10317                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10318                        cpi.applicationInfo.uid, cpi.exported)
10319                        == PackageManager.PERMISSION_GRANTED) {
10320                    return null;
10321                }
10322                String ppwperm = pp.getWritePermission();
10323                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10324                        cpi.applicationInfo.uid, cpi.exported)
10325                        == PackageManager.PERMISSION_GRANTED) {
10326                    return null;
10327                }
10328            }
10329        }
10330        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10331            return null;
10332        }
10333
10334        String msg;
10335        if (!cpi.exported) {
10336            msg = "Permission Denial: opening provider " + cpi.name
10337                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10338                    + ", uid=" + callingUid + ") that is not exported from uid "
10339                    + cpi.applicationInfo.uid;
10340        } else {
10341            msg = "Permission Denial: opening provider " + cpi.name
10342                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10343                    + ", uid=" + callingUid + ") requires "
10344                    + cpi.readPermission + " or " + cpi.writePermission;
10345        }
10346        Slog.w(TAG, msg);
10347        return msg;
10348    }
10349
10350    /**
10351     * Returns if the ContentProvider has granted a uri to callingUid
10352     */
10353    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10354        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10355        if (perms != null) {
10356            for (int i=perms.size()-1; i>=0; i--) {
10357                GrantUri grantUri = perms.keyAt(i);
10358                if (grantUri.sourceUserId == userId || !checkUser) {
10359                    if (matchesProvider(grantUri.uri, cpi)) {
10360                        return true;
10361                    }
10362                }
10363            }
10364        }
10365        return false;
10366    }
10367
10368    /**
10369     * Returns true if the uri authority is one of the authorities specified in the provider.
10370     */
10371    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10372        String uriAuth = uri.getAuthority();
10373        String cpiAuth = cpi.authority;
10374        if (cpiAuth.indexOf(';') == -1) {
10375            return cpiAuth.equals(uriAuth);
10376        }
10377        String[] cpiAuths = cpiAuth.split(";");
10378        int length = cpiAuths.length;
10379        for (int i = 0; i < length; i++) {
10380            if (cpiAuths[i].equals(uriAuth)) return true;
10381        }
10382        return false;
10383    }
10384
10385    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10386            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10387        if (r != null) {
10388            for (int i=0; i<r.conProviders.size(); i++) {
10389                ContentProviderConnection conn = r.conProviders.get(i);
10390                if (conn.provider == cpr) {
10391                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10392                            "Adding provider requested by "
10393                            + r.processName + " from process "
10394                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10395                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10396                    if (stable) {
10397                        conn.stableCount++;
10398                        conn.numStableIncs++;
10399                    } else {
10400                        conn.unstableCount++;
10401                        conn.numUnstableIncs++;
10402                    }
10403                    return conn;
10404                }
10405            }
10406            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10407            if (stable) {
10408                conn.stableCount = 1;
10409                conn.numStableIncs = 1;
10410            } else {
10411                conn.unstableCount = 1;
10412                conn.numUnstableIncs = 1;
10413            }
10414            cpr.connections.add(conn);
10415            r.conProviders.add(conn);
10416            startAssociationLocked(r.uid, r.processName, r.curProcState,
10417                    cpr.uid, cpr.name, cpr.info.processName);
10418            return conn;
10419        }
10420        cpr.addExternalProcessHandleLocked(externalProcessToken);
10421        return null;
10422    }
10423
10424    boolean decProviderCountLocked(ContentProviderConnection conn,
10425            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10426        if (conn != null) {
10427            cpr = conn.provider;
10428            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10429                    "Removing provider requested by "
10430                    + conn.client.processName + " from process "
10431                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10432                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10433            if (stable) {
10434                conn.stableCount--;
10435            } else {
10436                conn.unstableCount--;
10437            }
10438            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10439                cpr.connections.remove(conn);
10440                conn.client.conProviders.remove(conn);
10441                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10442                    // The client is more important than last activity -- note the time this
10443                    // is happening, so we keep the old provider process around a bit as last
10444                    // activity to avoid thrashing it.
10445                    if (cpr.proc != null) {
10446                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10447                    }
10448                }
10449                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10450                return true;
10451            }
10452            return false;
10453        }
10454        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10455        return false;
10456    }
10457
10458    private void checkTime(long startTime, String where) {
10459        long now = SystemClock.uptimeMillis();
10460        if ((now-startTime) > 50) {
10461            // If we are taking more than 50ms, log about it.
10462            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10463        }
10464    }
10465
10466    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10467            String name, IBinder token, boolean stable, int userId) {
10468        ContentProviderRecord cpr;
10469        ContentProviderConnection conn = null;
10470        ProviderInfo cpi = null;
10471
10472        synchronized(this) {
10473            long startTime = SystemClock.uptimeMillis();
10474
10475            ProcessRecord r = null;
10476            if (caller != null) {
10477                r = getRecordForAppLocked(caller);
10478                if (r == null) {
10479                    throw new SecurityException(
10480                            "Unable to find app for caller " + caller
10481                          + " (pid=" + Binder.getCallingPid()
10482                          + ") when getting content provider " + name);
10483                }
10484            }
10485
10486            boolean checkCrossUser = true;
10487
10488            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10489
10490            // First check if this content provider has been published...
10491            cpr = mProviderMap.getProviderByName(name, userId);
10492            // If that didn't work, check if it exists for user 0 and then
10493            // verify that it's a singleton provider before using it.
10494            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10495                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10496                if (cpr != null) {
10497                    cpi = cpr.info;
10498                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10499                            cpi.name, cpi.flags)
10500                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10501                        userId = UserHandle.USER_SYSTEM;
10502                        checkCrossUser = false;
10503                    } else {
10504                        cpr = null;
10505                        cpi = null;
10506                    }
10507                }
10508            }
10509
10510            boolean providerRunning = cpr != null;
10511            if (providerRunning) {
10512                cpi = cpr.info;
10513                String msg;
10514                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10515                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10516                        != null) {
10517                    throw new SecurityException(msg);
10518                }
10519                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10520
10521                if (r != null && cpr.canRunHere(r)) {
10522                    // This provider has been published or is in the process
10523                    // of being published...  but it is also allowed to run
10524                    // in the caller's process, so don't make a connection
10525                    // and just let the caller instantiate its own instance.
10526                    ContentProviderHolder holder = cpr.newHolder(null);
10527                    // don't give caller the provider object, it needs
10528                    // to make its own.
10529                    holder.provider = null;
10530                    return holder;
10531                }
10532
10533                final long origId = Binder.clearCallingIdentity();
10534
10535                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10536
10537                // In this case the provider instance already exists, so we can
10538                // return it right away.
10539                conn = incProviderCountLocked(r, cpr, token, stable);
10540                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10541                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10542                        // If this is a perceptible app accessing the provider,
10543                        // make sure to count it as being accessed and thus
10544                        // back up on the LRU list.  This is good because
10545                        // content providers are often expensive to start.
10546                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10547                        updateLruProcessLocked(cpr.proc, false, null);
10548                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10549                    }
10550                }
10551
10552                if (cpr.proc != null) {
10553                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10554                    boolean success = updateOomAdjLocked(cpr.proc);
10555                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10556                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10557                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10558                    // NOTE: there is still a race here where a signal could be
10559                    // pending on the process even though we managed to update its
10560                    // adj level.  Not sure what to do about this, but at least
10561                    // the race is now smaller.
10562                    if (!success) {
10563                        // Uh oh...  it looks like the provider's process
10564                        // has been killed on us.  We need to wait for a new
10565                        // process to be started, and make sure its death
10566                        // doesn't kill our process.
10567                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10568                                + " is crashing; detaching " + r);
10569                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10570                        checkTime(startTime, "getContentProviderImpl: before appDied");
10571                        appDiedLocked(cpr.proc);
10572                        checkTime(startTime, "getContentProviderImpl: after appDied");
10573                        if (!lastRef) {
10574                            // This wasn't the last ref our process had on
10575                            // the provider...  we have now been killed, bail.
10576                            return null;
10577                        }
10578                        providerRunning = false;
10579                        conn = null;
10580                    }
10581                }
10582
10583                Binder.restoreCallingIdentity(origId);
10584            }
10585
10586            if (!providerRunning) {
10587                try {
10588                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10589                    cpi = AppGlobals.getPackageManager().
10590                        resolveContentProvider(name,
10591                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10592                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10593                } catch (RemoteException ex) {
10594                }
10595                if (cpi == null) {
10596                    return null;
10597                }
10598                // If the provider is a singleton AND
10599                // (it's a call within the same user || the provider is a
10600                // privileged app)
10601                // Then allow connecting to the singleton provider
10602                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10603                        cpi.name, cpi.flags)
10604                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10605                if (singleton) {
10606                    userId = UserHandle.USER_SYSTEM;
10607                }
10608                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10609                checkTime(startTime, "getContentProviderImpl: got app info for user");
10610
10611                String msg;
10612                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10613                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10614                        != null) {
10615                    throw new SecurityException(msg);
10616                }
10617                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10618
10619                if (!mProcessesReady
10620                        && !cpi.processName.equals("system")) {
10621                    // If this content provider does not run in the system
10622                    // process, and the system is not yet ready to run other
10623                    // processes, then fail fast instead of hanging.
10624                    throw new IllegalArgumentException(
10625                            "Attempt to launch content provider before system ready");
10626                }
10627
10628                // Make sure that the user who owns this provider is running.  If not,
10629                // we don't want to allow it to run.
10630                if (!mUserController.isUserRunningLocked(userId, 0)) {
10631                    Slog.w(TAG, "Unable to launch app "
10632                            + cpi.applicationInfo.packageName + "/"
10633                            + cpi.applicationInfo.uid + " for provider "
10634                            + name + ": user " + userId + " is stopped");
10635                    return null;
10636                }
10637
10638                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10639                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10640                cpr = mProviderMap.getProviderByClass(comp, userId);
10641                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10642                final boolean firstClass = cpr == null;
10643                if (firstClass) {
10644                    final long ident = Binder.clearCallingIdentity();
10645
10646                    // If permissions need a review before any of the app components can run,
10647                    // we return no provider and launch a review activity if the calling app
10648                    // is in the foreground.
10649                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10650                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10651                            return null;
10652                        }
10653                    }
10654
10655                    try {
10656                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10657                        ApplicationInfo ai =
10658                            AppGlobals.getPackageManager().
10659                                getApplicationInfo(
10660                                        cpi.applicationInfo.packageName,
10661                                        STOCK_PM_FLAGS, userId);
10662                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10663                        if (ai == null) {
10664                            Slog.w(TAG, "No package info for content provider "
10665                                    + cpi.name);
10666                            return null;
10667                        }
10668                        ai = getAppInfoForUser(ai, userId);
10669                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10670                    } catch (RemoteException ex) {
10671                        // pm is in same process, this will never happen.
10672                    } finally {
10673                        Binder.restoreCallingIdentity(ident);
10674                    }
10675                }
10676
10677                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10678
10679                if (r != null && cpr.canRunHere(r)) {
10680                    // If this is a multiprocess provider, then just return its
10681                    // info and allow the caller to instantiate it.  Only do
10682                    // this if the provider is the same user as the caller's
10683                    // process, or can run as root (so can be in any process).
10684                    return cpr.newHolder(null);
10685                }
10686
10687                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10688                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10689                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10690
10691                // This is single process, and our app is now connecting to it.
10692                // See if we are already in the process of launching this
10693                // provider.
10694                final int N = mLaunchingProviders.size();
10695                int i;
10696                for (i = 0; i < N; i++) {
10697                    if (mLaunchingProviders.get(i) == cpr) {
10698                        break;
10699                    }
10700                }
10701
10702                // If the provider is not already being launched, then get it
10703                // started.
10704                if (i >= N) {
10705                    final long origId = Binder.clearCallingIdentity();
10706
10707                    try {
10708                        // Content provider is now in use, its package can't be stopped.
10709                        try {
10710                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10711                            AppGlobals.getPackageManager().setPackageStoppedState(
10712                                    cpr.appInfo.packageName, false, userId);
10713                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10714                        } catch (RemoteException e) {
10715                        } catch (IllegalArgumentException e) {
10716                            Slog.w(TAG, "Failed trying to unstop package "
10717                                    + cpr.appInfo.packageName + ": " + e);
10718                        }
10719
10720                        // Use existing process if already started
10721                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10722                        ProcessRecord proc = getProcessRecordLocked(
10723                                cpi.processName, cpr.appInfo.uid, false);
10724                        if (proc != null && proc.thread != null) {
10725                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10726                                    "Installing in existing process " + proc);
10727                            if (!proc.pubProviders.containsKey(cpi.name)) {
10728                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10729                                proc.pubProviders.put(cpi.name, cpr);
10730                                try {
10731                                    proc.thread.scheduleInstallProvider(cpi);
10732                                } catch (RemoteException e) {
10733                                }
10734                            }
10735                        } else {
10736                            checkTime(startTime, "getContentProviderImpl: before start process");
10737                            proc = startProcessLocked(cpi.processName,
10738                                    cpr.appInfo, false, 0, "content provider",
10739                                    new ComponentName(cpi.applicationInfo.packageName,
10740                                            cpi.name), false, false, false);
10741                            checkTime(startTime, "getContentProviderImpl: after start process");
10742                            if (proc == null) {
10743                                Slog.w(TAG, "Unable to launch app "
10744                                        + cpi.applicationInfo.packageName + "/"
10745                                        + cpi.applicationInfo.uid + " for provider "
10746                                        + name + ": process is bad");
10747                                return null;
10748                            }
10749                        }
10750                        cpr.launchingApp = proc;
10751                        mLaunchingProviders.add(cpr);
10752                    } finally {
10753                        Binder.restoreCallingIdentity(origId);
10754                    }
10755                }
10756
10757                checkTime(startTime, "getContentProviderImpl: updating data structures");
10758
10759                // Make sure the provider is published (the same provider class
10760                // may be published under multiple names).
10761                if (firstClass) {
10762                    mProviderMap.putProviderByClass(comp, cpr);
10763                }
10764
10765                mProviderMap.putProviderByName(name, cpr);
10766                conn = incProviderCountLocked(r, cpr, token, stable);
10767                if (conn != null) {
10768                    conn.waiting = true;
10769                }
10770            }
10771            checkTime(startTime, "getContentProviderImpl: done!");
10772        }
10773
10774        // Wait for the provider to be published...
10775        synchronized (cpr) {
10776            while (cpr.provider == null) {
10777                if (cpr.launchingApp == null) {
10778                    Slog.w(TAG, "Unable to launch app "
10779                            + cpi.applicationInfo.packageName + "/"
10780                            + cpi.applicationInfo.uid + " for provider "
10781                            + name + ": launching app became null");
10782                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10783                            UserHandle.getUserId(cpi.applicationInfo.uid),
10784                            cpi.applicationInfo.packageName,
10785                            cpi.applicationInfo.uid, name);
10786                    return null;
10787                }
10788                try {
10789                    if (DEBUG_MU) Slog.v(TAG_MU,
10790                            "Waiting to start provider " + cpr
10791                            + " launchingApp=" + cpr.launchingApp);
10792                    if (conn != null) {
10793                        conn.waiting = true;
10794                    }
10795                    cpr.wait();
10796                } catch (InterruptedException ex) {
10797                } finally {
10798                    if (conn != null) {
10799                        conn.waiting = false;
10800                    }
10801                }
10802            }
10803        }
10804        return cpr != null ? cpr.newHolder(conn) : null;
10805    }
10806
10807    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10808            ProcessRecord r, final int userId) {
10809        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10810                cpi.packageName, userId)) {
10811
10812            final boolean callerForeground = r == null || r.setSchedGroup
10813                    != ProcessList.SCHED_GROUP_BACKGROUND;
10814
10815            // Show a permission review UI only for starting from a foreground app
10816            if (!callerForeground) {
10817                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10818                        + cpi.packageName + " requires a permissions review");
10819                return false;
10820            }
10821
10822            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10823            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10824                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10825            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10826
10827            if (DEBUG_PERMISSIONS_REVIEW) {
10828                Slog.i(TAG, "u" + userId + " Launching permission review "
10829                        + "for package " + cpi.packageName);
10830            }
10831
10832            final UserHandle userHandle = new UserHandle(userId);
10833            mHandler.post(new Runnable() {
10834                @Override
10835                public void run() {
10836                    mContext.startActivityAsUser(intent, userHandle);
10837                }
10838            });
10839
10840            return false;
10841        }
10842
10843        return true;
10844    }
10845
10846    PackageManagerInternal getPackageManagerInternalLocked() {
10847        if (mPackageManagerInt == null) {
10848            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10849        }
10850        return mPackageManagerInt;
10851    }
10852
10853    @Override
10854    public final ContentProviderHolder getContentProvider(
10855            IApplicationThread caller, String name, int userId, boolean stable) {
10856        enforceNotIsolatedCaller("getContentProvider");
10857        if (caller == null) {
10858            String msg = "null IApplicationThread when getting content provider "
10859                    + name;
10860            Slog.w(TAG, msg);
10861            throw new SecurityException(msg);
10862        }
10863        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10864        // with cross-user grant.
10865        return getContentProviderImpl(caller, name, null, stable, userId);
10866    }
10867
10868    public ContentProviderHolder getContentProviderExternal(
10869            String name, int userId, IBinder token) {
10870        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10871            "Do not have permission in call getContentProviderExternal()");
10872        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10873                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10874        return getContentProviderExternalUnchecked(name, token, userId);
10875    }
10876
10877    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10878            IBinder token, int userId) {
10879        return getContentProviderImpl(null, name, token, true, userId);
10880    }
10881
10882    /**
10883     * Drop a content provider from a ProcessRecord's bookkeeping
10884     */
10885    public void removeContentProvider(IBinder connection, boolean stable) {
10886        enforceNotIsolatedCaller("removeContentProvider");
10887        long ident = Binder.clearCallingIdentity();
10888        try {
10889            synchronized (this) {
10890                ContentProviderConnection conn;
10891                try {
10892                    conn = (ContentProviderConnection)connection;
10893                } catch (ClassCastException e) {
10894                    String msg ="removeContentProvider: " + connection
10895                            + " not a ContentProviderConnection";
10896                    Slog.w(TAG, msg);
10897                    throw new IllegalArgumentException(msg);
10898                }
10899                if (conn == null) {
10900                    throw new NullPointerException("connection is null");
10901                }
10902                if (decProviderCountLocked(conn, null, null, stable)) {
10903                    updateOomAdjLocked();
10904                }
10905            }
10906        } finally {
10907            Binder.restoreCallingIdentity(ident);
10908        }
10909    }
10910
10911    public void removeContentProviderExternal(String name, IBinder token) {
10912        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10913            "Do not have permission in call removeContentProviderExternal()");
10914        int userId = UserHandle.getCallingUserId();
10915        long ident = Binder.clearCallingIdentity();
10916        try {
10917            removeContentProviderExternalUnchecked(name, token, userId);
10918        } finally {
10919            Binder.restoreCallingIdentity(ident);
10920        }
10921    }
10922
10923    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10924        synchronized (this) {
10925            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10926            if(cpr == null) {
10927                //remove from mProvidersByClass
10928                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10929                return;
10930            }
10931
10932            //update content provider record entry info
10933            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10934            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10935            if (localCpr.hasExternalProcessHandles()) {
10936                if (localCpr.removeExternalProcessHandleLocked(token)) {
10937                    updateOomAdjLocked();
10938                } else {
10939                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10940                            + " with no external reference for token: "
10941                            + token + ".");
10942                }
10943            } else {
10944                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10945                        + " with no external references.");
10946            }
10947        }
10948    }
10949
10950    public final void publishContentProviders(IApplicationThread caller,
10951            List<ContentProviderHolder> providers) {
10952        if (providers == null) {
10953            return;
10954        }
10955
10956        enforceNotIsolatedCaller("publishContentProviders");
10957        synchronized (this) {
10958            final ProcessRecord r = getRecordForAppLocked(caller);
10959            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10960            if (r == null) {
10961                throw new SecurityException(
10962                        "Unable to find app for caller " + caller
10963                      + " (pid=" + Binder.getCallingPid()
10964                      + ") when publishing content providers");
10965            }
10966
10967            final long origId = Binder.clearCallingIdentity();
10968
10969            final int N = providers.size();
10970            for (int i = 0; i < N; i++) {
10971                ContentProviderHolder src = providers.get(i);
10972                if (src == null || src.info == null || src.provider == null) {
10973                    continue;
10974                }
10975                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10976                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10977                if (dst != null) {
10978                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10979                    mProviderMap.putProviderByClass(comp, dst);
10980                    String names[] = dst.info.authority.split(";");
10981                    for (int j = 0; j < names.length; j++) {
10982                        mProviderMap.putProviderByName(names[j], dst);
10983                    }
10984
10985                    int launchingCount = mLaunchingProviders.size();
10986                    int j;
10987                    boolean wasInLaunchingProviders = false;
10988                    for (j = 0; j < launchingCount; j++) {
10989                        if (mLaunchingProviders.get(j) == dst) {
10990                            mLaunchingProviders.remove(j);
10991                            wasInLaunchingProviders = true;
10992                            j--;
10993                            launchingCount--;
10994                        }
10995                    }
10996                    if (wasInLaunchingProviders) {
10997                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10998                    }
10999                    synchronized (dst) {
11000                        dst.provider = src.provider;
11001                        dst.proc = r;
11002                        dst.notifyAll();
11003                    }
11004                    updateOomAdjLocked(r);
11005                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11006                            src.info.authority);
11007                }
11008            }
11009
11010            Binder.restoreCallingIdentity(origId);
11011        }
11012    }
11013
11014    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11015        ContentProviderConnection conn;
11016        try {
11017            conn = (ContentProviderConnection)connection;
11018        } catch (ClassCastException e) {
11019            String msg ="refContentProvider: " + connection
11020                    + " not a ContentProviderConnection";
11021            Slog.w(TAG, msg);
11022            throw new IllegalArgumentException(msg);
11023        }
11024        if (conn == null) {
11025            throw new NullPointerException("connection is null");
11026        }
11027
11028        synchronized (this) {
11029            if (stable > 0) {
11030                conn.numStableIncs += stable;
11031            }
11032            stable = conn.stableCount + stable;
11033            if (stable < 0) {
11034                throw new IllegalStateException("stableCount < 0: " + stable);
11035            }
11036
11037            if (unstable > 0) {
11038                conn.numUnstableIncs += unstable;
11039            }
11040            unstable = conn.unstableCount + unstable;
11041            if (unstable < 0) {
11042                throw new IllegalStateException("unstableCount < 0: " + unstable);
11043            }
11044
11045            if ((stable+unstable) <= 0) {
11046                throw new IllegalStateException("ref counts can't go to zero here: stable="
11047                        + stable + " unstable=" + unstable);
11048            }
11049            conn.stableCount = stable;
11050            conn.unstableCount = unstable;
11051            return !conn.dead;
11052        }
11053    }
11054
11055    public void unstableProviderDied(IBinder connection) {
11056        ContentProviderConnection conn;
11057        try {
11058            conn = (ContentProviderConnection)connection;
11059        } catch (ClassCastException e) {
11060            String msg ="refContentProvider: " + connection
11061                    + " not a ContentProviderConnection";
11062            Slog.w(TAG, msg);
11063            throw new IllegalArgumentException(msg);
11064        }
11065        if (conn == null) {
11066            throw new NullPointerException("connection is null");
11067        }
11068
11069        // Safely retrieve the content provider associated with the connection.
11070        IContentProvider provider;
11071        synchronized (this) {
11072            provider = conn.provider.provider;
11073        }
11074
11075        if (provider == null) {
11076            // Um, yeah, we're way ahead of you.
11077            return;
11078        }
11079
11080        // Make sure the caller is being honest with us.
11081        if (provider.asBinder().pingBinder()) {
11082            // Er, no, still looks good to us.
11083            synchronized (this) {
11084                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11085                        + " says " + conn + " died, but we don't agree");
11086                return;
11087            }
11088        }
11089
11090        // Well look at that!  It's dead!
11091        synchronized (this) {
11092            if (conn.provider.provider != provider) {
11093                // But something changed...  good enough.
11094                return;
11095            }
11096
11097            ProcessRecord proc = conn.provider.proc;
11098            if (proc == null || proc.thread == null) {
11099                // Seems like the process is already cleaned up.
11100                return;
11101            }
11102
11103            // As far as we're concerned, this is just like receiving a
11104            // death notification...  just a bit prematurely.
11105            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11106                    + ") early provider death");
11107            final long ident = Binder.clearCallingIdentity();
11108            try {
11109                appDiedLocked(proc);
11110            } finally {
11111                Binder.restoreCallingIdentity(ident);
11112            }
11113        }
11114    }
11115
11116    @Override
11117    public void appNotRespondingViaProvider(IBinder connection) {
11118        enforceCallingPermission(
11119                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11120
11121        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11122        if (conn == null) {
11123            Slog.w(TAG, "ContentProviderConnection is null");
11124            return;
11125        }
11126
11127        final ProcessRecord host = conn.provider.proc;
11128        if (host == null) {
11129            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11130            return;
11131        }
11132
11133        mHandler.post(new Runnable() {
11134            @Override
11135            public void run() {
11136                mAppErrors.appNotResponding(host, null, null, false,
11137                        "ContentProvider not responding");
11138            }
11139        });
11140    }
11141
11142    public final void installSystemProviders() {
11143        List<ProviderInfo> providers;
11144        synchronized (this) {
11145            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11146            providers = generateApplicationProvidersLocked(app);
11147            if (providers != null) {
11148                for (int i=providers.size()-1; i>=0; i--) {
11149                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11150                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11151                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11152                                + ": not system .apk");
11153                        providers.remove(i);
11154                    }
11155                }
11156            }
11157        }
11158        if (providers != null) {
11159            mSystemThread.installSystemProviders(providers);
11160        }
11161
11162        mCoreSettingsObserver = new CoreSettingsObserver(this);
11163        mFontScaleSettingObserver = new FontScaleSettingObserver();
11164
11165        //mUsageStatsService.monitorPackages();
11166    }
11167
11168    private void startPersistentApps(int matchFlags) {
11169        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11170
11171        synchronized (this) {
11172            try {
11173                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11174                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11175                for (ApplicationInfo app : apps) {
11176                    if (!"android".equals(app.packageName)) {
11177                        addAppLocked(app, false, null /* ABI override */);
11178                    }
11179                }
11180            } catch (RemoteException ex) {
11181            }
11182        }
11183    }
11184
11185    /**
11186     * When a user is unlocked, we need to install encryption-unaware providers
11187     * belonging to any running apps.
11188     */
11189    private void installEncryptionUnawareProviders(int userId) {
11190        // We're only interested in providers that are encryption unaware, and
11191        // we don't care about uninstalled apps, since there's no way they're
11192        // running at this point.
11193        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11194
11195        synchronized (this) {
11196            final int NP = mProcessNames.getMap().size();
11197            for (int ip = 0; ip < NP; ip++) {
11198                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11199                final int NA = apps.size();
11200                for (int ia = 0; ia < NA; ia++) {
11201                    final ProcessRecord app = apps.valueAt(ia);
11202                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11203
11204                    final int NG = app.pkgList.size();
11205                    for (int ig = 0; ig < NG; ig++) {
11206                        try {
11207                            final String pkgName = app.pkgList.keyAt(ig);
11208                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11209                                    .getPackageInfo(pkgName, matchFlags, userId);
11210                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11211                                for (ProviderInfo pi : pkgInfo.providers) {
11212                                    // TODO: keep in sync with generateApplicationProvidersLocked
11213                                    final boolean processMatch = Objects.equals(pi.processName,
11214                                            app.processName) || pi.multiprocess;
11215                                    final boolean userMatch = isSingleton(pi.processName,
11216                                            pi.applicationInfo, pi.name, pi.flags)
11217                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11218                                    if (processMatch && userMatch) {
11219                                        Log.v(TAG, "Installing " + pi);
11220                                        app.thread.scheduleInstallProvider(pi);
11221                                    } else {
11222                                        Log.v(TAG, "Skipping " + pi);
11223                                    }
11224                                }
11225                            }
11226                        } catch (RemoteException ignored) {
11227                        }
11228                    }
11229                }
11230            }
11231        }
11232    }
11233
11234    /**
11235     * Allows apps to retrieve the MIME type of a URI.
11236     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11237     * users, then it does not need permission to access the ContentProvider.
11238     * Either, it needs cross-user uri grants.
11239     *
11240     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11241     *
11242     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11243     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11244     */
11245    public String getProviderMimeType(Uri uri, int userId) {
11246        enforceNotIsolatedCaller("getProviderMimeType");
11247        final String name = uri.getAuthority();
11248        int callingUid = Binder.getCallingUid();
11249        int callingPid = Binder.getCallingPid();
11250        long ident = 0;
11251        boolean clearedIdentity = false;
11252        synchronized (this) {
11253            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11254        }
11255        if (canClearIdentity(callingPid, callingUid, userId)) {
11256            clearedIdentity = true;
11257            ident = Binder.clearCallingIdentity();
11258        }
11259        ContentProviderHolder holder = null;
11260        try {
11261            holder = getContentProviderExternalUnchecked(name, null, userId);
11262            if (holder != null) {
11263                return holder.provider.getType(uri);
11264            }
11265        } catch (RemoteException e) {
11266            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11267            return null;
11268        } finally {
11269            // We need to clear the identity to call removeContentProviderExternalUnchecked
11270            if (!clearedIdentity) {
11271                ident = Binder.clearCallingIdentity();
11272            }
11273            try {
11274                if (holder != null) {
11275                    removeContentProviderExternalUnchecked(name, null, userId);
11276                }
11277            } finally {
11278                Binder.restoreCallingIdentity(ident);
11279            }
11280        }
11281
11282        return null;
11283    }
11284
11285    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11286        if (UserHandle.getUserId(callingUid) == userId) {
11287            return true;
11288        }
11289        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11290                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11291                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11292                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11293                return true;
11294        }
11295        return false;
11296    }
11297
11298    // =========================================================
11299    // GLOBAL MANAGEMENT
11300    // =========================================================
11301
11302    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11303            boolean isolated, int isolatedUid) {
11304        String proc = customProcess != null ? customProcess : info.processName;
11305        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11306        final int userId = UserHandle.getUserId(info.uid);
11307        int uid = info.uid;
11308        if (isolated) {
11309            if (isolatedUid == 0) {
11310                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11311                while (true) {
11312                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11313                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11314                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11315                    }
11316                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11317                    mNextIsolatedProcessUid++;
11318                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11319                        // No process for this uid, use it.
11320                        break;
11321                    }
11322                    stepsLeft--;
11323                    if (stepsLeft <= 0) {
11324                        return null;
11325                    }
11326                }
11327            } else {
11328                // Special case for startIsolatedProcess (internal only), where
11329                // the uid of the isolated process is specified by the caller.
11330                uid = isolatedUid;
11331            }
11332        }
11333        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11334        if (!mBooted && !mBooting
11335                && userId == UserHandle.USER_SYSTEM
11336                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11337            r.persistent = true;
11338        }
11339        addProcessNameLocked(r);
11340        return r;
11341    }
11342
11343    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11344            String abiOverride) {
11345        ProcessRecord app;
11346        if (!isolated) {
11347            app = getProcessRecordLocked(info.processName, info.uid, true);
11348        } else {
11349            app = null;
11350        }
11351
11352        if (app == null) {
11353            app = newProcessRecordLocked(info, null, isolated, 0);
11354            updateLruProcessLocked(app, false, null);
11355            updateOomAdjLocked();
11356        }
11357
11358        // This package really, really can not be stopped.
11359        try {
11360            AppGlobals.getPackageManager().setPackageStoppedState(
11361                    info.packageName, false, UserHandle.getUserId(app.uid));
11362        } catch (RemoteException e) {
11363        } catch (IllegalArgumentException e) {
11364            Slog.w(TAG, "Failed trying to unstop package "
11365                    + info.packageName + ": " + e);
11366        }
11367
11368        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11369            app.persistent = true;
11370            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11371        }
11372        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11373            mPersistentStartingProcesses.add(app);
11374            startProcessLocked(app, "added application", app.processName, abiOverride,
11375                    null /* entryPoint */, null /* entryPointArgs */);
11376        }
11377
11378        return app;
11379    }
11380
11381    public void unhandledBack() {
11382        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11383                "unhandledBack()");
11384
11385        synchronized(this) {
11386            final long origId = Binder.clearCallingIdentity();
11387            try {
11388                getFocusedStack().unhandledBackLocked();
11389            } finally {
11390                Binder.restoreCallingIdentity(origId);
11391            }
11392        }
11393    }
11394
11395    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11396        enforceNotIsolatedCaller("openContentUri");
11397        final int userId = UserHandle.getCallingUserId();
11398        String name = uri.getAuthority();
11399        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11400        ParcelFileDescriptor pfd = null;
11401        if (cph != null) {
11402            // We record the binder invoker's uid in thread-local storage before
11403            // going to the content provider to open the file.  Later, in the code
11404            // that handles all permissions checks, we look for this uid and use
11405            // that rather than the Activity Manager's own uid.  The effect is that
11406            // we do the check against the caller's permissions even though it looks
11407            // to the content provider like the Activity Manager itself is making
11408            // the request.
11409            Binder token = new Binder();
11410            sCallerIdentity.set(new Identity(
11411                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11412            try {
11413                pfd = cph.provider.openFile(null, uri, "r", null, token);
11414            } catch (FileNotFoundException e) {
11415                // do nothing; pfd will be returned null
11416            } finally {
11417                // Ensure that whatever happens, we clean up the identity state
11418                sCallerIdentity.remove();
11419                // Ensure we're done with the provider.
11420                removeContentProviderExternalUnchecked(name, null, userId);
11421            }
11422        } else {
11423            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11424        }
11425        return pfd;
11426    }
11427
11428    // Actually is sleeping or shutting down or whatever else in the future
11429    // is an inactive state.
11430    public boolean isSleepingOrShuttingDown() {
11431        return isSleeping() || mShuttingDown;
11432    }
11433
11434    public boolean isSleeping() {
11435        return mSleeping;
11436    }
11437
11438    void onWakefulnessChanged(int wakefulness) {
11439        synchronized(this) {
11440            mWakefulness = wakefulness;
11441            updateSleepIfNeededLocked();
11442        }
11443    }
11444
11445    void finishRunningVoiceLocked() {
11446        if (mRunningVoice != null) {
11447            mRunningVoice = null;
11448            mVoiceWakeLock.release();
11449            updateSleepIfNeededLocked();
11450        }
11451    }
11452
11453    void startTimeTrackingFocusedActivityLocked() {
11454        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11455            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11456        }
11457    }
11458
11459    void updateSleepIfNeededLocked() {
11460        if (mSleeping && !shouldSleepLocked()) {
11461            mSleeping = false;
11462            startTimeTrackingFocusedActivityLocked();
11463            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11464            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11465            updateOomAdjLocked();
11466        } else if (!mSleeping && shouldSleepLocked()) {
11467            mSleeping = true;
11468            if (mCurAppTimeTracker != null) {
11469                mCurAppTimeTracker.stop();
11470            }
11471            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11472            mStackSupervisor.goingToSleepLocked();
11473            updateOomAdjLocked();
11474
11475            // Initialize the wake times of all processes.
11476            checkExcessivePowerUsageLocked(false);
11477            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11478            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11479            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11480        }
11481    }
11482
11483    private boolean shouldSleepLocked() {
11484        // Resume applications while running a voice interactor.
11485        if (mRunningVoice != null) {
11486            return false;
11487        }
11488
11489        // TODO: Transform the lock screen state into a sleep token instead.
11490        switch (mWakefulness) {
11491            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11492            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11493            case PowerManagerInternal.WAKEFULNESS_DOZING:
11494                // Pause applications whenever the lock screen is shown or any sleep
11495                // tokens have been acquired.
11496                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11497            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11498            default:
11499                // If we're asleep then pause applications unconditionally.
11500                return true;
11501        }
11502    }
11503
11504    /** Pokes the task persister. */
11505    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11506        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11507    }
11508
11509    /** Notifies all listeners when the task stack has changed. */
11510    void notifyTaskStackChangedLocked() {
11511        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11512        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11513        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11514        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11515    }
11516
11517    /** Notifies all listeners when an Activity is pinned. */
11518    void notifyActivityPinnedLocked() {
11519        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11520        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11521    }
11522
11523    /**
11524     * Notifies all listeners when an attempt was made to start an an activity that is already
11525     * running in the pinned stack and the activity was not actually started, but the task is
11526     * either brought to the front or a new Intent is delivered to it.
11527     */
11528    void notifyPinnedActivityRestartAttemptLocked() {
11529        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11530        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11531    }
11532
11533    /** Notifies all listeners when the pinned stack animation ends. */
11534    @Override
11535    public void notifyPinnedStackAnimationEnded() {
11536        synchronized (this) {
11537            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11538            mHandler.obtainMessage(
11539                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11540        }
11541    }
11542
11543    @Override
11544    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11545        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11546    }
11547
11548    @Override
11549    public boolean shutdown(int timeout) {
11550        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11551                != PackageManager.PERMISSION_GRANTED) {
11552            throw new SecurityException("Requires permission "
11553                    + android.Manifest.permission.SHUTDOWN);
11554        }
11555
11556        boolean timedout = false;
11557
11558        synchronized(this) {
11559            mShuttingDown = true;
11560            updateEventDispatchingLocked();
11561            timedout = mStackSupervisor.shutdownLocked(timeout);
11562        }
11563
11564        mAppOpsService.shutdown();
11565        if (mUsageStatsService != null) {
11566            mUsageStatsService.prepareShutdown();
11567        }
11568        mBatteryStatsService.shutdown();
11569        synchronized (this) {
11570            mProcessStats.shutdownLocked();
11571            notifyTaskPersisterLocked(null, true);
11572        }
11573
11574        return timedout;
11575    }
11576
11577    public final void activitySlept(IBinder token) {
11578        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11579
11580        final long origId = Binder.clearCallingIdentity();
11581
11582        synchronized (this) {
11583            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11584            if (r != null) {
11585                mStackSupervisor.activitySleptLocked(r);
11586            }
11587        }
11588
11589        Binder.restoreCallingIdentity(origId);
11590    }
11591
11592    private String lockScreenShownToString() {
11593        switch (mLockScreenShown) {
11594            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11595            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11596            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11597            default: return "Unknown=" + mLockScreenShown;
11598        }
11599    }
11600
11601    void logLockScreen(String msg) {
11602        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11603                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11604                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11605                + " mSleeping=" + mSleeping);
11606    }
11607
11608    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11609        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11610        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11611        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11612            boolean wasRunningVoice = mRunningVoice != null;
11613            mRunningVoice = session;
11614            if (!wasRunningVoice) {
11615                mVoiceWakeLock.acquire();
11616                updateSleepIfNeededLocked();
11617            }
11618        }
11619    }
11620
11621    private void updateEventDispatchingLocked() {
11622        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11623    }
11624
11625    public void setLockScreenShown(boolean showing, boolean occluded) {
11626        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11627                != PackageManager.PERMISSION_GRANTED) {
11628            throw new SecurityException("Requires permission "
11629                    + android.Manifest.permission.DEVICE_POWER);
11630        }
11631
11632        synchronized(this) {
11633            long ident = Binder.clearCallingIdentity();
11634            try {
11635                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11636                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11637                if (showing && occluded) {
11638                    // The lock screen is currently showing, but is occluded by a window that can
11639                    // show on top of the lock screen. In this can we want to dismiss the docked
11640                    // stack since it will be complicated/risky to try to put the activity on top
11641                    // of the lock screen in the right fullscreen configuration.
11642                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11643                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11644                }
11645
11646                updateSleepIfNeededLocked();
11647            } finally {
11648                Binder.restoreCallingIdentity(ident);
11649            }
11650        }
11651    }
11652
11653    @Override
11654    public void notifyLockedProfile(@UserIdInt int userId) {
11655        try {
11656            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11657                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11658            }
11659        } catch (RemoteException ex) {
11660            throw new SecurityException("Fail to check is caller a privileged app", ex);
11661        }
11662
11663        synchronized (this) {
11664            if (mStackSupervisor.isUserLockedProfile(userId)) {
11665                final long ident = Binder.clearCallingIdentity();
11666                try {
11667                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11668                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11669                        // If there is no device lock, we will show the profile's credential page.
11670                        mActivityStarter.showConfirmDeviceCredential(userId);
11671                    } else {
11672                        // Showing launcher to avoid user entering credential twice.
11673                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11674                    }
11675                } finally {
11676                    Binder.restoreCallingIdentity(ident);
11677                }
11678            }
11679        }
11680    }
11681
11682    @Override
11683    public void startConfirmDeviceCredentialIntent(Intent intent) {
11684        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11685        synchronized (this) {
11686            final long ident = Binder.clearCallingIdentity();
11687            try {
11688                mActivityStarter.startConfirmCredentialIntent(intent);
11689            } finally {
11690                Binder.restoreCallingIdentity(ident);
11691            }
11692        }
11693    }
11694
11695    @Override
11696    public void stopAppSwitches() {
11697        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11698                != PackageManager.PERMISSION_GRANTED) {
11699            throw new SecurityException("viewquires permission "
11700                    + android.Manifest.permission.STOP_APP_SWITCHES);
11701        }
11702
11703        synchronized(this) {
11704            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11705                    + APP_SWITCH_DELAY_TIME;
11706            mDidAppSwitch = false;
11707            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11708            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11709            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11710        }
11711    }
11712
11713    public void resumeAppSwitches() {
11714        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11715                != PackageManager.PERMISSION_GRANTED) {
11716            throw new SecurityException("Requires permission "
11717                    + android.Manifest.permission.STOP_APP_SWITCHES);
11718        }
11719
11720        synchronized(this) {
11721            // Note that we don't execute any pending app switches... we will
11722            // let those wait until either the timeout, or the next start
11723            // activity request.
11724            mAppSwitchesAllowedTime = 0;
11725        }
11726    }
11727
11728    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11729            int callingPid, int callingUid, String name) {
11730        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11731            return true;
11732        }
11733
11734        int perm = checkComponentPermission(
11735                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11736                sourceUid, -1, true);
11737        if (perm == PackageManager.PERMISSION_GRANTED) {
11738            return true;
11739        }
11740
11741        // If the actual IPC caller is different from the logical source, then
11742        // also see if they are allowed to control app switches.
11743        if (callingUid != -1 && callingUid != sourceUid) {
11744            perm = checkComponentPermission(
11745                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11746                    callingUid, -1, true);
11747            if (perm == PackageManager.PERMISSION_GRANTED) {
11748                return true;
11749            }
11750        }
11751
11752        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11753        return false;
11754    }
11755
11756    public void setDebugApp(String packageName, boolean waitForDebugger,
11757            boolean persistent) {
11758        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11759                "setDebugApp()");
11760
11761        long ident = Binder.clearCallingIdentity();
11762        try {
11763            // Note that this is not really thread safe if there are multiple
11764            // callers into it at the same time, but that's not a situation we
11765            // care about.
11766            if (persistent) {
11767                final ContentResolver resolver = mContext.getContentResolver();
11768                Settings.Global.putString(
11769                    resolver, Settings.Global.DEBUG_APP,
11770                    packageName);
11771                Settings.Global.putInt(
11772                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11773                    waitForDebugger ? 1 : 0);
11774            }
11775
11776            synchronized (this) {
11777                if (!persistent) {
11778                    mOrigDebugApp = mDebugApp;
11779                    mOrigWaitForDebugger = mWaitForDebugger;
11780                }
11781                mDebugApp = packageName;
11782                mWaitForDebugger = waitForDebugger;
11783                mDebugTransient = !persistent;
11784                if (packageName != null) {
11785                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11786                            false, UserHandle.USER_ALL, "set debug app");
11787                }
11788            }
11789        } finally {
11790            Binder.restoreCallingIdentity(ident);
11791        }
11792    }
11793
11794    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11795        synchronized (this) {
11796            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11797            if (!isDebuggable) {
11798                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11799                    throw new SecurityException("Process not debuggable: " + app.packageName);
11800                }
11801            }
11802
11803            mTrackAllocationApp = processName;
11804        }
11805    }
11806
11807    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11808        synchronized (this) {
11809            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11810            if (!isDebuggable) {
11811                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11812                    throw new SecurityException("Process not debuggable: " + app.packageName);
11813                }
11814            }
11815            mProfileApp = processName;
11816            mProfileFile = profilerInfo.profileFile;
11817            if (mProfileFd != null) {
11818                try {
11819                    mProfileFd.close();
11820                } catch (IOException e) {
11821                }
11822                mProfileFd = null;
11823            }
11824            mProfileFd = profilerInfo.profileFd;
11825            mSamplingInterval = profilerInfo.samplingInterval;
11826            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11827            mProfileType = 0;
11828        }
11829    }
11830
11831    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11832        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11833        if (!isDebuggable) {
11834            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11835                throw new SecurityException("Process not debuggable: " + app.packageName);
11836            }
11837        }
11838        mNativeDebuggingApp = processName;
11839    }
11840
11841    @Override
11842    public void setAlwaysFinish(boolean enabled) {
11843        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11844                "setAlwaysFinish()");
11845
11846        long ident = Binder.clearCallingIdentity();
11847        try {
11848            Settings.Global.putInt(
11849                    mContext.getContentResolver(),
11850                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11851
11852            synchronized (this) {
11853                mAlwaysFinishActivities = enabled;
11854            }
11855        } finally {
11856            Binder.restoreCallingIdentity(ident);
11857        }
11858    }
11859
11860    @Override
11861    public void setLenientBackgroundCheck(boolean enabled) {
11862        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11863                "setLenientBackgroundCheck()");
11864
11865        long ident = Binder.clearCallingIdentity();
11866        try {
11867            Settings.Global.putInt(
11868                    mContext.getContentResolver(),
11869                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11870
11871            synchronized (this) {
11872                mLenientBackgroundCheck = enabled;
11873            }
11874        } finally {
11875            Binder.restoreCallingIdentity(ident);
11876        }
11877    }
11878
11879    @Override
11880    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11881        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11882                "setActivityController()");
11883        synchronized (this) {
11884            mController = controller;
11885            mControllerIsAMonkey = imAMonkey;
11886            Watchdog.getInstance().setActivityController(controller);
11887        }
11888    }
11889
11890    @Override
11891    public void setUserIsMonkey(boolean userIsMonkey) {
11892        synchronized (this) {
11893            synchronized (mPidsSelfLocked) {
11894                final int callingPid = Binder.getCallingPid();
11895                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11896                if (precessRecord == null) {
11897                    throw new SecurityException("Unknown process: " + callingPid);
11898                }
11899                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11900                    throw new SecurityException("Only an instrumentation process "
11901                            + "with a UiAutomation can call setUserIsMonkey");
11902                }
11903            }
11904            mUserIsMonkey = userIsMonkey;
11905        }
11906    }
11907
11908    @Override
11909    public boolean isUserAMonkey() {
11910        synchronized (this) {
11911            // If there is a controller also implies the user is a monkey.
11912            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11913        }
11914    }
11915
11916    public void requestBugReport(int bugreportType) {
11917        String service = null;
11918        switch (bugreportType) {
11919            case ActivityManager.BUGREPORT_OPTION_FULL:
11920                service = "bugreport";
11921                break;
11922            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11923                service = "bugreportplus";
11924                break;
11925            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11926                service = "bugreportremote";
11927                break;
11928        }
11929        if (service == null) {
11930            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11931                    + bugreportType);
11932        }
11933        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11934        SystemProperties.set("ctl.start", service);
11935    }
11936
11937    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11938        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11939    }
11940
11941    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11942        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11943            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11944        }
11945        return KEY_DISPATCHING_TIMEOUT;
11946    }
11947
11948    @Override
11949    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11950        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11951                != PackageManager.PERMISSION_GRANTED) {
11952            throw new SecurityException("Requires permission "
11953                    + android.Manifest.permission.FILTER_EVENTS);
11954        }
11955        ProcessRecord proc;
11956        long timeout;
11957        synchronized (this) {
11958            synchronized (mPidsSelfLocked) {
11959                proc = mPidsSelfLocked.get(pid);
11960            }
11961            timeout = getInputDispatchingTimeoutLocked(proc);
11962        }
11963
11964        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11965            return -1;
11966        }
11967
11968        return timeout;
11969    }
11970
11971    /**
11972     * Handle input dispatching timeouts.
11973     * Returns whether input dispatching should be aborted or not.
11974     */
11975    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11976            final ActivityRecord activity, final ActivityRecord parent,
11977            final boolean aboveSystem, String reason) {
11978        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11979                != PackageManager.PERMISSION_GRANTED) {
11980            throw new SecurityException("Requires permission "
11981                    + android.Manifest.permission.FILTER_EVENTS);
11982        }
11983
11984        final String annotation;
11985        if (reason == null) {
11986            annotation = "Input dispatching timed out";
11987        } else {
11988            annotation = "Input dispatching timed out (" + reason + ")";
11989        }
11990
11991        if (proc != null) {
11992            synchronized (this) {
11993                if (proc.debugging) {
11994                    return false;
11995                }
11996
11997                if (mDidDexOpt) {
11998                    // Give more time since we were dexopting.
11999                    mDidDexOpt = false;
12000                    return false;
12001                }
12002
12003                if (proc.instrumentationClass != null) {
12004                    Bundle info = new Bundle();
12005                    info.putString("shortMsg", "keyDispatchingTimedOut");
12006                    info.putString("longMsg", annotation);
12007                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12008                    return true;
12009                }
12010            }
12011            mHandler.post(new Runnable() {
12012                @Override
12013                public void run() {
12014                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12015                }
12016            });
12017        }
12018
12019        return true;
12020    }
12021
12022    @Override
12023    public Bundle getAssistContextExtras(int requestType) {
12024        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12025                null, null, true /* focused */, true /* newSessionId */,
12026                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12027        if (pae == null) {
12028            return null;
12029        }
12030        synchronized (pae) {
12031            while (!pae.haveResult) {
12032                try {
12033                    pae.wait();
12034                } catch (InterruptedException e) {
12035                }
12036            }
12037        }
12038        synchronized (this) {
12039            buildAssistBundleLocked(pae, pae.result);
12040            mPendingAssistExtras.remove(pae);
12041            mUiHandler.removeCallbacks(pae);
12042        }
12043        return pae.extras;
12044    }
12045
12046    @Override
12047    public boolean isAssistDataAllowedOnCurrentActivity() {
12048        int userId;
12049        synchronized (this) {
12050            userId = mUserController.getCurrentUserIdLocked();
12051            ActivityRecord activity = getFocusedStack().topActivity();
12052            if (activity == null) {
12053                return false;
12054            }
12055            userId = activity.userId;
12056        }
12057        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12058                Context.DEVICE_POLICY_SERVICE);
12059        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12060    }
12061
12062    @Override
12063    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12064        long ident = Binder.clearCallingIdentity();
12065        try {
12066            synchronized (this) {
12067                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12068                ActivityRecord top = getFocusedStack().topActivity();
12069                if (top != caller) {
12070                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12071                            + " is not current top " + top);
12072                    return false;
12073                }
12074                if (!top.nowVisible) {
12075                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12076                            + " is not visible");
12077                    return false;
12078                }
12079            }
12080            AssistUtils utils = new AssistUtils(mContext);
12081            return utils.showSessionForActiveService(args,
12082                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12083        } finally {
12084            Binder.restoreCallingIdentity(ident);
12085        }
12086    }
12087
12088    @Override
12089    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12090            Bundle receiverExtras,
12091            IBinder activityToken, boolean focused, boolean newSessionId) {
12092        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12093                activityToken, focused, newSessionId,
12094                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12095                != null;
12096    }
12097
12098    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12099            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12100            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12101        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12102                "enqueueAssistContext()");
12103        synchronized (this) {
12104            ActivityRecord activity = getFocusedStack().topActivity();
12105            if (activity == null) {
12106                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12107                return null;
12108            }
12109            if (activity.app == null || activity.app.thread == null) {
12110                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12111                return null;
12112            }
12113            if (focused) {
12114                if (activityToken != null) {
12115                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12116                    if (activity != caller) {
12117                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12118                                + " is not current top " + activity);
12119                        return null;
12120                    }
12121                }
12122            } else {
12123                activity = ActivityRecord.forTokenLocked(activityToken);
12124                if (activity == null) {
12125                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12126                            + " couldn't be found");
12127                    return null;
12128                }
12129            }
12130
12131            PendingAssistExtras pae;
12132            Bundle extras = new Bundle();
12133            if (args != null) {
12134                extras.putAll(args);
12135            }
12136            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12137            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12138            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12139                    userHandle);
12140            // Increment the sessionId if necessary
12141            if (newSessionId) {
12142                mViSessionId++;
12143            }
12144            try {
12145                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12146                        requestType, mViSessionId);
12147                mPendingAssistExtras.add(pae);
12148                mUiHandler.postDelayed(pae, timeout);
12149            } catch (RemoteException e) {
12150                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12151                return null;
12152            }
12153            return pae;
12154        }
12155    }
12156
12157    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12158        IResultReceiver receiver;
12159        synchronized (this) {
12160            mPendingAssistExtras.remove(pae);
12161            receiver = pae.receiver;
12162        }
12163        if (receiver != null) {
12164            // Caller wants result sent back to them.
12165            Bundle sendBundle = new Bundle();
12166            // At least return the receiver extras
12167            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12168                    pae.receiverExtras);
12169            try {
12170                pae.receiver.send(0, sendBundle);
12171            } catch (RemoteException e) {
12172            }
12173        }
12174    }
12175
12176    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12177        if (result != null) {
12178            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12179        }
12180        if (pae.hint != null) {
12181            pae.extras.putBoolean(pae.hint, true);
12182        }
12183    }
12184
12185    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12186            AssistContent content, Uri referrer) {
12187        PendingAssistExtras pae = (PendingAssistExtras)token;
12188        synchronized (pae) {
12189            pae.result = extras;
12190            pae.structure = structure;
12191            pae.content = content;
12192            if (referrer != null) {
12193                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12194            }
12195            pae.haveResult = true;
12196            pae.notifyAll();
12197            if (pae.intent == null && pae.receiver == null) {
12198                // Caller is just waiting for the result.
12199                return;
12200            }
12201        }
12202
12203        // We are now ready to launch the assist activity.
12204        IResultReceiver sendReceiver = null;
12205        Bundle sendBundle = null;
12206        synchronized (this) {
12207            buildAssistBundleLocked(pae, extras);
12208            boolean exists = mPendingAssistExtras.remove(pae);
12209            mUiHandler.removeCallbacks(pae);
12210            if (!exists) {
12211                // Timed out.
12212                return;
12213            }
12214            if ((sendReceiver=pae.receiver) != null) {
12215                // Caller wants result sent back to them.
12216                sendBundle = new Bundle();
12217                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12218                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12219                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12220                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12221                        pae.receiverExtras);
12222            }
12223        }
12224        if (sendReceiver != null) {
12225            try {
12226                sendReceiver.send(0, sendBundle);
12227            } catch (RemoteException e) {
12228            }
12229            return;
12230        }
12231
12232        long ident = Binder.clearCallingIdentity();
12233        try {
12234            pae.intent.replaceExtras(pae.extras);
12235            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12236                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12237                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12238            closeSystemDialogs("assist");
12239            try {
12240                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12241            } catch (ActivityNotFoundException e) {
12242                Slog.w(TAG, "No activity to handle assist action.", e);
12243            }
12244        } finally {
12245            Binder.restoreCallingIdentity(ident);
12246        }
12247    }
12248
12249    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12250            Bundle args) {
12251        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12252                true /* focused */, true /* newSessionId */,
12253                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12254    }
12255
12256    public void registerProcessObserver(IProcessObserver observer) {
12257        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12258                "registerProcessObserver()");
12259        synchronized (this) {
12260            mProcessObservers.register(observer);
12261        }
12262    }
12263
12264    @Override
12265    public void unregisterProcessObserver(IProcessObserver observer) {
12266        synchronized (this) {
12267            mProcessObservers.unregister(observer);
12268        }
12269    }
12270
12271    @Override
12272    public void registerUidObserver(IUidObserver observer, int which) {
12273        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12274                "registerUidObserver()");
12275        synchronized (this) {
12276            mUidObservers.register(observer, which);
12277        }
12278    }
12279
12280    @Override
12281    public void unregisterUidObserver(IUidObserver observer) {
12282        synchronized (this) {
12283            mUidObservers.unregister(observer);
12284        }
12285    }
12286
12287    @Override
12288    public boolean convertFromTranslucent(IBinder token) {
12289        final long origId = Binder.clearCallingIdentity();
12290        try {
12291            synchronized (this) {
12292                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12293                if (r == null) {
12294                    return false;
12295                }
12296                final boolean translucentChanged = r.changeWindowTranslucency(true);
12297                if (translucentChanged) {
12298                    r.task.stack.releaseBackgroundResources(r);
12299                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12300                }
12301                mWindowManager.setAppFullscreen(token, true);
12302                return translucentChanged;
12303            }
12304        } finally {
12305            Binder.restoreCallingIdentity(origId);
12306        }
12307    }
12308
12309    @Override
12310    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12311        final long origId = Binder.clearCallingIdentity();
12312        try {
12313            synchronized (this) {
12314                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12315                if (r == null) {
12316                    return false;
12317                }
12318                int index = r.task.mActivities.lastIndexOf(r);
12319                if (index > 0) {
12320                    ActivityRecord under = r.task.mActivities.get(index - 1);
12321                    under.returningOptions = options;
12322                }
12323                final boolean translucentChanged = r.changeWindowTranslucency(false);
12324                if (translucentChanged) {
12325                    r.task.stack.convertActivityToTranslucent(r);
12326                }
12327                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12328                mWindowManager.setAppFullscreen(token, false);
12329                return translucentChanged;
12330            }
12331        } finally {
12332            Binder.restoreCallingIdentity(origId);
12333        }
12334    }
12335
12336    @Override
12337    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12338        final long origId = Binder.clearCallingIdentity();
12339        try {
12340            synchronized (this) {
12341                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12342                if (r != null) {
12343                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12344                }
12345            }
12346            return false;
12347        } finally {
12348            Binder.restoreCallingIdentity(origId);
12349        }
12350    }
12351
12352    @Override
12353    public boolean isBackgroundVisibleBehind(IBinder token) {
12354        final long origId = Binder.clearCallingIdentity();
12355        try {
12356            synchronized (this) {
12357                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12358                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12359                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12360                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12361                return visible;
12362            }
12363        } finally {
12364            Binder.restoreCallingIdentity(origId);
12365        }
12366    }
12367
12368    @Override
12369    public ActivityOptions getActivityOptions(IBinder token) {
12370        final long origId = Binder.clearCallingIdentity();
12371        try {
12372            synchronized (this) {
12373                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12374                if (r != null) {
12375                    final ActivityOptions activityOptions = r.pendingOptions;
12376                    r.pendingOptions = null;
12377                    return activityOptions;
12378                }
12379                return null;
12380            }
12381        } finally {
12382            Binder.restoreCallingIdentity(origId);
12383        }
12384    }
12385
12386    @Override
12387    public void setImmersive(IBinder token, boolean immersive) {
12388        synchronized(this) {
12389            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12390            if (r == null) {
12391                throw new IllegalArgumentException();
12392            }
12393            r.immersive = immersive;
12394
12395            // update associated state if we're frontmost
12396            if (r == mFocusedActivity) {
12397                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12398                applyUpdateLockStateLocked(r);
12399            }
12400        }
12401    }
12402
12403    @Override
12404    public boolean isImmersive(IBinder token) {
12405        synchronized (this) {
12406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12407            if (r == null) {
12408                throw new IllegalArgumentException();
12409            }
12410            return r.immersive;
12411        }
12412    }
12413
12414    @Override
12415    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12416        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12417            throw new UnsupportedOperationException("VR mode not supported on this device!");
12418        }
12419
12420        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12421
12422        ActivityRecord r;
12423        synchronized (this) {
12424            r = ActivityRecord.isInStackLocked(token);
12425        }
12426
12427        if (r == null) {
12428            throw new IllegalArgumentException();
12429        }
12430
12431        int err;
12432        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12433                VrManagerInternal.NO_ERROR) {
12434            return err;
12435        }
12436
12437        synchronized(this) {
12438            r.requestedVrComponent = (enabled) ? packageName : null;
12439
12440            // Update associated state if this activity is currently focused
12441            if (r == mFocusedActivity) {
12442                applyUpdateVrModeLocked(r);
12443            }
12444            return 0;
12445        }
12446    }
12447
12448    @Override
12449    public boolean isVrModePackageEnabled(ComponentName packageName) {
12450        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12451            throw new UnsupportedOperationException("VR mode not supported on this device!");
12452        }
12453
12454        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12455
12456        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12457                VrManagerInternal.NO_ERROR;
12458    }
12459
12460    public boolean isTopActivityImmersive() {
12461        enforceNotIsolatedCaller("startActivity");
12462        synchronized (this) {
12463            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12464            return (r != null) ? r.immersive : false;
12465        }
12466    }
12467
12468    @Override
12469    public boolean isTopOfTask(IBinder token) {
12470        synchronized (this) {
12471            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12472            if (r == null) {
12473                throw new IllegalArgumentException();
12474            }
12475            return r.task.getTopActivity() == r;
12476        }
12477    }
12478
12479    public final void enterSafeMode() {
12480        synchronized(this) {
12481            // It only makes sense to do this before the system is ready
12482            // and started launching other packages.
12483            if (!mSystemReady) {
12484                try {
12485                    AppGlobals.getPackageManager().enterSafeMode();
12486                } catch (RemoteException e) {
12487                }
12488            }
12489
12490            mSafeMode = true;
12491        }
12492    }
12493
12494    public final void showSafeModeOverlay() {
12495        View v = LayoutInflater.from(mContext).inflate(
12496                com.android.internal.R.layout.safe_mode, null);
12497        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12498        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12499        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12500        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12501        lp.gravity = Gravity.BOTTOM | Gravity.START;
12502        lp.format = v.getBackground().getOpacity();
12503        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12504                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12505        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12506        ((WindowManager)mContext.getSystemService(
12507                Context.WINDOW_SERVICE)).addView(v, lp);
12508    }
12509
12510    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12511        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12512            return;
12513        }
12514        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12515        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12516        synchronized (stats) {
12517            if (mBatteryStatsService.isOnBattery()) {
12518                mBatteryStatsService.enforceCallingPermission();
12519                int MY_UID = Binder.getCallingUid();
12520                final int uid;
12521                if (sender == null) {
12522                    uid = sourceUid;
12523                } else {
12524                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12525                }
12526                BatteryStatsImpl.Uid.Pkg pkg =
12527                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12528                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12529                pkg.noteWakeupAlarmLocked(tag);
12530            }
12531        }
12532    }
12533
12534    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12535        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12536            return;
12537        }
12538        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12539        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12540        synchronized (stats) {
12541            mBatteryStatsService.enforceCallingPermission();
12542            int MY_UID = Binder.getCallingUid();
12543            final int uid;
12544            if (sender == null) {
12545                uid = sourceUid;
12546            } else {
12547                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12548            }
12549            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12550        }
12551    }
12552
12553    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12554        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12555            return;
12556        }
12557        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12558        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12559        synchronized (stats) {
12560            mBatteryStatsService.enforceCallingPermission();
12561            int MY_UID = Binder.getCallingUid();
12562            final int uid;
12563            if (sender == null) {
12564                uid = sourceUid;
12565            } else {
12566                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12567            }
12568            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12569        }
12570    }
12571
12572    public boolean killPids(int[] pids, String pReason, boolean secure) {
12573        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12574            throw new SecurityException("killPids only available to the system");
12575        }
12576        String reason = (pReason == null) ? "Unknown" : pReason;
12577        // XXX Note: don't acquire main activity lock here, because the window
12578        // manager calls in with its locks held.
12579
12580        boolean killed = false;
12581        synchronized (mPidsSelfLocked) {
12582            int worstType = 0;
12583            for (int i=0; i<pids.length; i++) {
12584                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12585                if (proc != null) {
12586                    int type = proc.setAdj;
12587                    if (type > worstType) {
12588                        worstType = type;
12589                    }
12590                }
12591            }
12592
12593            // If the worst oom_adj is somewhere in the cached proc LRU range,
12594            // then constrain it so we will kill all cached procs.
12595            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12596                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12597                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12598            }
12599
12600            // If this is not a secure call, don't let it kill processes that
12601            // are important.
12602            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12603                worstType = ProcessList.SERVICE_ADJ;
12604            }
12605
12606            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12607            for (int i=0; i<pids.length; i++) {
12608                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12609                if (proc == null) {
12610                    continue;
12611                }
12612                int adj = proc.setAdj;
12613                if (adj >= worstType && !proc.killedByAm) {
12614                    proc.kill(reason, true);
12615                    killed = true;
12616                }
12617            }
12618        }
12619        return killed;
12620    }
12621
12622    @Override
12623    public void killUid(int appId, int userId, String reason) {
12624        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12625        synchronized (this) {
12626            final long identity = Binder.clearCallingIdentity();
12627            try {
12628                killPackageProcessesLocked(null, appId, userId,
12629                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12630                        reason != null ? reason : "kill uid");
12631            } finally {
12632                Binder.restoreCallingIdentity(identity);
12633            }
12634        }
12635    }
12636
12637    @Override
12638    public boolean killProcessesBelowForeground(String reason) {
12639        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12640            throw new SecurityException("killProcessesBelowForeground() only available to system");
12641        }
12642
12643        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12644    }
12645
12646    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12647        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12648            throw new SecurityException("killProcessesBelowAdj() only available to system");
12649        }
12650
12651        boolean killed = false;
12652        synchronized (mPidsSelfLocked) {
12653            final int size = mPidsSelfLocked.size();
12654            for (int i = 0; i < size; i++) {
12655                final int pid = mPidsSelfLocked.keyAt(i);
12656                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12657                if (proc == null) continue;
12658
12659                final int adj = proc.setAdj;
12660                if (adj > belowAdj && !proc.killedByAm) {
12661                    proc.kill(reason, true);
12662                    killed = true;
12663                }
12664            }
12665        }
12666        return killed;
12667    }
12668
12669    @Override
12670    public void hang(final IBinder who, boolean allowRestart) {
12671        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12672                != PackageManager.PERMISSION_GRANTED) {
12673            throw new SecurityException("Requires permission "
12674                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12675        }
12676
12677        final IBinder.DeathRecipient death = new DeathRecipient() {
12678            @Override
12679            public void binderDied() {
12680                synchronized (this) {
12681                    notifyAll();
12682                }
12683            }
12684        };
12685
12686        try {
12687            who.linkToDeath(death, 0);
12688        } catch (RemoteException e) {
12689            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12690            return;
12691        }
12692
12693        synchronized (this) {
12694            Watchdog.getInstance().setAllowRestart(allowRestart);
12695            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12696            synchronized (death) {
12697                while (who.isBinderAlive()) {
12698                    try {
12699                        death.wait();
12700                    } catch (InterruptedException e) {
12701                    }
12702                }
12703            }
12704            Watchdog.getInstance().setAllowRestart(true);
12705        }
12706    }
12707
12708    @Override
12709    public void restart() {
12710        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12711                != PackageManager.PERMISSION_GRANTED) {
12712            throw new SecurityException("Requires permission "
12713                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12714        }
12715
12716        Log.i(TAG, "Sending shutdown broadcast...");
12717
12718        BroadcastReceiver br = new BroadcastReceiver() {
12719            @Override public void onReceive(Context context, Intent intent) {
12720                // Now the broadcast is done, finish up the low-level shutdown.
12721                Log.i(TAG, "Shutting down activity manager...");
12722                shutdown(10000);
12723                Log.i(TAG, "Shutdown complete, restarting!");
12724                Process.killProcess(Process.myPid());
12725                System.exit(10);
12726            }
12727        };
12728
12729        // First send the high-level shut down broadcast.
12730        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12731        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12732        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12733        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12734        mContext.sendOrderedBroadcastAsUser(intent,
12735                UserHandle.ALL, null, br, mHandler, 0, null, null);
12736        */
12737        br.onReceive(mContext, intent);
12738    }
12739
12740    private long getLowRamTimeSinceIdle(long now) {
12741        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12742    }
12743
12744    @Override
12745    public void performIdleMaintenance() {
12746        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12747                != PackageManager.PERMISSION_GRANTED) {
12748            throw new SecurityException("Requires permission "
12749                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12750        }
12751
12752        synchronized (this) {
12753            final long now = SystemClock.uptimeMillis();
12754            final long timeSinceLastIdle = now - mLastIdleTime;
12755            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12756            mLastIdleTime = now;
12757            mLowRamTimeSinceLastIdle = 0;
12758            if (mLowRamStartTime != 0) {
12759                mLowRamStartTime = now;
12760            }
12761
12762            StringBuilder sb = new StringBuilder(128);
12763            sb.append("Idle maintenance over ");
12764            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12765            sb.append(" low RAM for ");
12766            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12767            Slog.i(TAG, sb.toString());
12768
12769            // If at least 1/3 of our time since the last idle period has been spent
12770            // with RAM low, then we want to kill processes.
12771            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12772
12773            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12774                ProcessRecord proc = mLruProcesses.get(i);
12775                if (proc.notCachedSinceIdle) {
12776                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12777                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12778                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12779                        if (doKilling && proc.initialIdlePss != 0
12780                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12781                            sb = new StringBuilder(128);
12782                            sb.append("Kill");
12783                            sb.append(proc.processName);
12784                            sb.append(" in idle maint: pss=");
12785                            sb.append(proc.lastPss);
12786                            sb.append(", swapPss=");
12787                            sb.append(proc.lastSwapPss);
12788                            sb.append(", initialPss=");
12789                            sb.append(proc.initialIdlePss);
12790                            sb.append(", period=");
12791                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12792                            sb.append(", lowRamPeriod=");
12793                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12794                            Slog.wtfQuiet(TAG, sb.toString());
12795                            proc.kill("idle maint (pss " + proc.lastPss
12796                                    + " from " + proc.initialIdlePss + ")", true);
12797                        }
12798                    }
12799                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12800                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12801                    proc.notCachedSinceIdle = true;
12802                    proc.initialIdlePss = 0;
12803                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12804                            mTestPssMode, isSleeping(), now);
12805                }
12806            }
12807
12808            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12809            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12810        }
12811    }
12812
12813    @Override
12814    public void sendIdleJobTrigger() {
12815        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12816                != PackageManager.PERMISSION_GRANTED) {
12817            throw new SecurityException("Requires permission "
12818                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12819        }
12820
12821        final long ident = Binder.clearCallingIdentity();
12822        try {
12823            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12824                    .setPackage("android")
12825                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12826            broadcastIntent(null, intent, null, null, 0, null, null, null,
12827                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12828        } finally {
12829            Binder.restoreCallingIdentity(ident);
12830        }
12831    }
12832
12833    private void retrieveSettings() {
12834        final ContentResolver resolver = mContext.getContentResolver();
12835        final boolean freeformWindowManagement =
12836                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12837                        || Settings.Global.getInt(
12838                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12839        final boolean supportsPictureInPicture =
12840                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12841
12842        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12843        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12844        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12845        final boolean alwaysFinishActivities =
12846                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12847        final boolean lenientBackgroundCheck =
12848                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12849        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12850        final boolean forceResizable = Settings.Global.getInt(
12851                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12852        // Transfer any global setting for forcing RTL layout, into a System Property
12853        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12854
12855        final Configuration configuration = new Configuration();
12856        Settings.System.getConfiguration(resolver, configuration);
12857        if (forceRtl) {
12858            // This will take care of setting the correct layout direction flags
12859            configuration.setLayoutDirection(configuration.locale);
12860        }
12861
12862        synchronized (this) {
12863            mDebugApp = mOrigDebugApp = debugApp;
12864            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12865            mAlwaysFinishActivities = alwaysFinishActivities;
12866            mLenientBackgroundCheck = lenientBackgroundCheck;
12867            mForceResizableActivities = forceResizable;
12868            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12869            if (supportsMultiWindow || forceResizable) {
12870                mSupportsMultiWindow = true;
12871                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12872                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12873            } else {
12874                mSupportsMultiWindow = false;
12875                mSupportsFreeformWindowManagement = false;
12876                mSupportsPictureInPicture = false;
12877            }
12878            // This happens before any activities are started, so we can
12879            // change mConfiguration in-place.
12880            updateConfigurationLocked(configuration, null, true);
12881            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12882                    "Initial config: " + mConfiguration);
12883
12884            // Load resources only after the current configuration has been set.
12885            final Resources res = mContext.getResources();
12886            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12887            mThumbnailWidth = res.getDimensionPixelSize(
12888                    com.android.internal.R.dimen.thumbnail_width);
12889            mThumbnailHeight = res.getDimensionPixelSize(
12890                    com.android.internal.R.dimen.thumbnail_height);
12891            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12892                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12893            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12894                    com.android.internal.R.string.config_appsNotReportingCrashes));
12895            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12896                mFullscreenThumbnailScale = (float) res
12897                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12898                    (float) mConfiguration.screenWidthDp;
12899            } else {
12900                mFullscreenThumbnailScale = res.getFraction(
12901                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12902            }
12903        }
12904    }
12905
12906    public boolean testIsSystemReady() {
12907        // no need to synchronize(this) just to read & return the value
12908        return mSystemReady;
12909    }
12910
12911    public void systemReady(final Runnable goingCallback) {
12912        synchronized(this) {
12913            if (mSystemReady) {
12914                // If we're done calling all the receivers, run the next "boot phase" passed in
12915                // by the SystemServer
12916                if (goingCallback != null) {
12917                    goingCallback.run();
12918                }
12919                return;
12920            }
12921
12922            mLocalDeviceIdleController
12923                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12924
12925            // Make sure we have the current profile info, since it is needed for security checks.
12926            mUserController.onSystemReady();
12927            mRecentTasks.onSystemReadyLocked();
12928            mAppOpsService.systemReady();
12929            mSystemReady = true;
12930        }
12931
12932        ArrayList<ProcessRecord> procsToKill = null;
12933        synchronized(mPidsSelfLocked) {
12934            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12935                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12936                if (!isAllowedWhileBooting(proc.info)){
12937                    if (procsToKill == null) {
12938                        procsToKill = new ArrayList<ProcessRecord>();
12939                    }
12940                    procsToKill.add(proc);
12941                }
12942            }
12943        }
12944
12945        synchronized(this) {
12946            if (procsToKill != null) {
12947                for (int i=procsToKill.size()-1; i>=0; i--) {
12948                    ProcessRecord proc = procsToKill.get(i);
12949                    Slog.i(TAG, "Removing system update proc: " + proc);
12950                    removeProcessLocked(proc, true, false, "system update done");
12951                }
12952            }
12953
12954            // Now that we have cleaned up any update processes, we
12955            // are ready to start launching real processes and know that
12956            // we won't trample on them any more.
12957            mProcessesReady = true;
12958        }
12959
12960        Slog.i(TAG, "System now ready");
12961        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12962            SystemClock.uptimeMillis());
12963
12964        synchronized(this) {
12965            // Make sure we have no pre-ready processes sitting around.
12966
12967            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12968                ResolveInfo ri = mContext.getPackageManager()
12969                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12970                                STOCK_PM_FLAGS);
12971                CharSequence errorMsg = null;
12972                if (ri != null) {
12973                    ActivityInfo ai = ri.activityInfo;
12974                    ApplicationInfo app = ai.applicationInfo;
12975                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12976                        mTopAction = Intent.ACTION_FACTORY_TEST;
12977                        mTopData = null;
12978                        mTopComponent = new ComponentName(app.packageName,
12979                                ai.name);
12980                    } else {
12981                        errorMsg = mContext.getResources().getText(
12982                                com.android.internal.R.string.factorytest_not_system);
12983                    }
12984                } else {
12985                    errorMsg = mContext.getResources().getText(
12986                            com.android.internal.R.string.factorytest_no_action);
12987                }
12988                if (errorMsg != null) {
12989                    mTopAction = null;
12990                    mTopData = null;
12991                    mTopComponent = null;
12992                    Message msg = Message.obtain();
12993                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12994                    msg.getData().putCharSequence("msg", errorMsg);
12995                    mUiHandler.sendMessage(msg);
12996                }
12997            }
12998        }
12999
13000        retrieveSettings();
13001        final int currentUserId;
13002        synchronized (this) {
13003            currentUserId = mUserController.getCurrentUserIdLocked();
13004            readGrantedUriPermissionsLocked();
13005        }
13006
13007        if (goingCallback != null) goingCallback.run();
13008
13009        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13010                Integer.toString(currentUserId), currentUserId);
13011        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13012                Integer.toString(currentUserId), currentUserId);
13013        mSystemServiceManager.startUser(currentUserId);
13014
13015        synchronized (this) {
13016            // Only start up encryption-aware persistent apps; once user is
13017            // unlocked we'll come back around and start unaware apps
13018            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13019
13020            // Start up initial activity.
13021            mBooting = true;
13022            // Enable home activity for system user, so that the system can always boot
13023            if (UserManager.isSplitSystemUser()) {
13024                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13025                try {
13026                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13027                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13028                            UserHandle.USER_SYSTEM);
13029                } catch (RemoteException e) {
13030                    throw e.rethrowAsRuntimeException();
13031                }
13032            }
13033            startHomeActivityLocked(currentUserId, "systemReady");
13034
13035            try {
13036                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13037                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13038                            + " data partition or your device will be unstable.");
13039                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13040                }
13041            } catch (RemoteException e) {
13042            }
13043
13044            if (!Build.isBuildConsistent()) {
13045                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13046                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13047            }
13048
13049            long ident = Binder.clearCallingIdentity();
13050            try {
13051                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13052                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13053                        | Intent.FLAG_RECEIVER_FOREGROUND);
13054                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13055                broadcastIntentLocked(null, null, intent,
13056                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13057                        null, false, false, MY_PID, Process.SYSTEM_UID,
13058                        currentUserId);
13059                intent = new Intent(Intent.ACTION_USER_STARTING);
13060                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13061                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13062                broadcastIntentLocked(null, null, intent,
13063                        null, new IIntentReceiver.Stub() {
13064                            @Override
13065                            public void performReceive(Intent intent, int resultCode, String data,
13066                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13067                                    throws RemoteException {
13068                            }
13069                        }, 0, null, null,
13070                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13071                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13072            } catch (Throwable t) {
13073                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13074            } finally {
13075                Binder.restoreCallingIdentity(ident);
13076            }
13077            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13078            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13079        }
13080    }
13081
13082    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13083        synchronized (this) {
13084            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13085        }
13086    }
13087
13088    void skipCurrentReceiverLocked(ProcessRecord app) {
13089        for (BroadcastQueue queue : mBroadcastQueues) {
13090            queue.skipCurrentReceiverLocked(app);
13091        }
13092    }
13093
13094    /**
13095     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13096     * The application process will exit immediately after this call returns.
13097     * @param app object of the crashing app, null for the system server
13098     * @param crashInfo describing the exception
13099     */
13100    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13101        ProcessRecord r = findAppProcess(app, "Crash");
13102        final String processName = app == null ? "system_server"
13103                : (r == null ? "unknown" : r.processName);
13104
13105        handleApplicationCrashInner("crash", r, processName, crashInfo);
13106    }
13107
13108    /* Native crash reporting uses this inner version because it needs to be somewhat
13109     * decoupled from the AM-managed cleanup lifecycle
13110     */
13111    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13112            ApplicationErrorReport.CrashInfo crashInfo) {
13113        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13114                UserHandle.getUserId(Binder.getCallingUid()), processName,
13115                r == null ? -1 : r.info.flags,
13116                crashInfo.exceptionClassName,
13117                crashInfo.exceptionMessage,
13118                crashInfo.throwFileName,
13119                crashInfo.throwLineNumber);
13120
13121        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13122
13123        mAppErrors.crashApplication(r, crashInfo);
13124    }
13125
13126    public void handleApplicationStrictModeViolation(
13127            IBinder app,
13128            int violationMask,
13129            StrictMode.ViolationInfo info) {
13130        ProcessRecord r = findAppProcess(app, "StrictMode");
13131        if (r == null) {
13132            return;
13133        }
13134
13135        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13136            Integer stackFingerprint = info.hashCode();
13137            boolean logIt = true;
13138            synchronized (mAlreadyLoggedViolatedStacks) {
13139                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13140                    logIt = false;
13141                    // TODO: sub-sample into EventLog for these, with
13142                    // the info.durationMillis?  Then we'd get
13143                    // the relative pain numbers, without logging all
13144                    // the stack traces repeatedly.  We'd want to do
13145                    // likewise in the client code, which also does
13146                    // dup suppression, before the Binder call.
13147                } else {
13148                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13149                        mAlreadyLoggedViolatedStacks.clear();
13150                    }
13151                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13152                }
13153            }
13154            if (logIt) {
13155                logStrictModeViolationToDropBox(r, info);
13156            }
13157        }
13158
13159        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13160            AppErrorResult result = new AppErrorResult();
13161            synchronized (this) {
13162                final long origId = Binder.clearCallingIdentity();
13163
13164                Message msg = Message.obtain();
13165                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13166                HashMap<String, Object> data = new HashMap<String, Object>();
13167                data.put("result", result);
13168                data.put("app", r);
13169                data.put("violationMask", violationMask);
13170                data.put("info", info);
13171                msg.obj = data;
13172                mUiHandler.sendMessage(msg);
13173
13174                Binder.restoreCallingIdentity(origId);
13175            }
13176            int res = result.get();
13177            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13178        }
13179    }
13180
13181    // Depending on the policy in effect, there could be a bunch of
13182    // these in quick succession so we try to batch these together to
13183    // minimize disk writes, number of dropbox entries, and maximize
13184    // compression, by having more fewer, larger records.
13185    private void logStrictModeViolationToDropBox(
13186            ProcessRecord process,
13187            StrictMode.ViolationInfo info) {
13188        if (info == null) {
13189            return;
13190        }
13191        final boolean isSystemApp = process == null ||
13192                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13193                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13194        final String processName = process == null ? "unknown" : process.processName;
13195        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13196        final DropBoxManager dbox = (DropBoxManager)
13197                mContext.getSystemService(Context.DROPBOX_SERVICE);
13198
13199        // Exit early if the dropbox isn't configured to accept this report type.
13200        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13201
13202        boolean bufferWasEmpty;
13203        boolean needsFlush;
13204        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13205        synchronized (sb) {
13206            bufferWasEmpty = sb.length() == 0;
13207            appendDropBoxProcessHeaders(process, processName, sb);
13208            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13209            sb.append("System-App: ").append(isSystemApp).append("\n");
13210            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13211            if (info.violationNumThisLoop != 0) {
13212                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13213            }
13214            if (info.numAnimationsRunning != 0) {
13215                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13216            }
13217            if (info.broadcastIntentAction != null) {
13218                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13219            }
13220            if (info.durationMillis != -1) {
13221                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13222            }
13223            if (info.numInstances != -1) {
13224                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13225            }
13226            if (info.tags != null) {
13227                for (String tag : info.tags) {
13228                    sb.append("Span-Tag: ").append(tag).append("\n");
13229                }
13230            }
13231            sb.append("\n");
13232            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13233                sb.append(info.crashInfo.stackTrace);
13234                sb.append("\n");
13235            }
13236            if (info.message != null) {
13237                sb.append(info.message);
13238                sb.append("\n");
13239            }
13240
13241            // Only buffer up to ~64k.  Various logging bits truncate
13242            // things at 128k.
13243            needsFlush = (sb.length() > 64 * 1024);
13244        }
13245
13246        // Flush immediately if the buffer's grown too large, or this
13247        // is a non-system app.  Non-system apps are isolated with a
13248        // different tag & policy and not batched.
13249        //
13250        // Batching is useful during internal testing with
13251        // StrictMode settings turned up high.  Without batching,
13252        // thousands of separate files could be created on boot.
13253        if (!isSystemApp || needsFlush) {
13254            new Thread("Error dump: " + dropboxTag) {
13255                @Override
13256                public void run() {
13257                    String report;
13258                    synchronized (sb) {
13259                        report = sb.toString();
13260                        sb.delete(0, sb.length());
13261                        sb.trimToSize();
13262                    }
13263                    if (report.length() != 0) {
13264                        dbox.addText(dropboxTag, report);
13265                    }
13266                }
13267            }.start();
13268            return;
13269        }
13270
13271        // System app batching:
13272        if (!bufferWasEmpty) {
13273            // An existing dropbox-writing thread is outstanding, so
13274            // we don't need to start it up.  The existing thread will
13275            // catch the buffer appends we just did.
13276            return;
13277        }
13278
13279        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13280        // (After this point, we shouldn't access AMS internal data structures.)
13281        new Thread("Error dump: " + dropboxTag) {
13282            @Override
13283            public void run() {
13284                // 5 second sleep to let stacks arrive and be batched together
13285                try {
13286                    Thread.sleep(5000);  // 5 seconds
13287                } catch (InterruptedException e) {}
13288
13289                String errorReport;
13290                synchronized (mStrictModeBuffer) {
13291                    errorReport = mStrictModeBuffer.toString();
13292                    if (errorReport.length() == 0) {
13293                        return;
13294                    }
13295                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13296                    mStrictModeBuffer.trimToSize();
13297                }
13298                dbox.addText(dropboxTag, errorReport);
13299            }
13300        }.start();
13301    }
13302
13303    /**
13304     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13305     * @param app object of the crashing app, null for the system server
13306     * @param tag reported by the caller
13307     * @param system whether this wtf is coming from the system
13308     * @param crashInfo describing the context of the error
13309     * @return true if the process should exit immediately (WTF is fatal)
13310     */
13311    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13312            final ApplicationErrorReport.CrashInfo crashInfo) {
13313        final int callingUid = Binder.getCallingUid();
13314        final int callingPid = Binder.getCallingPid();
13315
13316        if (system) {
13317            // If this is coming from the system, we could very well have low-level
13318            // system locks held, so we want to do this all asynchronously.  And we
13319            // never want this to become fatal, so there is that too.
13320            mHandler.post(new Runnable() {
13321                @Override public void run() {
13322                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13323                }
13324            });
13325            return false;
13326        }
13327
13328        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13329                crashInfo);
13330
13331        if (r != null && r.pid != Process.myPid() &&
13332                Settings.Global.getInt(mContext.getContentResolver(),
13333                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13334            mAppErrors.crashApplication(r, crashInfo);
13335            return true;
13336        } else {
13337            return false;
13338        }
13339    }
13340
13341    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13342            final ApplicationErrorReport.CrashInfo crashInfo) {
13343        final ProcessRecord r = findAppProcess(app, "WTF");
13344        final String processName = app == null ? "system_server"
13345                : (r == null ? "unknown" : r.processName);
13346
13347        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13348                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13349
13350        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13351
13352        return r;
13353    }
13354
13355    /**
13356     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13357     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13358     */
13359    private ProcessRecord findAppProcess(IBinder app, String reason) {
13360        if (app == null) {
13361            return null;
13362        }
13363
13364        synchronized (this) {
13365            final int NP = mProcessNames.getMap().size();
13366            for (int ip=0; ip<NP; ip++) {
13367                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13368                final int NA = apps.size();
13369                for (int ia=0; ia<NA; ia++) {
13370                    ProcessRecord p = apps.valueAt(ia);
13371                    if (p.thread != null && p.thread.asBinder() == app) {
13372                        return p;
13373                    }
13374                }
13375            }
13376
13377            Slog.w(TAG, "Can't find mystery application for " + reason
13378                    + " from pid=" + Binder.getCallingPid()
13379                    + " uid=" + Binder.getCallingUid() + ": " + app);
13380            return null;
13381        }
13382    }
13383
13384    /**
13385     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13386     * to append various headers to the dropbox log text.
13387     */
13388    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13389            StringBuilder sb) {
13390        // Watchdog thread ends up invoking this function (with
13391        // a null ProcessRecord) to add the stack file to dropbox.
13392        // Do not acquire a lock on this (am) in such cases, as it
13393        // could cause a potential deadlock, if and when watchdog
13394        // is invoked due to unavailability of lock on am and it
13395        // would prevent watchdog from killing system_server.
13396        if (process == null) {
13397            sb.append("Process: ").append(processName).append("\n");
13398            return;
13399        }
13400        // Note: ProcessRecord 'process' is guarded by the service
13401        // instance.  (notably process.pkgList, which could otherwise change
13402        // concurrently during execution of this method)
13403        synchronized (this) {
13404            sb.append("Process: ").append(processName).append("\n");
13405            int flags = process.info.flags;
13406            IPackageManager pm = AppGlobals.getPackageManager();
13407            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13408            for (int ip=0; ip<process.pkgList.size(); ip++) {
13409                String pkg = process.pkgList.keyAt(ip);
13410                sb.append("Package: ").append(pkg);
13411                try {
13412                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13413                    if (pi != null) {
13414                        sb.append(" v").append(pi.versionCode);
13415                        if (pi.versionName != null) {
13416                            sb.append(" (").append(pi.versionName).append(")");
13417                        }
13418                    }
13419                } catch (RemoteException e) {
13420                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13421                }
13422                sb.append("\n");
13423            }
13424        }
13425    }
13426
13427    private static String processClass(ProcessRecord process) {
13428        if (process == null || process.pid == MY_PID) {
13429            return "system_server";
13430        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13431            return "system_app";
13432        } else {
13433            return "data_app";
13434        }
13435    }
13436
13437    private volatile long mWtfClusterStart;
13438    private volatile int mWtfClusterCount;
13439
13440    /**
13441     * Write a description of an error (crash, WTF, ANR) to the drop box.
13442     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13443     * @param process which caused the error, null means the system server
13444     * @param activity which triggered the error, null if unknown
13445     * @param parent activity related to the error, null if unknown
13446     * @param subject line related to the error, null if absent
13447     * @param report in long form describing the error, null if absent
13448     * @param logFile to include in the report, null if none
13449     * @param crashInfo giving an application stack trace, null if absent
13450     */
13451    public void addErrorToDropBox(String eventType,
13452            ProcessRecord process, String processName, ActivityRecord activity,
13453            ActivityRecord parent, String subject,
13454            final String report, final File logFile,
13455            final ApplicationErrorReport.CrashInfo crashInfo) {
13456        // NOTE -- this must never acquire the ActivityManagerService lock,
13457        // otherwise the watchdog may be prevented from resetting the system.
13458
13459        final String dropboxTag = processClass(process) + "_" + eventType;
13460        final DropBoxManager dbox = (DropBoxManager)
13461                mContext.getSystemService(Context.DROPBOX_SERVICE);
13462
13463        // Exit early if the dropbox isn't configured to accept this report type.
13464        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13465
13466        // Rate-limit how often we're willing to do the heavy lifting below to
13467        // collect and record logs; currently 5 logs per 10 second period.
13468        final long now = SystemClock.elapsedRealtime();
13469        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13470            mWtfClusterStart = now;
13471            mWtfClusterCount = 1;
13472        } else {
13473            if (mWtfClusterCount++ >= 5) return;
13474        }
13475
13476        final StringBuilder sb = new StringBuilder(1024);
13477        appendDropBoxProcessHeaders(process, processName, sb);
13478        if (process != null) {
13479            sb.append("Foreground: ")
13480                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13481                    .append("\n");
13482        }
13483        if (activity != null) {
13484            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13485        }
13486        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13487            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13488        }
13489        if (parent != null && parent != activity) {
13490            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13491        }
13492        if (subject != null) {
13493            sb.append("Subject: ").append(subject).append("\n");
13494        }
13495        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13496        if (Debug.isDebuggerConnected()) {
13497            sb.append("Debugger: Connected\n");
13498        }
13499        sb.append("\n");
13500
13501        // Do the rest in a worker thread to avoid blocking the caller on I/O
13502        // (After this point, we shouldn't access AMS internal data structures.)
13503        Thread worker = new Thread("Error dump: " + dropboxTag) {
13504            @Override
13505            public void run() {
13506                if (report != null) {
13507                    sb.append(report);
13508                }
13509                if (logFile != null) {
13510                    try {
13511                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13512                                    "\n\n[[TRUNCATED]]"));
13513                    } catch (IOException e) {
13514                        Slog.e(TAG, "Error reading " + logFile, e);
13515                    }
13516                }
13517                if (crashInfo != null && crashInfo.stackTrace != null) {
13518                    sb.append(crashInfo.stackTrace);
13519                }
13520
13521                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13522                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13523                if (lines > 0) {
13524                    sb.append("\n");
13525
13526                    // Merge several logcat streams, and take the last N lines
13527                    InputStreamReader input = null;
13528                    try {
13529                        java.lang.Process logcat = new ProcessBuilder(
13530                                "/system/bin/timeout", "-k", "15s", "10s",
13531                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13532                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13533                                        .redirectErrorStream(true).start();
13534
13535                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13536                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13537                        input = new InputStreamReader(logcat.getInputStream());
13538
13539                        int num;
13540                        char[] buf = new char[8192];
13541                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13542                    } catch (IOException e) {
13543                        Slog.e(TAG, "Error running logcat", e);
13544                    } finally {
13545                        if (input != null) try { input.close(); } catch (IOException e) {}
13546                    }
13547                }
13548
13549                dbox.addText(dropboxTag, sb.toString());
13550            }
13551        };
13552
13553        if (process == null) {
13554            // If process is null, we are being called from some internal code
13555            // and may be about to die -- run this synchronously.
13556            worker.run();
13557        } else {
13558            worker.start();
13559        }
13560    }
13561
13562    @Override
13563    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13564        enforceNotIsolatedCaller("getProcessesInErrorState");
13565        // assume our apps are happy - lazy create the list
13566        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13567
13568        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13569                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13570        int userId = UserHandle.getUserId(Binder.getCallingUid());
13571
13572        synchronized (this) {
13573
13574            // iterate across all processes
13575            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13576                ProcessRecord app = mLruProcesses.get(i);
13577                if (!allUsers && app.userId != userId) {
13578                    continue;
13579                }
13580                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13581                    // This one's in trouble, so we'll generate a report for it
13582                    // crashes are higher priority (in case there's a crash *and* an anr)
13583                    ActivityManager.ProcessErrorStateInfo report = null;
13584                    if (app.crashing) {
13585                        report = app.crashingReport;
13586                    } else if (app.notResponding) {
13587                        report = app.notRespondingReport;
13588                    }
13589
13590                    if (report != null) {
13591                        if (errList == null) {
13592                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13593                        }
13594                        errList.add(report);
13595                    } else {
13596                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13597                                " crashing = " + app.crashing +
13598                                " notResponding = " + app.notResponding);
13599                    }
13600                }
13601            }
13602        }
13603
13604        return errList;
13605    }
13606
13607    static int procStateToImportance(int procState, int memAdj,
13608            ActivityManager.RunningAppProcessInfo currApp) {
13609        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13610        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13611            currApp.lru = memAdj;
13612        } else {
13613            currApp.lru = 0;
13614        }
13615        return imp;
13616    }
13617
13618    private void fillInProcMemInfo(ProcessRecord app,
13619            ActivityManager.RunningAppProcessInfo outInfo) {
13620        outInfo.pid = app.pid;
13621        outInfo.uid = app.info.uid;
13622        if (mHeavyWeightProcess == app) {
13623            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13624        }
13625        if (app.persistent) {
13626            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13627        }
13628        if (app.activities.size() > 0) {
13629            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13630        }
13631        outInfo.lastTrimLevel = app.trimMemoryLevel;
13632        int adj = app.curAdj;
13633        int procState = app.curProcState;
13634        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13635        outInfo.importanceReasonCode = app.adjTypeCode;
13636        outInfo.processState = app.curProcState;
13637    }
13638
13639    @Override
13640    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13641        enforceNotIsolatedCaller("getRunningAppProcesses");
13642
13643        final int callingUid = Binder.getCallingUid();
13644
13645        // Lazy instantiation of list
13646        List<ActivityManager.RunningAppProcessInfo> runList = null;
13647        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13648                callingUid) == PackageManager.PERMISSION_GRANTED;
13649        final int userId = UserHandle.getUserId(callingUid);
13650        final boolean allUids = isGetTasksAllowed(
13651                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13652
13653        synchronized (this) {
13654            // Iterate across all processes
13655            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13656                ProcessRecord app = mLruProcesses.get(i);
13657                if ((!allUsers && app.userId != userId)
13658                        || (!allUids && app.uid != callingUid)) {
13659                    continue;
13660                }
13661                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13662                    // Generate process state info for running application
13663                    ActivityManager.RunningAppProcessInfo currApp =
13664                        new ActivityManager.RunningAppProcessInfo(app.processName,
13665                                app.pid, app.getPackageList());
13666                    fillInProcMemInfo(app, currApp);
13667                    if (app.adjSource instanceof ProcessRecord) {
13668                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13669                        currApp.importanceReasonImportance =
13670                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13671                                        app.adjSourceProcState);
13672                    } else if (app.adjSource instanceof ActivityRecord) {
13673                        ActivityRecord r = (ActivityRecord)app.adjSource;
13674                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13675                    }
13676                    if (app.adjTarget instanceof ComponentName) {
13677                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13678                    }
13679                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13680                    //        + " lru=" + currApp.lru);
13681                    if (runList == null) {
13682                        runList = new ArrayList<>();
13683                    }
13684                    runList.add(currApp);
13685                }
13686            }
13687        }
13688        return runList;
13689    }
13690
13691    @Override
13692    public List<ApplicationInfo> getRunningExternalApplications() {
13693        enforceNotIsolatedCaller("getRunningExternalApplications");
13694        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13695        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13696        if (runningApps != null && runningApps.size() > 0) {
13697            Set<String> extList = new HashSet<String>();
13698            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13699                if (app.pkgList != null) {
13700                    for (String pkg : app.pkgList) {
13701                        extList.add(pkg);
13702                    }
13703                }
13704            }
13705            IPackageManager pm = AppGlobals.getPackageManager();
13706            for (String pkg : extList) {
13707                try {
13708                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13709                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13710                        retList.add(info);
13711                    }
13712                } catch (RemoteException e) {
13713                }
13714            }
13715        }
13716        return retList;
13717    }
13718
13719    @Override
13720    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13721        enforceNotIsolatedCaller("getMyMemoryState");
13722        synchronized (this) {
13723            ProcessRecord proc;
13724            synchronized (mPidsSelfLocked) {
13725                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13726            }
13727            fillInProcMemInfo(proc, outInfo);
13728        }
13729    }
13730
13731    @Override
13732    public int getMemoryTrimLevel() {
13733        enforceNotIsolatedCaller("getMyMemoryState");
13734        synchronized (this) {
13735            return mLastMemoryLevel;
13736        }
13737    }
13738
13739    @Override
13740    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13741            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13742        (new ActivityManagerShellCommand(this, false)).exec(
13743                this, in, out, err, args, resultReceiver);
13744    }
13745
13746    @Override
13747    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13748        if (checkCallingPermission(android.Manifest.permission.DUMP)
13749                != PackageManager.PERMISSION_GRANTED) {
13750            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13751                    + Binder.getCallingPid()
13752                    + ", uid=" + Binder.getCallingUid()
13753                    + " without permission "
13754                    + android.Manifest.permission.DUMP);
13755            return;
13756        }
13757
13758        boolean dumpAll = false;
13759        boolean dumpClient = false;
13760        String dumpPackage = null;
13761
13762        int opti = 0;
13763        while (opti < args.length) {
13764            String opt = args[opti];
13765            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13766                break;
13767            }
13768            opti++;
13769            if ("-a".equals(opt)) {
13770                dumpAll = true;
13771            } else if ("-c".equals(opt)) {
13772                dumpClient = true;
13773            } else if ("-p".equals(opt)) {
13774                if (opti < args.length) {
13775                    dumpPackage = args[opti];
13776                    opti++;
13777                } else {
13778                    pw.println("Error: -p option requires package argument");
13779                    return;
13780                }
13781                dumpClient = true;
13782            } else if ("-h".equals(opt)) {
13783                ActivityManagerShellCommand.dumpHelp(pw, true);
13784                return;
13785            } else {
13786                pw.println("Unknown argument: " + opt + "; use -h for help");
13787            }
13788        }
13789
13790        long origId = Binder.clearCallingIdentity();
13791        boolean more = false;
13792        // Is the caller requesting to dump a particular piece of data?
13793        if (opti < args.length) {
13794            String cmd = args[opti];
13795            opti++;
13796            if ("activities".equals(cmd) || "a".equals(cmd)) {
13797                synchronized (this) {
13798                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13799                }
13800            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13801                synchronized (this) {
13802                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13803                }
13804            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13805                String[] newArgs;
13806                String name;
13807                if (opti >= args.length) {
13808                    name = null;
13809                    newArgs = EMPTY_STRING_ARRAY;
13810                } else {
13811                    dumpPackage = args[opti];
13812                    opti++;
13813                    newArgs = new String[args.length - opti];
13814                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13815                            args.length - opti);
13816                }
13817                synchronized (this) {
13818                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13819                }
13820            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13821                String[] newArgs;
13822                String name;
13823                if (opti >= args.length) {
13824                    name = null;
13825                    newArgs = EMPTY_STRING_ARRAY;
13826                } else {
13827                    dumpPackage = args[opti];
13828                    opti++;
13829                    newArgs = new String[args.length - opti];
13830                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13831                            args.length - opti);
13832                }
13833                synchronized (this) {
13834                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13835                }
13836            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13837                String[] newArgs;
13838                String name;
13839                if (opti >= args.length) {
13840                    name = null;
13841                    newArgs = EMPTY_STRING_ARRAY;
13842                } else {
13843                    dumpPackage = args[opti];
13844                    opti++;
13845                    newArgs = new String[args.length - opti];
13846                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13847                            args.length - opti);
13848                }
13849                synchronized (this) {
13850                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13851                }
13852            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13853                synchronized (this) {
13854                    dumpOomLocked(fd, pw, args, opti, true);
13855                }
13856            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13857                synchronized (this) {
13858                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13859                }
13860            } else if ("provider".equals(cmd)) {
13861                String[] newArgs;
13862                String name;
13863                if (opti >= args.length) {
13864                    name = null;
13865                    newArgs = EMPTY_STRING_ARRAY;
13866                } else {
13867                    name = args[opti];
13868                    opti++;
13869                    newArgs = new String[args.length - opti];
13870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13871                }
13872                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13873                    pw.println("No providers match: " + name);
13874                    pw.println("Use -h for help.");
13875                }
13876            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13877                synchronized (this) {
13878                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13879                }
13880            } else if ("service".equals(cmd)) {
13881                String[] newArgs;
13882                String name;
13883                if (opti >= args.length) {
13884                    name = null;
13885                    newArgs = EMPTY_STRING_ARRAY;
13886                } else {
13887                    name = args[opti];
13888                    opti++;
13889                    newArgs = new String[args.length - opti];
13890                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13891                            args.length - opti);
13892                }
13893                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13894                    pw.println("No services match: " + name);
13895                    pw.println("Use -h for help.");
13896                }
13897            } else if ("package".equals(cmd)) {
13898                String[] newArgs;
13899                if (opti >= args.length) {
13900                    pw.println("package: no package name specified");
13901                    pw.println("Use -h for help.");
13902                } else {
13903                    dumpPackage = args[opti];
13904                    opti++;
13905                    newArgs = new String[args.length - opti];
13906                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13907                            args.length - opti);
13908                    args = newArgs;
13909                    opti = 0;
13910                    more = true;
13911                }
13912            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13913                synchronized (this) {
13914                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13915                }
13916            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13917                if (dumpClient) {
13918                    ActiveServices.ServiceDumper dumper;
13919                    synchronized (this) {
13920                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13921                                dumpPackage);
13922                    }
13923                    dumper.dumpWithClient();
13924                } else {
13925                    synchronized (this) {
13926                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13927                                dumpPackage).dumpLocked();
13928                    }
13929                }
13930            } else if ("locks".equals(cmd)) {
13931                LockGuard.dump(fd, pw, args);
13932            } else {
13933                // Dumping a single activity?
13934                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13935                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13936                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13937                    if (res < 0) {
13938                        pw.println("Bad activity command, or no activities match: " + cmd);
13939                        pw.println("Use -h for help.");
13940                    }
13941                }
13942            }
13943            if (!more) {
13944                Binder.restoreCallingIdentity(origId);
13945                return;
13946            }
13947        }
13948
13949        // No piece of data specified, dump everything.
13950        if (dumpClient) {
13951            ActiveServices.ServiceDumper sdumper;
13952            synchronized (this) {
13953                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13954                pw.println();
13955                if (dumpAll) {
13956                    pw.println("-------------------------------------------------------------------------------");
13957                }
13958                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13959                pw.println();
13960                if (dumpAll) {
13961                    pw.println("-------------------------------------------------------------------------------");
13962                }
13963                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13964                pw.println();
13965                if (dumpAll) {
13966                    pw.println("-------------------------------------------------------------------------------");
13967                }
13968                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13969                pw.println();
13970                if (dumpAll) {
13971                    pw.println("-------------------------------------------------------------------------------");
13972                }
13973                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13974                        dumpPackage);
13975            }
13976            sdumper.dumpWithClient();
13977            pw.println();
13978            synchronized (this) {
13979                if (dumpAll) {
13980                    pw.println("-------------------------------------------------------------------------------");
13981                }
13982                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13983                pw.println();
13984                if (dumpAll) {
13985                    pw.println("-------------------------------------------------------------------------------");
13986                }
13987                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13988                if (mAssociations.size() > 0) {
13989                    pw.println();
13990                    if (dumpAll) {
13991                        pw.println("-------------------------------------------------------------------------------");
13992                    }
13993                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13994                }
13995                pw.println();
13996                if (dumpAll) {
13997                    pw.println("-------------------------------------------------------------------------------");
13998                }
13999                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14000            }
14001
14002        } else {
14003            synchronized (this) {
14004                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14005                pw.println();
14006                if (dumpAll) {
14007                    pw.println("-------------------------------------------------------------------------------");
14008                }
14009                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14010                pw.println();
14011                if (dumpAll) {
14012                    pw.println("-------------------------------------------------------------------------------");
14013                }
14014                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14015                pw.println();
14016                if (dumpAll) {
14017                    pw.println("-------------------------------------------------------------------------------");
14018                }
14019                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14020                pw.println();
14021                if (dumpAll) {
14022                    pw.println("-------------------------------------------------------------------------------");
14023                }
14024                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14025                        .dumpLocked();
14026                pw.println();
14027                if (dumpAll) {
14028                    pw.println("-------------------------------------------------------------------------------");
14029                }
14030                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14031                pw.println();
14032                if (dumpAll) {
14033                    pw.println("-------------------------------------------------------------------------------");
14034                }
14035                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14036                if (mAssociations.size() > 0) {
14037                    pw.println();
14038                    if (dumpAll) {
14039                        pw.println("-------------------------------------------------------------------------------");
14040                    }
14041                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14042                }
14043                pw.println();
14044                if (dumpAll) {
14045                    pw.println("-------------------------------------------------------------------------------");
14046                }
14047                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14048            }
14049        }
14050        Binder.restoreCallingIdentity(origId);
14051    }
14052
14053    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14054            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14055        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14056
14057        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14058                dumpPackage);
14059        boolean needSep = printedAnything;
14060
14061        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14062                dumpPackage, needSep, "  mFocusedActivity: ");
14063        if (printed) {
14064            printedAnything = true;
14065            needSep = false;
14066        }
14067
14068        if (dumpPackage == null) {
14069            if (needSep) {
14070                pw.println();
14071            }
14072            needSep = true;
14073            printedAnything = true;
14074            mStackSupervisor.dump(pw, "  ");
14075        }
14076
14077        if (!printedAnything) {
14078            pw.println("  (nothing)");
14079        }
14080    }
14081
14082    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14083            int opti, boolean dumpAll, String dumpPackage) {
14084        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14085
14086        boolean printedAnything = false;
14087
14088        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14089            boolean printedHeader = false;
14090
14091            final int N = mRecentTasks.size();
14092            for (int i=0; i<N; i++) {
14093                TaskRecord tr = mRecentTasks.get(i);
14094                if (dumpPackage != null) {
14095                    if (tr.realActivity == null ||
14096                            !dumpPackage.equals(tr.realActivity)) {
14097                        continue;
14098                    }
14099                }
14100                if (!printedHeader) {
14101                    pw.println("  Recent tasks:");
14102                    printedHeader = true;
14103                    printedAnything = true;
14104                }
14105                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14106                        pw.println(tr);
14107                if (dumpAll) {
14108                    mRecentTasks.get(i).dump(pw, "    ");
14109                }
14110            }
14111        }
14112
14113        if (!printedAnything) {
14114            pw.println("  (nothing)");
14115        }
14116    }
14117
14118    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14119            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14120        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14121
14122        int dumpUid = 0;
14123        if (dumpPackage != null) {
14124            IPackageManager pm = AppGlobals.getPackageManager();
14125            try {
14126                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14127            } catch (RemoteException e) {
14128            }
14129        }
14130
14131        boolean printedAnything = false;
14132
14133        final long now = SystemClock.uptimeMillis();
14134
14135        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14136            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14137                    = mAssociations.valueAt(i1);
14138            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14139                SparseArray<ArrayMap<String, Association>> sourceUids
14140                        = targetComponents.valueAt(i2);
14141                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14142                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14143                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14144                        Association ass = sourceProcesses.valueAt(i4);
14145                        if (dumpPackage != null) {
14146                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14147                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14148                                continue;
14149                            }
14150                        }
14151                        printedAnything = true;
14152                        pw.print("  ");
14153                        pw.print(ass.mTargetProcess);
14154                        pw.print("/");
14155                        UserHandle.formatUid(pw, ass.mTargetUid);
14156                        pw.print(" <- ");
14157                        pw.print(ass.mSourceProcess);
14158                        pw.print("/");
14159                        UserHandle.formatUid(pw, ass.mSourceUid);
14160                        pw.println();
14161                        pw.print("    via ");
14162                        pw.print(ass.mTargetComponent.flattenToShortString());
14163                        pw.println();
14164                        pw.print("    ");
14165                        long dur = ass.mTime;
14166                        if (ass.mNesting > 0) {
14167                            dur += now - ass.mStartTime;
14168                        }
14169                        TimeUtils.formatDuration(dur, pw);
14170                        pw.print(" (");
14171                        pw.print(ass.mCount);
14172                        pw.print(" times)");
14173                        pw.print("  ");
14174                        for (int i=0; i<ass.mStateTimes.length; i++) {
14175                            long amt = ass.mStateTimes[i];
14176                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14177                                amt += now - ass.mLastStateUptime;
14178                            }
14179                            if (amt != 0) {
14180                                pw.print(" ");
14181                                pw.print(ProcessList.makeProcStateString(
14182                                            i + ActivityManager.MIN_PROCESS_STATE));
14183                                pw.print("=");
14184                                TimeUtils.formatDuration(amt, pw);
14185                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14186                                    pw.print("*");
14187                                }
14188                            }
14189                        }
14190                        pw.println();
14191                        if (ass.mNesting > 0) {
14192                            pw.print("    Currently active: ");
14193                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14194                            pw.println();
14195                        }
14196                    }
14197                }
14198            }
14199
14200        }
14201
14202        if (!printedAnything) {
14203            pw.println("  (nothing)");
14204        }
14205    }
14206
14207    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14208            String header, boolean needSep) {
14209        boolean printed = false;
14210        int whichAppId = -1;
14211        if (dumpPackage != null) {
14212            try {
14213                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14214                        dumpPackage, 0);
14215                whichAppId = UserHandle.getAppId(info.uid);
14216            } catch (NameNotFoundException e) {
14217                e.printStackTrace();
14218            }
14219        }
14220        for (int i=0; i<uids.size(); i++) {
14221            UidRecord uidRec = uids.valueAt(i);
14222            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14223                continue;
14224            }
14225            if (!printed) {
14226                printed = true;
14227                if (needSep) {
14228                    pw.println();
14229                }
14230                pw.print("  ");
14231                pw.println(header);
14232                needSep = true;
14233            }
14234            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14235            pw.print(": "); pw.println(uidRec);
14236        }
14237        return printed;
14238    }
14239
14240    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14241            int opti, boolean dumpAll, String dumpPackage) {
14242        boolean needSep = false;
14243        boolean printedAnything = false;
14244        int numPers = 0;
14245
14246        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14247
14248        if (dumpAll) {
14249            final int NP = mProcessNames.getMap().size();
14250            for (int ip=0; ip<NP; ip++) {
14251                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14252                final int NA = procs.size();
14253                for (int ia=0; ia<NA; ia++) {
14254                    ProcessRecord r = procs.valueAt(ia);
14255                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14256                        continue;
14257                    }
14258                    if (!needSep) {
14259                        pw.println("  All known processes:");
14260                        needSep = true;
14261                        printedAnything = true;
14262                    }
14263                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14264                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14265                        pw.print(" "); pw.println(r);
14266                    r.dump(pw, "    ");
14267                    if (r.persistent) {
14268                        numPers++;
14269                    }
14270                }
14271            }
14272        }
14273
14274        if (mIsolatedProcesses.size() > 0) {
14275            boolean printed = false;
14276            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14277                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14278                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14279                    continue;
14280                }
14281                if (!printed) {
14282                    if (needSep) {
14283                        pw.println();
14284                    }
14285                    pw.println("  Isolated process list (sorted by uid):");
14286                    printedAnything = true;
14287                    printed = true;
14288                    needSep = true;
14289                }
14290                pw.println(String.format("%sIsolated #%2d: %s",
14291                        "    ", i, r.toString()));
14292            }
14293        }
14294
14295        if (mActiveUids.size() > 0) {
14296            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14297                printedAnything = needSep = true;
14298            }
14299        }
14300        if (mValidateUids.size() > 0) {
14301            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14302                printedAnything = needSep = true;
14303            }
14304        }
14305
14306        if (mLruProcesses.size() > 0) {
14307            if (needSep) {
14308                pw.println();
14309            }
14310            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14311                    pw.print(" total, non-act at ");
14312                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14313                    pw.print(", non-svc at ");
14314                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14315                    pw.println("):");
14316            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14317            needSep = true;
14318            printedAnything = true;
14319        }
14320
14321        if (dumpAll || dumpPackage != null) {
14322            synchronized (mPidsSelfLocked) {
14323                boolean printed = false;
14324                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14325                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14326                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14327                        continue;
14328                    }
14329                    if (!printed) {
14330                        if (needSep) pw.println();
14331                        needSep = true;
14332                        pw.println("  PID mappings:");
14333                        printed = true;
14334                        printedAnything = true;
14335                    }
14336                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14337                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14338                }
14339            }
14340        }
14341
14342        if (mForegroundProcesses.size() > 0) {
14343            synchronized (mPidsSelfLocked) {
14344                boolean printed = false;
14345                for (int i=0; i<mForegroundProcesses.size(); i++) {
14346                    ProcessRecord r = mPidsSelfLocked.get(
14347                            mForegroundProcesses.valueAt(i).pid);
14348                    if (dumpPackage != null && (r == null
14349                            || !r.pkgList.containsKey(dumpPackage))) {
14350                        continue;
14351                    }
14352                    if (!printed) {
14353                        if (needSep) pw.println();
14354                        needSep = true;
14355                        pw.println("  Foreground Processes:");
14356                        printed = true;
14357                        printedAnything = true;
14358                    }
14359                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14360                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14361                }
14362            }
14363        }
14364
14365        if (mPersistentStartingProcesses.size() > 0) {
14366            if (needSep) pw.println();
14367            needSep = true;
14368            printedAnything = true;
14369            pw.println("  Persisent processes that are starting:");
14370            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14371                    "Starting Norm", "Restarting PERS", dumpPackage);
14372        }
14373
14374        if (mRemovedProcesses.size() > 0) {
14375            if (needSep) pw.println();
14376            needSep = true;
14377            printedAnything = true;
14378            pw.println("  Processes that are being removed:");
14379            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14380                    "Removed Norm", "Removed PERS", dumpPackage);
14381        }
14382
14383        if (mProcessesOnHold.size() > 0) {
14384            if (needSep) pw.println();
14385            needSep = true;
14386            printedAnything = true;
14387            pw.println("  Processes that are on old until the system is ready:");
14388            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14389                    "OnHold Norm", "OnHold PERS", dumpPackage);
14390        }
14391
14392        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14393
14394        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14395        if (needSep) {
14396            printedAnything = true;
14397        }
14398
14399        if (dumpPackage == null) {
14400            pw.println();
14401            needSep = false;
14402            mUserController.dump(pw, dumpAll);
14403        }
14404        if (mHomeProcess != null && (dumpPackage == null
14405                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14406            if (needSep) {
14407                pw.println();
14408                needSep = false;
14409            }
14410            pw.println("  mHomeProcess: " + mHomeProcess);
14411        }
14412        if (mPreviousProcess != null && (dumpPackage == null
14413                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14414            if (needSep) {
14415                pw.println();
14416                needSep = false;
14417            }
14418            pw.println("  mPreviousProcess: " + mPreviousProcess);
14419        }
14420        if (dumpAll) {
14421            StringBuilder sb = new StringBuilder(128);
14422            sb.append("  mPreviousProcessVisibleTime: ");
14423            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14424            pw.println(sb);
14425        }
14426        if (mHeavyWeightProcess != null && (dumpPackage == null
14427                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14428            if (needSep) {
14429                pw.println();
14430                needSep = false;
14431            }
14432            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14433        }
14434        if (dumpPackage == null) {
14435            pw.println("  mConfiguration: " + mConfiguration);
14436        }
14437        if (dumpAll) {
14438            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14439            if (mCompatModePackages.getPackages().size() > 0) {
14440                boolean printed = false;
14441                for (Map.Entry<String, Integer> entry
14442                        : mCompatModePackages.getPackages().entrySet()) {
14443                    String pkg = entry.getKey();
14444                    int mode = entry.getValue();
14445                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14446                        continue;
14447                    }
14448                    if (!printed) {
14449                        pw.println("  mScreenCompatPackages:");
14450                        printed = true;
14451                    }
14452                    pw.print("    "); pw.print(pkg); pw.print(": ");
14453                            pw.print(mode); pw.println();
14454                }
14455            }
14456        }
14457        if (dumpPackage == null) {
14458            pw.println("  mWakefulness="
14459                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14460            pw.println("  mSleepTokens=" + mSleepTokens);
14461            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14462                    + lockScreenShownToString());
14463            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14464            if (mRunningVoice != null) {
14465                pw.println("  mRunningVoice=" + mRunningVoice);
14466                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14467            }
14468        }
14469        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14470                || mOrigWaitForDebugger) {
14471            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14472                    || dumpPackage.equals(mOrigDebugApp)) {
14473                if (needSep) {
14474                    pw.println();
14475                    needSep = false;
14476                }
14477                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14478                        + " mDebugTransient=" + mDebugTransient
14479                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14480            }
14481        }
14482        if (mCurAppTimeTracker != null) {
14483            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14484        }
14485        if (mMemWatchProcesses.getMap().size() > 0) {
14486            pw.println("  Mem watch processes:");
14487            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14488                    = mMemWatchProcesses.getMap();
14489            for (int i=0; i<procs.size(); i++) {
14490                final String proc = procs.keyAt(i);
14491                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14492                for (int j=0; j<uids.size(); j++) {
14493                    if (needSep) {
14494                        pw.println();
14495                        needSep = false;
14496                    }
14497                    StringBuilder sb = new StringBuilder();
14498                    sb.append("    ").append(proc).append('/');
14499                    UserHandle.formatUid(sb, uids.keyAt(j));
14500                    Pair<Long, String> val = uids.valueAt(j);
14501                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14502                    if (val.second != null) {
14503                        sb.append(", report to ").append(val.second);
14504                    }
14505                    pw.println(sb.toString());
14506                }
14507            }
14508            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14509            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14510            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14511                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14512        }
14513        if (mTrackAllocationApp != null) {
14514            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14515                if (needSep) {
14516                    pw.println();
14517                    needSep = false;
14518                }
14519                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14520            }
14521        }
14522        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14523                || mProfileFd != null) {
14524            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14525                if (needSep) {
14526                    pw.println();
14527                    needSep = false;
14528                }
14529                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14530                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14531                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14532                        + mAutoStopProfiler);
14533                pw.println("  mProfileType=" + mProfileType);
14534            }
14535        }
14536        if (mNativeDebuggingApp != null) {
14537            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14538                if (needSep) {
14539                    pw.println();
14540                    needSep = false;
14541                }
14542                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14543            }
14544        }
14545        if (dumpPackage == null) {
14546            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14547                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14548                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14549            }
14550            if (mController != null) {
14551                pw.println("  mController=" + mController
14552                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14553            }
14554            if (dumpAll) {
14555                pw.println("  Total persistent processes: " + numPers);
14556                pw.println("  mProcessesReady=" + mProcessesReady
14557                        + " mSystemReady=" + mSystemReady
14558                        + " mBooted=" + mBooted
14559                        + " mFactoryTest=" + mFactoryTest);
14560                pw.println("  mBooting=" + mBooting
14561                        + " mCallFinishBooting=" + mCallFinishBooting
14562                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14563                pw.print("  mLastPowerCheckRealtime=");
14564                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14565                        pw.println("");
14566                pw.print("  mLastPowerCheckUptime=");
14567                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14568                        pw.println("");
14569                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14570                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14571                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14572                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14573                        + " (" + mLruProcesses.size() + " total)"
14574                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14575                        + " mNumServiceProcs=" + mNumServiceProcs
14576                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14577                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14578                        + " mLastMemoryLevel=" + mLastMemoryLevel
14579                        + " mLastNumProcesses=" + mLastNumProcesses);
14580                long now = SystemClock.uptimeMillis();
14581                pw.print("  mLastIdleTime=");
14582                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14583                        pw.print(" mLowRamSinceLastIdle=");
14584                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14585                        pw.println();
14586            }
14587        }
14588
14589        if (!printedAnything) {
14590            pw.println("  (nothing)");
14591        }
14592    }
14593
14594    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14595            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14596        if (mProcessesToGc.size() > 0) {
14597            boolean printed = false;
14598            long now = SystemClock.uptimeMillis();
14599            for (int i=0; i<mProcessesToGc.size(); i++) {
14600                ProcessRecord proc = mProcessesToGc.get(i);
14601                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14602                    continue;
14603                }
14604                if (!printed) {
14605                    if (needSep) pw.println();
14606                    needSep = true;
14607                    pw.println("  Processes that are waiting to GC:");
14608                    printed = true;
14609                }
14610                pw.print("    Process "); pw.println(proc);
14611                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14612                        pw.print(", last gced=");
14613                        pw.print(now-proc.lastRequestedGc);
14614                        pw.print(" ms ago, last lowMem=");
14615                        pw.print(now-proc.lastLowMemory);
14616                        pw.println(" ms ago");
14617
14618            }
14619        }
14620        return needSep;
14621    }
14622
14623    void printOomLevel(PrintWriter pw, String name, int adj) {
14624        pw.print("    ");
14625        if (adj >= 0) {
14626            pw.print(' ');
14627            if (adj < 10) pw.print(' ');
14628        } else {
14629            if (adj > -10) pw.print(' ');
14630        }
14631        pw.print(adj);
14632        pw.print(": ");
14633        pw.print(name);
14634        pw.print(" (");
14635        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14636        pw.println(")");
14637    }
14638
14639    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14640            int opti, boolean dumpAll) {
14641        boolean needSep = false;
14642
14643        if (mLruProcesses.size() > 0) {
14644            if (needSep) pw.println();
14645            needSep = true;
14646            pw.println("  OOM levels:");
14647            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14648            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14649            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14650            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14651            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14652            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14653            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14654            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14655            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14656            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14657            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14658            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14659            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14660            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14661
14662            if (needSep) pw.println();
14663            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14664                    pw.print(" total, non-act at ");
14665                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14666                    pw.print(", non-svc at ");
14667                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14668                    pw.println("):");
14669            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14670            needSep = true;
14671        }
14672
14673        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14674
14675        pw.println();
14676        pw.println("  mHomeProcess: " + mHomeProcess);
14677        pw.println("  mPreviousProcess: " + mPreviousProcess);
14678        if (mHeavyWeightProcess != null) {
14679            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14680        }
14681
14682        return true;
14683    }
14684
14685    /**
14686     * There are three ways to call this:
14687     *  - no provider specified: dump all the providers
14688     *  - a flattened component name that matched an existing provider was specified as the
14689     *    first arg: dump that one provider
14690     *  - the first arg isn't the flattened component name of an existing provider:
14691     *    dump all providers whose component contains the first arg as a substring
14692     */
14693    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14694            int opti, boolean dumpAll) {
14695        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14696    }
14697
14698    static class ItemMatcher {
14699        ArrayList<ComponentName> components;
14700        ArrayList<String> strings;
14701        ArrayList<Integer> objects;
14702        boolean all;
14703
14704        ItemMatcher() {
14705            all = true;
14706        }
14707
14708        void build(String name) {
14709            ComponentName componentName = ComponentName.unflattenFromString(name);
14710            if (componentName != null) {
14711                if (components == null) {
14712                    components = new ArrayList<ComponentName>();
14713                }
14714                components.add(componentName);
14715                all = false;
14716            } else {
14717                int objectId = 0;
14718                // Not a '/' separated full component name; maybe an object ID?
14719                try {
14720                    objectId = Integer.parseInt(name, 16);
14721                    if (objects == null) {
14722                        objects = new ArrayList<Integer>();
14723                    }
14724                    objects.add(objectId);
14725                    all = false;
14726                } catch (RuntimeException e) {
14727                    // Not an integer; just do string match.
14728                    if (strings == null) {
14729                        strings = new ArrayList<String>();
14730                    }
14731                    strings.add(name);
14732                    all = false;
14733                }
14734            }
14735        }
14736
14737        int build(String[] args, int opti) {
14738            for (; opti<args.length; opti++) {
14739                String name = args[opti];
14740                if ("--".equals(name)) {
14741                    return opti+1;
14742                }
14743                build(name);
14744            }
14745            return opti;
14746        }
14747
14748        boolean match(Object object, ComponentName comp) {
14749            if (all) {
14750                return true;
14751            }
14752            if (components != null) {
14753                for (int i=0; i<components.size(); i++) {
14754                    if (components.get(i).equals(comp)) {
14755                        return true;
14756                    }
14757                }
14758            }
14759            if (objects != null) {
14760                for (int i=0; i<objects.size(); i++) {
14761                    if (System.identityHashCode(object) == objects.get(i)) {
14762                        return true;
14763                    }
14764                }
14765            }
14766            if (strings != null) {
14767                String flat = comp.flattenToString();
14768                for (int i=0; i<strings.size(); i++) {
14769                    if (flat.contains(strings.get(i))) {
14770                        return true;
14771                    }
14772                }
14773            }
14774            return false;
14775        }
14776    }
14777
14778    /**
14779     * There are three things that cmd can be:
14780     *  - a flattened component name that matches an existing activity
14781     *  - the cmd arg isn't the flattened component name of an existing activity:
14782     *    dump all activity whose component contains the cmd as a substring
14783     *  - A hex number of the ActivityRecord object instance.
14784     */
14785    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14786            int opti, boolean dumpAll) {
14787        ArrayList<ActivityRecord> activities;
14788
14789        synchronized (this) {
14790            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14791        }
14792
14793        if (activities.size() <= 0) {
14794            return false;
14795        }
14796
14797        String[] newArgs = new String[args.length - opti];
14798        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14799
14800        TaskRecord lastTask = null;
14801        boolean needSep = false;
14802        for (int i=activities.size()-1; i>=0; i--) {
14803            ActivityRecord r = activities.get(i);
14804            if (needSep) {
14805                pw.println();
14806            }
14807            needSep = true;
14808            synchronized (this) {
14809                if (lastTask != r.task) {
14810                    lastTask = r.task;
14811                    pw.print("TASK "); pw.print(lastTask.affinity);
14812                            pw.print(" id="); pw.println(lastTask.taskId);
14813                    if (dumpAll) {
14814                        lastTask.dump(pw, "  ");
14815                    }
14816                }
14817            }
14818            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14819        }
14820        return true;
14821    }
14822
14823    /**
14824     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14825     * there is a thread associated with the activity.
14826     */
14827    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14828            final ActivityRecord r, String[] args, boolean dumpAll) {
14829        String innerPrefix = prefix + "  ";
14830        synchronized (this) {
14831            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14832                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14833                    pw.print(" pid=");
14834                    if (r.app != null) pw.println(r.app.pid);
14835                    else pw.println("(not running)");
14836            if (dumpAll) {
14837                r.dump(pw, innerPrefix);
14838            }
14839        }
14840        if (r.app != null && r.app.thread != null) {
14841            // flush anything that is already in the PrintWriter since the thread is going
14842            // to write to the file descriptor directly
14843            pw.flush();
14844            try {
14845                TransferPipe tp = new TransferPipe();
14846                try {
14847                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14848                            r.appToken, innerPrefix, args);
14849                    tp.go(fd);
14850                } finally {
14851                    tp.kill();
14852                }
14853            } catch (IOException e) {
14854                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14855            } catch (RemoteException e) {
14856                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14857            }
14858        }
14859    }
14860
14861    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14862            int opti, boolean dumpAll, String dumpPackage) {
14863        boolean needSep = false;
14864        boolean onlyHistory = false;
14865        boolean printedAnything = false;
14866
14867        if ("history".equals(dumpPackage)) {
14868            if (opti < args.length && "-s".equals(args[opti])) {
14869                dumpAll = false;
14870            }
14871            onlyHistory = true;
14872            dumpPackage = null;
14873        }
14874
14875        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14876        if (!onlyHistory && dumpAll) {
14877            if (mRegisteredReceivers.size() > 0) {
14878                boolean printed = false;
14879                Iterator it = mRegisteredReceivers.values().iterator();
14880                while (it.hasNext()) {
14881                    ReceiverList r = (ReceiverList)it.next();
14882                    if (dumpPackage != null && (r.app == null ||
14883                            !dumpPackage.equals(r.app.info.packageName))) {
14884                        continue;
14885                    }
14886                    if (!printed) {
14887                        pw.println("  Registered Receivers:");
14888                        needSep = true;
14889                        printed = true;
14890                        printedAnything = true;
14891                    }
14892                    pw.print("  * "); pw.println(r);
14893                    r.dump(pw, "    ");
14894                }
14895            }
14896
14897            if (mReceiverResolver.dump(pw, needSep ?
14898                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14899                    "    ", dumpPackage, false, false)) {
14900                needSep = true;
14901                printedAnything = true;
14902            }
14903        }
14904
14905        for (BroadcastQueue q : mBroadcastQueues) {
14906            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14907            printedAnything |= needSep;
14908        }
14909
14910        needSep = true;
14911
14912        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14913            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14914                if (needSep) {
14915                    pw.println();
14916                }
14917                needSep = true;
14918                printedAnything = true;
14919                pw.print("  Sticky broadcasts for user ");
14920                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14921                StringBuilder sb = new StringBuilder(128);
14922                for (Map.Entry<String, ArrayList<Intent>> ent
14923                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14924                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14925                    if (dumpAll) {
14926                        pw.println(":");
14927                        ArrayList<Intent> intents = ent.getValue();
14928                        final int N = intents.size();
14929                        for (int i=0; i<N; i++) {
14930                            sb.setLength(0);
14931                            sb.append("    Intent: ");
14932                            intents.get(i).toShortString(sb, false, true, false, false);
14933                            pw.println(sb.toString());
14934                            Bundle bundle = intents.get(i).getExtras();
14935                            if (bundle != null) {
14936                                pw.print("      ");
14937                                pw.println(bundle.toString());
14938                            }
14939                        }
14940                    } else {
14941                        pw.println("");
14942                    }
14943                }
14944            }
14945        }
14946
14947        if (!onlyHistory && dumpAll) {
14948            pw.println();
14949            for (BroadcastQueue queue : mBroadcastQueues) {
14950                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14951                        + queue.mBroadcastsScheduled);
14952            }
14953            pw.println("  mHandler:");
14954            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14955            needSep = true;
14956            printedAnything = true;
14957        }
14958
14959        if (!printedAnything) {
14960            pw.println("  (nothing)");
14961        }
14962    }
14963
14964    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14965            int opti, boolean dumpAll, String dumpPackage) {
14966        boolean needSep;
14967        boolean printedAnything = false;
14968
14969        ItemMatcher matcher = new ItemMatcher();
14970        matcher.build(args, opti);
14971
14972        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14973
14974        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14975        printedAnything |= needSep;
14976
14977        if (mLaunchingProviders.size() > 0) {
14978            boolean printed = false;
14979            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14980                ContentProviderRecord r = mLaunchingProviders.get(i);
14981                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14982                    continue;
14983                }
14984                if (!printed) {
14985                    if (needSep) pw.println();
14986                    needSep = true;
14987                    pw.println("  Launching content providers:");
14988                    printed = true;
14989                    printedAnything = true;
14990                }
14991                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14992                        pw.println(r);
14993            }
14994        }
14995
14996        if (!printedAnything) {
14997            pw.println("  (nothing)");
14998        }
14999    }
15000
15001    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15002            int opti, boolean dumpAll, String dumpPackage) {
15003        boolean needSep = false;
15004        boolean printedAnything = false;
15005
15006        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15007
15008        if (mGrantedUriPermissions.size() > 0) {
15009            boolean printed = false;
15010            int dumpUid = -2;
15011            if (dumpPackage != null) {
15012                try {
15013                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15014                            MATCH_UNINSTALLED_PACKAGES, 0);
15015                } catch (NameNotFoundException e) {
15016                    dumpUid = -1;
15017                }
15018            }
15019            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15020                int uid = mGrantedUriPermissions.keyAt(i);
15021                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15022                    continue;
15023                }
15024                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15025                if (!printed) {
15026                    if (needSep) pw.println();
15027                    needSep = true;
15028                    pw.println("  Granted Uri Permissions:");
15029                    printed = true;
15030                    printedAnything = true;
15031                }
15032                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15033                for (UriPermission perm : perms.values()) {
15034                    pw.print("    "); pw.println(perm);
15035                    if (dumpAll) {
15036                        perm.dump(pw, "      ");
15037                    }
15038                }
15039            }
15040        }
15041
15042        if (!printedAnything) {
15043            pw.println("  (nothing)");
15044        }
15045    }
15046
15047    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15048            int opti, boolean dumpAll, String dumpPackage) {
15049        boolean printed = false;
15050
15051        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15052
15053        if (mIntentSenderRecords.size() > 0) {
15054            Iterator<WeakReference<PendingIntentRecord>> it
15055                    = mIntentSenderRecords.values().iterator();
15056            while (it.hasNext()) {
15057                WeakReference<PendingIntentRecord> ref = it.next();
15058                PendingIntentRecord rec = ref != null ? ref.get(): null;
15059                if (dumpPackage != null && (rec == null
15060                        || !dumpPackage.equals(rec.key.packageName))) {
15061                    continue;
15062                }
15063                printed = true;
15064                if (rec != null) {
15065                    pw.print("  * "); pw.println(rec);
15066                    if (dumpAll) {
15067                        rec.dump(pw, "    ");
15068                    }
15069                } else {
15070                    pw.print("  * "); pw.println(ref);
15071                }
15072            }
15073        }
15074
15075        if (!printed) {
15076            pw.println("  (nothing)");
15077        }
15078    }
15079
15080    private static final int dumpProcessList(PrintWriter pw,
15081            ActivityManagerService service, List list,
15082            String prefix, String normalLabel, String persistentLabel,
15083            String dumpPackage) {
15084        int numPers = 0;
15085        final int N = list.size()-1;
15086        for (int i=N; i>=0; i--) {
15087            ProcessRecord r = (ProcessRecord)list.get(i);
15088            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15089                continue;
15090            }
15091            pw.println(String.format("%s%s #%2d: %s",
15092                    prefix, (r.persistent ? persistentLabel : normalLabel),
15093                    i, r.toString()));
15094            if (r.persistent) {
15095                numPers++;
15096            }
15097        }
15098        return numPers;
15099    }
15100
15101    private static final boolean dumpProcessOomList(PrintWriter pw,
15102            ActivityManagerService service, List<ProcessRecord> origList,
15103            String prefix, String normalLabel, String persistentLabel,
15104            boolean inclDetails, String dumpPackage) {
15105
15106        ArrayList<Pair<ProcessRecord, Integer>> list
15107                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15108        for (int i=0; i<origList.size(); i++) {
15109            ProcessRecord r = origList.get(i);
15110            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15111                continue;
15112            }
15113            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15114        }
15115
15116        if (list.size() <= 0) {
15117            return false;
15118        }
15119
15120        Comparator<Pair<ProcessRecord, Integer>> comparator
15121                = new Comparator<Pair<ProcessRecord, Integer>>() {
15122            @Override
15123            public int compare(Pair<ProcessRecord, Integer> object1,
15124                    Pair<ProcessRecord, Integer> object2) {
15125                if (object1.first.setAdj != object2.first.setAdj) {
15126                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15127                }
15128                if (object1.first.setProcState != object2.first.setProcState) {
15129                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15130                }
15131                if (object1.second.intValue() != object2.second.intValue()) {
15132                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15133                }
15134                return 0;
15135            }
15136        };
15137
15138        Collections.sort(list, comparator);
15139
15140        final long curRealtime = SystemClock.elapsedRealtime();
15141        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15142        final long curUptime = SystemClock.uptimeMillis();
15143        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15144
15145        for (int i=list.size()-1; i>=0; i--) {
15146            ProcessRecord r = list.get(i).first;
15147            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15148            char schedGroup;
15149            switch (r.setSchedGroup) {
15150                case ProcessList.SCHED_GROUP_BACKGROUND:
15151                    schedGroup = 'B';
15152                    break;
15153                case ProcessList.SCHED_GROUP_DEFAULT:
15154                    schedGroup = 'F';
15155                    break;
15156                case ProcessList.SCHED_GROUP_TOP_APP:
15157                    schedGroup = 'T';
15158                    break;
15159                default:
15160                    schedGroup = '?';
15161                    break;
15162            }
15163            char foreground;
15164            if (r.foregroundActivities) {
15165                foreground = 'A';
15166            } else if (r.foregroundServices) {
15167                foreground = 'S';
15168            } else {
15169                foreground = ' ';
15170            }
15171            String procState = ProcessList.makeProcStateString(r.curProcState);
15172            pw.print(prefix);
15173            pw.print(r.persistent ? persistentLabel : normalLabel);
15174            pw.print(" #");
15175            int num = (origList.size()-1)-list.get(i).second;
15176            if (num < 10) pw.print(' ');
15177            pw.print(num);
15178            pw.print(": ");
15179            pw.print(oomAdj);
15180            pw.print(' ');
15181            pw.print(schedGroup);
15182            pw.print('/');
15183            pw.print(foreground);
15184            pw.print('/');
15185            pw.print(procState);
15186            pw.print(" trm:");
15187            if (r.trimMemoryLevel < 10) pw.print(' ');
15188            pw.print(r.trimMemoryLevel);
15189            pw.print(' ');
15190            pw.print(r.toShortString());
15191            pw.print(" (");
15192            pw.print(r.adjType);
15193            pw.println(')');
15194            if (r.adjSource != null || r.adjTarget != null) {
15195                pw.print(prefix);
15196                pw.print("    ");
15197                if (r.adjTarget instanceof ComponentName) {
15198                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15199                } else if (r.adjTarget != null) {
15200                    pw.print(r.adjTarget.toString());
15201                } else {
15202                    pw.print("{null}");
15203                }
15204                pw.print("<=");
15205                if (r.adjSource instanceof ProcessRecord) {
15206                    pw.print("Proc{");
15207                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15208                    pw.println("}");
15209                } else if (r.adjSource != null) {
15210                    pw.println(r.adjSource.toString());
15211                } else {
15212                    pw.println("{null}");
15213                }
15214            }
15215            if (inclDetails) {
15216                pw.print(prefix);
15217                pw.print("    ");
15218                pw.print("oom: max="); pw.print(r.maxAdj);
15219                pw.print(" curRaw="); pw.print(r.curRawAdj);
15220                pw.print(" setRaw="); pw.print(r.setRawAdj);
15221                pw.print(" cur="); pw.print(r.curAdj);
15222                pw.print(" set="); pw.println(r.setAdj);
15223                pw.print(prefix);
15224                pw.print("    ");
15225                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15226                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15227                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15228                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15229                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15230                pw.println();
15231                pw.print(prefix);
15232                pw.print("    ");
15233                pw.print("cached="); pw.print(r.cached);
15234                pw.print(" empty="); pw.print(r.empty);
15235                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15236
15237                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15238                    if (r.lastWakeTime != 0) {
15239                        long wtime;
15240                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15241                        synchronized (stats) {
15242                            wtime = stats.getProcessWakeTime(r.info.uid,
15243                                    r.pid, curRealtime);
15244                        }
15245                        long timeUsed = wtime - r.lastWakeTime;
15246                        pw.print(prefix);
15247                        pw.print("    ");
15248                        pw.print("keep awake over ");
15249                        TimeUtils.formatDuration(realtimeSince, pw);
15250                        pw.print(" used ");
15251                        TimeUtils.formatDuration(timeUsed, pw);
15252                        pw.print(" (");
15253                        pw.print((timeUsed*100)/realtimeSince);
15254                        pw.println("%)");
15255                    }
15256                    if (r.lastCpuTime != 0) {
15257                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15258                        pw.print(prefix);
15259                        pw.print("    ");
15260                        pw.print("run cpu over ");
15261                        TimeUtils.formatDuration(uptimeSince, pw);
15262                        pw.print(" used ");
15263                        TimeUtils.formatDuration(timeUsed, pw);
15264                        pw.print(" (");
15265                        pw.print((timeUsed*100)/uptimeSince);
15266                        pw.println("%)");
15267                    }
15268                }
15269            }
15270        }
15271        return true;
15272    }
15273
15274    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15275            String[] args) {
15276        ArrayList<ProcessRecord> procs;
15277        synchronized (this) {
15278            if (args != null && args.length > start
15279                    && args[start].charAt(0) != '-') {
15280                procs = new ArrayList<ProcessRecord>();
15281                int pid = -1;
15282                try {
15283                    pid = Integer.parseInt(args[start]);
15284                } catch (NumberFormatException e) {
15285                }
15286                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15287                    ProcessRecord proc = mLruProcesses.get(i);
15288                    if (proc.pid == pid) {
15289                        procs.add(proc);
15290                    } else if (allPkgs && proc.pkgList != null
15291                            && proc.pkgList.containsKey(args[start])) {
15292                        procs.add(proc);
15293                    } else if (proc.processName.equals(args[start])) {
15294                        procs.add(proc);
15295                    }
15296                }
15297                if (procs.size() <= 0) {
15298                    return null;
15299                }
15300            } else {
15301                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15302            }
15303        }
15304        return procs;
15305    }
15306
15307    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15308            PrintWriter pw, String[] args) {
15309        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15310        if (procs == null) {
15311            pw.println("No process found for: " + args[0]);
15312            return;
15313        }
15314
15315        long uptime = SystemClock.uptimeMillis();
15316        long realtime = SystemClock.elapsedRealtime();
15317        pw.println("Applications Graphics Acceleration Info:");
15318        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15319
15320        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15321            ProcessRecord r = procs.get(i);
15322            if (r.thread != null) {
15323                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15324                pw.flush();
15325                try {
15326                    TransferPipe tp = new TransferPipe();
15327                    try {
15328                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15329                        tp.go(fd);
15330                    } finally {
15331                        tp.kill();
15332                    }
15333                } catch (IOException e) {
15334                    pw.println("Failure while dumping the app: " + r);
15335                    pw.flush();
15336                } catch (RemoteException e) {
15337                    pw.println("Got a RemoteException while dumping the app " + r);
15338                    pw.flush();
15339                }
15340            }
15341        }
15342    }
15343
15344    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15345        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15346        if (procs == null) {
15347            pw.println("No process found for: " + args[0]);
15348            return;
15349        }
15350
15351        pw.println("Applications Database Info:");
15352
15353        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15354            ProcessRecord r = procs.get(i);
15355            if (r.thread != null) {
15356                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15357                pw.flush();
15358                try {
15359                    TransferPipe tp = new TransferPipe();
15360                    try {
15361                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15362                        tp.go(fd);
15363                    } finally {
15364                        tp.kill();
15365                    }
15366                } catch (IOException e) {
15367                    pw.println("Failure while dumping the app: " + r);
15368                    pw.flush();
15369                } catch (RemoteException e) {
15370                    pw.println("Got a RemoteException while dumping the app " + r);
15371                    pw.flush();
15372                }
15373            }
15374        }
15375    }
15376
15377    final static class MemItem {
15378        final boolean isProc;
15379        final String label;
15380        final String shortLabel;
15381        final long pss;
15382        final long swapPss;
15383        final int id;
15384        final boolean hasActivities;
15385        ArrayList<MemItem> subitems;
15386
15387        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15388                boolean _hasActivities) {
15389            isProc = true;
15390            label = _label;
15391            shortLabel = _shortLabel;
15392            pss = _pss;
15393            swapPss = _swapPss;
15394            id = _id;
15395            hasActivities = _hasActivities;
15396        }
15397
15398        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15399            isProc = false;
15400            label = _label;
15401            shortLabel = _shortLabel;
15402            pss = _pss;
15403            swapPss = _swapPss;
15404            id = _id;
15405            hasActivities = false;
15406        }
15407    }
15408
15409    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15410            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15411        if (sort && !isCompact) {
15412            Collections.sort(items, new Comparator<MemItem>() {
15413                @Override
15414                public int compare(MemItem lhs, MemItem rhs) {
15415                    if (lhs.pss < rhs.pss) {
15416                        return 1;
15417                    } else if (lhs.pss > rhs.pss) {
15418                        return -1;
15419                    }
15420                    return 0;
15421                }
15422            });
15423        }
15424
15425        for (int i=0; i<items.size(); i++) {
15426            MemItem mi = items.get(i);
15427            if (!isCompact) {
15428                if (dumpSwapPss) {
15429                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15430                            mi.label, stringifyKBSize(mi.swapPss));
15431                } else {
15432                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15433                }
15434            } else if (mi.isProc) {
15435                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15436                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15437                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15438                pw.println(mi.hasActivities ? ",a" : ",e");
15439            } else {
15440                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15441                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15442            }
15443            if (mi.subitems != null) {
15444                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15445                        true, isCompact, dumpSwapPss);
15446            }
15447        }
15448    }
15449
15450    // These are in KB.
15451    static final long[] DUMP_MEM_BUCKETS = new long[] {
15452        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15453        120*1024, 160*1024, 200*1024,
15454        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15455        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15456    };
15457
15458    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15459            boolean stackLike) {
15460        int start = label.lastIndexOf('.');
15461        if (start >= 0) start++;
15462        else start = 0;
15463        int end = label.length();
15464        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15465            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15466                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15467                out.append(bucket);
15468                out.append(stackLike ? "MB." : "MB ");
15469                out.append(label, start, end);
15470                return;
15471            }
15472        }
15473        out.append(memKB/1024);
15474        out.append(stackLike ? "MB." : "MB ");
15475        out.append(label, start, end);
15476    }
15477
15478    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15479            ProcessList.NATIVE_ADJ,
15480            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15481            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15482            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15483            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15484            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15485            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15486    };
15487    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15488            "Native",
15489            "System", "Persistent", "Persistent Service", "Foreground",
15490            "Visible", "Perceptible",
15491            "Heavy Weight", "Backup",
15492            "A Services", "Home",
15493            "Previous", "B Services", "Cached"
15494    };
15495    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15496            "native",
15497            "sys", "pers", "persvc", "fore",
15498            "vis", "percept",
15499            "heavy", "backup",
15500            "servicea", "home",
15501            "prev", "serviceb", "cached"
15502    };
15503
15504    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15505            long realtime, boolean isCheckinRequest, boolean isCompact) {
15506        if (isCompact) {
15507            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15508        }
15509        if (isCheckinRequest || isCompact) {
15510            // short checkin version
15511            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15512        } else {
15513            pw.println("Applications Memory Usage (in Kilobytes):");
15514            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15515        }
15516    }
15517
15518    private static final int KSM_SHARED = 0;
15519    private static final int KSM_SHARING = 1;
15520    private static final int KSM_UNSHARED = 2;
15521    private static final int KSM_VOLATILE = 3;
15522
15523    private final long[] getKsmInfo() {
15524        long[] longOut = new long[4];
15525        final int[] SINGLE_LONG_FORMAT = new int[] {
15526            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15527        };
15528        long[] longTmp = new long[1];
15529        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15530                SINGLE_LONG_FORMAT, null, longTmp, null);
15531        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15532        longTmp[0] = 0;
15533        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15534                SINGLE_LONG_FORMAT, null, longTmp, null);
15535        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15536        longTmp[0] = 0;
15537        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15538                SINGLE_LONG_FORMAT, null, longTmp, null);
15539        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15540        longTmp[0] = 0;
15541        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15542                SINGLE_LONG_FORMAT, null, longTmp, null);
15543        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15544        return longOut;
15545    }
15546
15547    private static String stringifySize(long size, int order) {
15548        Locale locale = Locale.US;
15549        switch (order) {
15550            case 1:
15551                return String.format(locale, "%,13d", size);
15552            case 1024:
15553                return String.format(locale, "%,9dK", size / 1024);
15554            case 1024 * 1024:
15555                return String.format(locale, "%,5dM", size / 1024 / 1024);
15556            case 1024 * 1024 * 1024:
15557                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15558            default:
15559                throw new IllegalArgumentException("Invalid size order");
15560        }
15561    }
15562
15563    private static String stringifyKBSize(long size) {
15564        return stringifySize(size * 1024, 1024);
15565    }
15566
15567    // Update this version number in case you change the 'compact' format
15568    private static final int MEMINFO_COMPACT_VERSION = 1;
15569
15570    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15571            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15572        boolean dumpDetails = false;
15573        boolean dumpFullDetails = false;
15574        boolean dumpDalvik = false;
15575        boolean dumpSummaryOnly = false;
15576        boolean dumpUnreachable = false;
15577        boolean oomOnly = false;
15578        boolean isCompact = false;
15579        boolean localOnly = false;
15580        boolean packages = false;
15581        boolean isCheckinRequest = false;
15582        boolean dumpSwapPss = false;
15583
15584        int opti = 0;
15585        while (opti < args.length) {
15586            String opt = args[opti];
15587            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15588                break;
15589            }
15590            opti++;
15591            if ("-a".equals(opt)) {
15592                dumpDetails = true;
15593                dumpFullDetails = true;
15594                dumpDalvik = true;
15595                dumpSwapPss = true;
15596            } else if ("-d".equals(opt)) {
15597                dumpDalvik = true;
15598            } else if ("-c".equals(opt)) {
15599                isCompact = true;
15600            } else if ("-s".equals(opt)) {
15601                dumpDetails = true;
15602                dumpSummaryOnly = true;
15603            } else if ("-S".equals(opt)) {
15604                dumpSwapPss = true;
15605            } else if ("--unreachable".equals(opt)) {
15606                dumpUnreachable = true;
15607            } else if ("--oom".equals(opt)) {
15608                oomOnly = true;
15609            } else if ("--local".equals(opt)) {
15610                localOnly = true;
15611            } else if ("--package".equals(opt)) {
15612                packages = true;
15613            } else if ("--checkin".equals(opt)) {
15614                isCheckinRequest = true;
15615
15616            } else if ("-h".equals(opt)) {
15617                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15618                pw.println("  -a: include all available information for each process.");
15619                pw.println("  -d: include dalvik details.");
15620                pw.println("  -c: dump in a compact machine-parseable representation.");
15621                pw.println("  -s: dump only summary of application memory usage.");
15622                pw.println("  -S: dump also SwapPss.");
15623                pw.println("  --oom: only show processes organized by oom adj.");
15624                pw.println("  --local: only collect details locally, don't call process.");
15625                pw.println("  --package: interpret process arg as package, dumping all");
15626                pw.println("             processes that have loaded that package.");
15627                pw.println("  --checkin: dump data for a checkin");
15628                pw.println("If [process] is specified it can be the name or ");
15629                pw.println("pid of a specific process to dump.");
15630                return;
15631            } else {
15632                pw.println("Unknown argument: " + opt + "; use -h for help");
15633            }
15634        }
15635
15636        long uptime = SystemClock.uptimeMillis();
15637        long realtime = SystemClock.elapsedRealtime();
15638        final long[] tmpLong = new long[1];
15639
15640        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15641        if (procs == null) {
15642            // No Java processes.  Maybe they want to print a native process.
15643            if (args != null && args.length > opti
15644                    && args[opti].charAt(0) != '-') {
15645                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15646                        = new ArrayList<ProcessCpuTracker.Stats>();
15647                updateCpuStatsNow();
15648                int findPid = -1;
15649                try {
15650                    findPid = Integer.parseInt(args[opti]);
15651                } catch (NumberFormatException e) {
15652                }
15653                synchronized (mProcessCpuTracker) {
15654                    final int N = mProcessCpuTracker.countStats();
15655                    for (int i=0; i<N; i++) {
15656                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15657                        if (st.pid == findPid || (st.baseName != null
15658                                && st.baseName.equals(args[opti]))) {
15659                            nativeProcs.add(st);
15660                        }
15661                    }
15662                }
15663                if (nativeProcs.size() > 0) {
15664                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15665                            isCompact);
15666                    Debug.MemoryInfo mi = null;
15667                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15668                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15669                        final int pid = r.pid;
15670                        if (!isCheckinRequest && dumpDetails) {
15671                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15672                        }
15673                        if (mi == null) {
15674                            mi = new Debug.MemoryInfo();
15675                        }
15676                        if (dumpDetails || (!brief && !oomOnly)) {
15677                            Debug.getMemoryInfo(pid, mi);
15678                        } else {
15679                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15680                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15681                        }
15682                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15683                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15684                        if (isCheckinRequest) {
15685                            pw.println();
15686                        }
15687                    }
15688                    return;
15689                }
15690            }
15691            pw.println("No process found for: " + args[opti]);
15692            return;
15693        }
15694
15695        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15696            dumpDetails = true;
15697        }
15698
15699        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15700
15701        String[] innerArgs = new String[args.length-opti];
15702        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15703
15704        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15705        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15706        long nativePss = 0;
15707        long nativeSwapPss = 0;
15708        long dalvikPss = 0;
15709        long dalvikSwapPss = 0;
15710        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15711                EmptyArray.LONG;
15712        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15713                EmptyArray.LONG;
15714        long otherPss = 0;
15715        long otherSwapPss = 0;
15716        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15717        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15718
15719        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15720        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15721        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15722                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15723
15724        long totalPss = 0;
15725        long totalSwapPss = 0;
15726        long cachedPss = 0;
15727        long cachedSwapPss = 0;
15728        boolean hasSwapPss = false;
15729
15730        Debug.MemoryInfo mi = null;
15731        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15732            final ProcessRecord r = procs.get(i);
15733            final IApplicationThread thread;
15734            final int pid;
15735            final int oomAdj;
15736            final boolean hasActivities;
15737            synchronized (this) {
15738                thread = r.thread;
15739                pid = r.pid;
15740                oomAdj = r.getSetAdjWithServices();
15741                hasActivities = r.activities.size() > 0;
15742            }
15743            if (thread != null) {
15744                if (!isCheckinRequest && dumpDetails) {
15745                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15746                }
15747                if (mi == null) {
15748                    mi = new Debug.MemoryInfo();
15749                }
15750                if (dumpDetails || (!brief && !oomOnly)) {
15751                    Debug.getMemoryInfo(pid, mi);
15752                    hasSwapPss = mi.hasSwappedOutPss;
15753                } else {
15754                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15755                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15756                }
15757                if (dumpDetails) {
15758                    if (localOnly) {
15759                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15760                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15761                        if (isCheckinRequest) {
15762                            pw.println();
15763                        }
15764                    } else {
15765                        try {
15766                            pw.flush();
15767                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15768                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15769                        } catch (RemoteException e) {
15770                            if (!isCheckinRequest) {
15771                                pw.println("Got RemoteException!");
15772                                pw.flush();
15773                            }
15774                        }
15775                    }
15776                }
15777
15778                final long myTotalPss = mi.getTotalPss();
15779                final long myTotalUss = mi.getTotalUss();
15780                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15781
15782                synchronized (this) {
15783                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15784                        // Record this for posterity if the process has been stable.
15785                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15786                    }
15787                }
15788
15789                if (!isCheckinRequest && mi != null) {
15790                    totalPss += myTotalPss;
15791                    totalSwapPss += myTotalSwapPss;
15792                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15793                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15794                            myTotalSwapPss, pid, hasActivities);
15795                    procMems.add(pssItem);
15796                    procMemsMap.put(pid, pssItem);
15797
15798                    nativePss += mi.nativePss;
15799                    nativeSwapPss += mi.nativeSwappedOutPss;
15800                    dalvikPss += mi.dalvikPss;
15801                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15802                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15803                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15804                        dalvikSubitemSwapPss[j] +=
15805                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15806                    }
15807                    otherPss += mi.otherPss;
15808                    otherSwapPss += mi.otherSwappedOutPss;
15809                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15810                        long mem = mi.getOtherPss(j);
15811                        miscPss[j] += mem;
15812                        otherPss -= mem;
15813                        mem = mi.getOtherSwappedOutPss(j);
15814                        miscSwapPss[j] += mem;
15815                        otherSwapPss -= mem;
15816                    }
15817
15818                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15819                        cachedPss += myTotalPss;
15820                        cachedSwapPss += myTotalSwapPss;
15821                    }
15822
15823                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15824                        if (oomIndex == (oomPss.length - 1)
15825                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15826                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15827                            oomPss[oomIndex] += myTotalPss;
15828                            oomSwapPss[oomIndex] += myTotalSwapPss;
15829                            if (oomProcs[oomIndex] == null) {
15830                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15831                            }
15832                            oomProcs[oomIndex].add(pssItem);
15833                            break;
15834                        }
15835                    }
15836                }
15837            }
15838        }
15839
15840        long nativeProcTotalPss = 0;
15841
15842        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15843            // If we are showing aggregations, also look for native processes to
15844            // include so that our aggregations are more accurate.
15845            updateCpuStatsNow();
15846            mi = null;
15847            synchronized (mProcessCpuTracker) {
15848                final int N = mProcessCpuTracker.countStats();
15849                for (int i=0; i<N; i++) {
15850                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15851                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15852                        if (mi == null) {
15853                            mi = new Debug.MemoryInfo();
15854                        }
15855                        if (!brief && !oomOnly) {
15856                            Debug.getMemoryInfo(st.pid, mi);
15857                        } else {
15858                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15859                            mi.nativePrivateDirty = (int)tmpLong[0];
15860                        }
15861
15862                        final long myTotalPss = mi.getTotalPss();
15863                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15864                        totalPss += myTotalPss;
15865                        nativeProcTotalPss += myTotalPss;
15866
15867                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15868                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15869                        procMems.add(pssItem);
15870
15871                        nativePss += mi.nativePss;
15872                        nativeSwapPss += mi.nativeSwappedOutPss;
15873                        dalvikPss += mi.dalvikPss;
15874                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15875                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15876                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15877                            dalvikSubitemSwapPss[j] +=
15878                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15879                        }
15880                        otherPss += mi.otherPss;
15881                        otherSwapPss += mi.otherSwappedOutPss;
15882                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15883                            long mem = mi.getOtherPss(j);
15884                            miscPss[j] += mem;
15885                            otherPss -= mem;
15886                            mem = mi.getOtherSwappedOutPss(j);
15887                            miscSwapPss[j] += mem;
15888                            otherSwapPss -= mem;
15889                        }
15890                        oomPss[0] += myTotalPss;
15891                        oomSwapPss[0] += myTotalSwapPss;
15892                        if (oomProcs[0] == null) {
15893                            oomProcs[0] = new ArrayList<MemItem>();
15894                        }
15895                        oomProcs[0].add(pssItem);
15896                    }
15897                }
15898            }
15899
15900            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15901
15902            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15903            final MemItem dalvikItem =
15904                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15905            if (dalvikSubitemPss.length > 0) {
15906                dalvikItem.subitems = new ArrayList<MemItem>();
15907                for (int j=0; j<dalvikSubitemPss.length; j++) {
15908                    final String name = Debug.MemoryInfo.getOtherLabel(
15909                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15910                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15911                                    dalvikSubitemSwapPss[j], j));
15912                }
15913            }
15914            catMems.add(dalvikItem);
15915            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15916            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15917                String label = Debug.MemoryInfo.getOtherLabel(j);
15918                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15919            }
15920
15921            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15922            for (int j=0; j<oomPss.length; j++) {
15923                if (oomPss[j] != 0) {
15924                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15925                            : DUMP_MEM_OOM_LABEL[j];
15926                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15927                            DUMP_MEM_OOM_ADJ[j]);
15928                    item.subitems = oomProcs[j];
15929                    oomMems.add(item);
15930                }
15931            }
15932
15933            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15934            if (!brief && !oomOnly && !isCompact) {
15935                pw.println();
15936                pw.println("Total PSS by process:");
15937                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15938                pw.println();
15939            }
15940            if (!isCompact) {
15941                pw.println("Total PSS by OOM adjustment:");
15942            }
15943            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15944            if (!brief && !oomOnly) {
15945                PrintWriter out = categoryPw != null ? categoryPw : pw;
15946                if (!isCompact) {
15947                    out.println();
15948                    out.println("Total PSS by category:");
15949                }
15950                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15951            }
15952            if (!isCompact) {
15953                pw.println();
15954            }
15955            MemInfoReader memInfo = new MemInfoReader();
15956            memInfo.readMemInfo();
15957            if (nativeProcTotalPss > 0) {
15958                synchronized (this) {
15959                    final long cachedKb = memInfo.getCachedSizeKb();
15960                    final long freeKb = memInfo.getFreeSizeKb();
15961                    final long zramKb = memInfo.getZramTotalSizeKb();
15962                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15963                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15964                            kernelKb*1024, nativeProcTotalPss*1024);
15965                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15966                            nativeProcTotalPss);
15967                }
15968            }
15969            if (!brief) {
15970                if (!isCompact) {
15971                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15972                    pw.print(" (status ");
15973                    switch (mLastMemoryLevel) {
15974                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15975                            pw.println("normal)");
15976                            break;
15977                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15978                            pw.println("moderate)");
15979                            break;
15980                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15981                            pw.println("low)");
15982                            break;
15983                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15984                            pw.println("critical)");
15985                            break;
15986                        default:
15987                            pw.print(mLastMemoryLevel);
15988                            pw.println(")");
15989                            break;
15990                    }
15991                    pw.print(" Free RAM: ");
15992                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15993                            + memInfo.getFreeSizeKb()));
15994                    pw.print(" (");
15995                    pw.print(stringifyKBSize(cachedPss));
15996                    pw.print(" cached pss + ");
15997                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15998                    pw.print(" cached kernel + ");
15999                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16000                    pw.println(" free)");
16001                } else {
16002                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16003                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16004                            + memInfo.getFreeSizeKb()); pw.print(",");
16005                    pw.println(totalPss - cachedPss);
16006                }
16007            }
16008            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16009                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16010                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16011            if (!isCompact) {
16012                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16013                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16014                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16015                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16016                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16017            } else {
16018                pw.print("lostram,"); pw.println(lostRAM);
16019            }
16020            if (!brief) {
16021                if (memInfo.getZramTotalSizeKb() != 0) {
16022                    if (!isCompact) {
16023                        pw.print("     ZRAM: ");
16024                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16025                                pw.print(" physical used for ");
16026                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16027                                        - memInfo.getSwapFreeSizeKb()));
16028                                pw.print(" in swap (");
16029                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16030                                pw.println(" total swap)");
16031                    } else {
16032                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16033                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16034                                pw.println(memInfo.getSwapFreeSizeKb());
16035                    }
16036                }
16037                final long[] ksm = getKsmInfo();
16038                if (!isCompact) {
16039                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16040                            || ksm[KSM_VOLATILE] != 0) {
16041                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16042                                pw.print(" saved from shared ");
16043                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16044                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16045                                pw.print(" unshared; ");
16046                                pw.print(stringifyKBSize(
16047                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16048                    }
16049                    pw.print("   Tuning: ");
16050                    pw.print(ActivityManager.staticGetMemoryClass());
16051                    pw.print(" (large ");
16052                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16053                    pw.print("), oom ");
16054                    pw.print(stringifySize(
16055                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16056                    pw.print(", restore limit ");
16057                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16058                    if (ActivityManager.isLowRamDeviceStatic()) {
16059                        pw.print(" (low-ram)");
16060                    }
16061                    if (ActivityManager.isHighEndGfx()) {
16062                        pw.print(" (high-end-gfx)");
16063                    }
16064                    pw.println();
16065                } else {
16066                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16067                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16068                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16069                    pw.print("tuning,");
16070                    pw.print(ActivityManager.staticGetMemoryClass());
16071                    pw.print(',');
16072                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16073                    pw.print(',');
16074                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16075                    if (ActivityManager.isLowRamDeviceStatic()) {
16076                        pw.print(",low-ram");
16077                    }
16078                    if (ActivityManager.isHighEndGfx()) {
16079                        pw.print(",high-end-gfx");
16080                    }
16081                    pw.println();
16082                }
16083            }
16084        }
16085    }
16086
16087    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16088            long memtrack, String name) {
16089        sb.append("  ");
16090        sb.append(ProcessList.makeOomAdjString(oomAdj));
16091        sb.append(' ');
16092        sb.append(ProcessList.makeProcStateString(procState));
16093        sb.append(' ');
16094        ProcessList.appendRamKb(sb, pss);
16095        sb.append(": ");
16096        sb.append(name);
16097        if (memtrack > 0) {
16098            sb.append(" (");
16099            sb.append(stringifyKBSize(memtrack));
16100            sb.append(" memtrack)");
16101        }
16102    }
16103
16104    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16105        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16106        sb.append(" (pid ");
16107        sb.append(mi.pid);
16108        sb.append(") ");
16109        sb.append(mi.adjType);
16110        sb.append('\n');
16111        if (mi.adjReason != null) {
16112            sb.append("                      ");
16113            sb.append(mi.adjReason);
16114            sb.append('\n');
16115        }
16116    }
16117
16118    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16119        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16120        for (int i=0, N=memInfos.size(); i<N; i++) {
16121            ProcessMemInfo mi = memInfos.get(i);
16122            infoMap.put(mi.pid, mi);
16123        }
16124        updateCpuStatsNow();
16125        long[] memtrackTmp = new long[1];
16126        synchronized (mProcessCpuTracker) {
16127            final int N = mProcessCpuTracker.countStats();
16128            for (int i=0; i<N; i++) {
16129                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16130                if (st.vsize > 0) {
16131                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16132                    if (pss > 0) {
16133                        if (infoMap.indexOfKey(st.pid) < 0) {
16134                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16135                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16136                            mi.pss = pss;
16137                            mi.memtrack = memtrackTmp[0];
16138                            memInfos.add(mi);
16139                        }
16140                    }
16141                }
16142            }
16143        }
16144
16145        long totalPss = 0;
16146        long totalMemtrack = 0;
16147        for (int i=0, N=memInfos.size(); i<N; i++) {
16148            ProcessMemInfo mi = memInfos.get(i);
16149            if (mi.pss == 0) {
16150                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16151                mi.memtrack = memtrackTmp[0];
16152            }
16153            totalPss += mi.pss;
16154            totalMemtrack += mi.memtrack;
16155        }
16156        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16157            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16158                if (lhs.oomAdj != rhs.oomAdj) {
16159                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16160                }
16161                if (lhs.pss != rhs.pss) {
16162                    return lhs.pss < rhs.pss ? 1 : -1;
16163                }
16164                return 0;
16165            }
16166        });
16167
16168        StringBuilder tag = new StringBuilder(128);
16169        StringBuilder stack = new StringBuilder(128);
16170        tag.append("Low on memory -- ");
16171        appendMemBucket(tag, totalPss, "total", false);
16172        appendMemBucket(stack, totalPss, "total", true);
16173
16174        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16175        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16176        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16177
16178        boolean firstLine = true;
16179        int lastOomAdj = Integer.MIN_VALUE;
16180        long extraNativeRam = 0;
16181        long extraNativeMemtrack = 0;
16182        long cachedPss = 0;
16183        for (int i=0, N=memInfos.size(); i<N; i++) {
16184            ProcessMemInfo mi = memInfos.get(i);
16185
16186            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16187                cachedPss += mi.pss;
16188            }
16189
16190            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16191                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16192                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16193                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16194                if (lastOomAdj != mi.oomAdj) {
16195                    lastOomAdj = mi.oomAdj;
16196                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16197                        tag.append(" / ");
16198                    }
16199                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16200                        if (firstLine) {
16201                            stack.append(":");
16202                            firstLine = false;
16203                        }
16204                        stack.append("\n\t at ");
16205                    } else {
16206                        stack.append("$");
16207                    }
16208                } else {
16209                    tag.append(" ");
16210                    stack.append("$");
16211                }
16212                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16213                    appendMemBucket(tag, mi.pss, mi.name, false);
16214                }
16215                appendMemBucket(stack, mi.pss, mi.name, true);
16216                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16217                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16218                    stack.append("(");
16219                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16220                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16221                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16222                            stack.append(":");
16223                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16224                        }
16225                    }
16226                    stack.append(")");
16227                }
16228            }
16229
16230            appendMemInfo(fullNativeBuilder, mi);
16231            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16232                // The short form only has native processes that are >= 512K.
16233                if (mi.pss >= 512) {
16234                    appendMemInfo(shortNativeBuilder, mi);
16235                } else {
16236                    extraNativeRam += mi.pss;
16237                    extraNativeMemtrack += mi.memtrack;
16238                }
16239            } else {
16240                // Short form has all other details, but if we have collected RAM
16241                // from smaller native processes let's dump a summary of that.
16242                if (extraNativeRam > 0) {
16243                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16244                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16245                    shortNativeBuilder.append('\n');
16246                    extraNativeRam = 0;
16247                }
16248                appendMemInfo(fullJavaBuilder, mi);
16249            }
16250        }
16251
16252        fullJavaBuilder.append("           ");
16253        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16254        fullJavaBuilder.append(": TOTAL");
16255        if (totalMemtrack > 0) {
16256            fullJavaBuilder.append(" (");
16257            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16258            fullJavaBuilder.append(" memtrack)");
16259        } else {
16260        }
16261        fullJavaBuilder.append("\n");
16262
16263        MemInfoReader memInfo = new MemInfoReader();
16264        memInfo.readMemInfo();
16265        final long[] infos = memInfo.getRawInfo();
16266
16267        StringBuilder memInfoBuilder = new StringBuilder(1024);
16268        Debug.getMemInfo(infos);
16269        memInfoBuilder.append("  MemInfo: ");
16270        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16271        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16272        memInfoBuilder.append(stringifyKBSize(
16273                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16274        memInfoBuilder.append(stringifyKBSize(
16275                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16276        memInfoBuilder.append(stringifyKBSize(
16277                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16278        memInfoBuilder.append("           ");
16279        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16280        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16281        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16282        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16283        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16284            memInfoBuilder.append("  ZRAM: ");
16285            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16286            memInfoBuilder.append(" RAM, ");
16287            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16288            memInfoBuilder.append(" swap total, ");
16289            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16290            memInfoBuilder.append(" swap free\n");
16291        }
16292        final long[] ksm = getKsmInfo();
16293        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16294                || ksm[KSM_VOLATILE] != 0) {
16295            memInfoBuilder.append("  KSM: ");
16296            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16297            memInfoBuilder.append(" saved from shared ");
16298            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16299            memInfoBuilder.append("\n       ");
16300            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16301            memInfoBuilder.append(" unshared; ");
16302            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16303            memInfoBuilder.append(" volatile\n");
16304        }
16305        memInfoBuilder.append("  Free RAM: ");
16306        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16307                + memInfo.getFreeSizeKb()));
16308        memInfoBuilder.append("\n");
16309        memInfoBuilder.append("  Used RAM: ");
16310        memInfoBuilder.append(stringifyKBSize(
16311                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16312        memInfoBuilder.append("\n");
16313        memInfoBuilder.append("  Lost RAM: ");
16314        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16315                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16316                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16317        memInfoBuilder.append("\n");
16318        Slog.i(TAG, "Low on memory:");
16319        Slog.i(TAG, shortNativeBuilder.toString());
16320        Slog.i(TAG, fullJavaBuilder.toString());
16321        Slog.i(TAG, memInfoBuilder.toString());
16322
16323        StringBuilder dropBuilder = new StringBuilder(1024);
16324        /*
16325        StringWriter oomSw = new StringWriter();
16326        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16327        StringWriter catSw = new StringWriter();
16328        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16329        String[] emptyArgs = new String[] { };
16330        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16331        oomPw.flush();
16332        String oomString = oomSw.toString();
16333        */
16334        dropBuilder.append("Low on memory:");
16335        dropBuilder.append(stack);
16336        dropBuilder.append('\n');
16337        dropBuilder.append(fullNativeBuilder);
16338        dropBuilder.append(fullJavaBuilder);
16339        dropBuilder.append('\n');
16340        dropBuilder.append(memInfoBuilder);
16341        dropBuilder.append('\n');
16342        /*
16343        dropBuilder.append(oomString);
16344        dropBuilder.append('\n');
16345        */
16346        StringWriter catSw = new StringWriter();
16347        synchronized (ActivityManagerService.this) {
16348            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16349            String[] emptyArgs = new String[] { };
16350            catPw.println();
16351            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16352            catPw.println();
16353            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16354                    false, null).dumpLocked();
16355            catPw.println();
16356            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16357            catPw.flush();
16358        }
16359        dropBuilder.append(catSw.toString());
16360        addErrorToDropBox("lowmem", null, "system_server", null,
16361                null, tag.toString(), dropBuilder.toString(), null, null);
16362        //Slog.i(TAG, "Sent to dropbox:");
16363        //Slog.i(TAG, dropBuilder.toString());
16364        synchronized (ActivityManagerService.this) {
16365            long now = SystemClock.uptimeMillis();
16366            if (mLastMemUsageReportTime < now) {
16367                mLastMemUsageReportTime = now;
16368            }
16369        }
16370    }
16371
16372    /**
16373     * Searches array of arguments for the specified string
16374     * @param args array of argument strings
16375     * @param value value to search for
16376     * @return true if the value is contained in the array
16377     */
16378    private static boolean scanArgs(String[] args, String value) {
16379        if (args != null) {
16380            for (String arg : args) {
16381                if (value.equals(arg)) {
16382                    return true;
16383                }
16384            }
16385        }
16386        return false;
16387    }
16388
16389    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16390            ContentProviderRecord cpr, boolean always) {
16391        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16392
16393        if (!inLaunching || always) {
16394            synchronized (cpr) {
16395                cpr.launchingApp = null;
16396                cpr.notifyAll();
16397            }
16398            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16399            String names[] = cpr.info.authority.split(";");
16400            for (int j = 0; j < names.length; j++) {
16401                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16402            }
16403        }
16404
16405        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16406            ContentProviderConnection conn = cpr.connections.get(i);
16407            if (conn.waiting) {
16408                // If this connection is waiting for the provider, then we don't
16409                // need to mess with its process unless we are always removing
16410                // or for some reason the provider is not currently launching.
16411                if (inLaunching && !always) {
16412                    continue;
16413                }
16414            }
16415            ProcessRecord capp = conn.client;
16416            conn.dead = true;
16417            if (conn.stableCount > 0) {
16418                if (!capp.persistent && capp.thread != null
16419                        && capp.pid != 0
16420                        && capp.pid != MY_PID) {
16421                    capp.kill("depends on provider "
16422                            + cpr.name.flattenToShortString()
16423                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16424                }
16425            } else if (capp.thread != null && conn.provider.provider != null) {
16426                try {
16427                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16428                } catch (RemoteException e) {
16429                }
16430                // In the protocol here, we don't expect the client to correctly
16431                // clean up this connection, we'll just remove it.
16432                cpr.connections.remove(i);
16433                if (conn.client.conProviders.remove(conn)) {
16434                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16435                }
16436            }
16437        }
16438
16439        if (inLaunching && always) {
16440            mLaunchingProviders.remove(cpr);
16441        }
16442        return inLaunching;
16443    }
16444
16445    /**
16446     * Main code for cleaning up a process when it has gone away.  This is
16447     * called both as a result of the process dying, or directly when stopping
16448     * a process when running in single process mode.
16449     *
16450     * @return Returns true if the given process has been restarted, so the
16451     * app that was passed in must remain on the process lists.
16452     */
16453    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16454            boolean restarting, boolean allowRestart, int index) {
16455        if (index >= 0) {
16456            removeLruProcessLocked(app);
16457            ProcessList.remove(app.pid);
16458        }
16459
16460        mProcessesToGc.remove(app);
16461        mPendingPssProcesses.remove(app);
16462
16463        // Dismiss any open dialogs.
16464        if (app.crashDialog != null && !app.forceCrashReport) {
16465            app.crashDialog.dismiss();
16466            app.crashDialog = null;
16467        }
16468        if (app.anrDialog != null) {
16469            app.anrDialog.dismiss();
16470            app.anrDialog = null;
16471        }
16472        if (app.waitDialog != null) {
16473            app.waitDialog.dismiss();
16474            app.waitDialog = null;
16475        }
16476
16477        app.crashing = false;
16478        app.notResponding = false;
16479
16480        app.resetPackageList(mProcessStats);
16481        app.unlinkDeathRecipient();
16482        app.makeInactive(mProcessStats);
16483        app.waitingToKill = null;
16484        app.forcingToForeground = null;
16485        updateProcessForegroundLocked(app, false, false);
16486        app.foregroundActivities = false;
16487        app.hasShownUi = false;
16488        app.treatLikeActivity = false;
16489        app.hasAboveClient = false;
16490        app.hasClientActivities = false;
16491
16492        mServices.killServicesLocked(app, allowRestart);
16493
16494        boolean restart = false;
16495
16496        // Remove published content providers.
16497        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16498            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16499            final boolean always = app.bad || !allowRestart;
16500            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16501            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16502                // We left the provider in the launching list, need to
16503                // restart it.
16504                restart = true;
16505            }
16506
16507            cpr.provider = null;
16508            cpr.proc = null;
16509        }
16510        app.pubProviders.clear();
16511
16512        // Take care of any launching providers waiting for this process.
16513        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16514            restart = true;
16515        }
16516
16517        // Unregister from connected content providers.
16518        if (!app.conProviders.isEmpty()) {
16519            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16520                ContentProviderConnection conn = app.conProviders.get(i);
16521                conn.provider.connections.remove(conn);
16522                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16523                        conn.provider.name);
16524            }
16525            app.conProviders.clear();
16526        }
16527
16528        // At this point there may be remaining entries in mLaunchingProviders
16529        // where we were the only one waiting, so they are no longer of use.
16530        // Look for these and clean up if found.
16531        // XXX Commented out for now.  Trying to figure out a way to reproduce
16532        // the actual situation to identify what is actually going on.
16533        if (false) {
16534            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16535                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16536                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16537                    synchronized (cpr) {
16538                        cpr.launchingApp = null;
16539                        cpr.notifyAll();
16540                    }
16541                }
16542            }
16543        }
16544
16545        skipCurrentReceiverLocked(app);
16546
16547        // Unregister any receivers.
16548        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16549            removeReceiverLocked(app.receivers.valueAt(i));
16550        }
16551        app.receivers.clear();
16552
16553        // If the app is undergoing backup, tell the backup manager about it
16554        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16555            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16556                    + mBackupTarget.appInfo + " died during backup");
16557            try {
16558                IBackupManager bm = IBackupManager.Stub.asInterface(
16559                        ServiceManager.getService(Context.BACKUP_SERVICE));
16560                bm.agentDisconnected(app.info.packageName);
16561            } catch (RemoteException e) {
16562                // can't happen; backup manager is local
16563            }
16564        }
16565
16566        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16567            ProcessChangeItem item = mPendingProcessChanges.get(i);
16568            if (item.pid == app.pid) {
16569                mPendingProcessChanges.remove(i);
16570                mAvailProcessChanges.add(item);
16571            }
16572        }
16573        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16574                null).sendToTarget();
16575
16576        // If the caller is restarting this app, then leave it in its
16577        // current lists and let the caller take care of it.
16578        if (restarting) {
16579            return false;
16580        }
16581
16582        if (!app.persistent || app.isolated) {
16583            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16584                    "Removing non-persistent process during cleanup: " + app);
16585            removeProcessNameLocked(app.processName, app.uid);
16586            if (mHeavyWeightProcess == app) {
16587                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16588                        mHeavyWeightProcess.userId, 0));
16589                mHeavyWeightProcess = null;
16590            }
16591        } else if (!app.removed) {
16592            // This app is persistent, so we need to keep its record around.
16593            // If it is not already on the pending app list, add it there
16594            // and start a new process for it.
16595            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16596                mPersistentStartingProcesses.add(app);
16597                restart = true;
16598            }
16599        }
16600        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16601                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16602        mProcessesOnHold.remove(app);
16603
16604        if (app == mHomeProcess) {
16605            mHomeProcess = null;
16606        }
16607        if (app == mPreviousProcess) {
16608            mPreviousProcess = null;
16609        }
16610
16611        if (restart && !app.isolated) {
16612            // We have components that still need to be running in the
16613            // process, so re-launch it.
16614            if (index < 0) {
16615                ProcessList.remove(app.pid);
16616            }
16617            addProcessNameLocked(app);
16618            startProcessLocked(app, "restart", app.processName);
16619            return true;
16620        } else if (app.pid > 0 && app.pid != MY_PID) {
16621            // Goodbye!
16622            boolean removed;
16623            synchronized (mPidsSelfLocked) {
16624                mPidsSelfLocked.remove(app.pid);
16625                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16626            }
16627            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16628            if (app.isolated) {
16629                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16630            }
16631            app.setPid(0);
16632        }
16633        return false;
16634    }
16635
16636    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16637        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16638            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16639            if (cpr.launchingApp == app) {
16640                return true;
16641            }
16642        }
16643        return false;
16644    }
16645
16646    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16647        // Look through the content providers we are waiting to have launched,
16648        // and if any run in this process then either schedule a restart of
16649        // the process or kill the client waiting for it if this process has
16650        // gone bad.
16651        boolean restart = false;
16652        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16653            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16654            if (cpr.launchingApp == app) {
16655                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16656                    restart = true;
16657                } else {
16658                    removeDyingProviderLocked(app, cpr, true);
16659                }
16660            }
16661        }
16662        return restart;
16663    }
16664
16665    // =========================================================
16666    // SERVICES
16667    // =========================================================
16668
16669    @Override
16670    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16671            int flags) {
16672        enforceNotIsolatedCaller("getServices");
16673        synchronized (this) {
16674            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16675        }
16676    }
16677
16678    @Override
16679    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16680        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16681        synchronized (this) {
16682            return mServices.getRunningServiceControlPanelLocked(name);
16683        }
16684    }
16685
16686    @Override
16687    public ComponentName startService(IApplicationThread caller, Intent service,
16688            String resolvedType, String callingPackage, int userId)
16689            throws TransactionTooLargeException {
16690        enforceNotIsolatedCaller("startService");
16691        // Refuse possible leaked file descriptors
16692        if (service != null && service.hasFileDescriptors() == true) {
16693            throw new IllegalArgumentException("File descriptors passed in Intent");
16694        }
16695
16696        if (callingPackage == null) {
16697            throw new IllegalArgumentException("callingPackage cannot be null");
16698        }
16699
16700        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16701                "startService: " + service + " type=" + resolvedType);
16702        synchronized(this) {
16703            final int callingPid = Binder.getCallingPid();
16704            final int callingUid = Binder.getCallingUid();
16705            final long origId = Binder.clearCallingIdentity();
16706            ComponentName res = mServices.startServiceLocked(caller, service,
16707                    resolvedType, callingPid, callingUid, callingPackage, userId);
16708            Binder.restoreCallingIdentity(origId);
16709            return res;
16710        }
16711    }
16712
16713    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16714            String callingPackage, int userId)
16715            throws TransactionTooLargeException {
16716        synchronized(this) {
16717            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16718                    "startServiceInPackage: " + service + " type=" + resolvedType);
16719            final long origId = Binder.clearCallingIdentity();
16720            ComponentName res = mServices.startServiceLocked(null, service,
16721                    resolvedType, -1, uid, callingPackage, userId);
16722            Binder.restoreCallingIdentity(origId);
16723            return res;
16724        }
16725    }
16726
16727    @Override
16728    public int stopService(IApplicationThread caller, Intent service,
16729            String resolvedType, int userId) {
16730        enforceNotIsolatedCaller("stopService");
16731        // Refuse possible leaked file descriptors
16732        if (service != null && service.hasFileDescriptors() == true) {
16733            throw new IllegalArgumentException("File descriptors passed in Intent");
16734        }
16735
16736        synchronized(this) {
16737            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16738        }
16739    }
16740
16741    @Override
16742    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16743        enforceNotIsolatedCaller("peekService");
16744        // Refuse possible leaked file descriptors
16745        if (service != null && service.hasFileDescriptors() == true) {
16746            throw new IllegalArgumentException("File descriptors passed in Intent");
16747        }
16748
16749        if (callingPackage == null) {
16750            throw new IllegalArgumentException("callingPackage cannot be null");
16751        }
16752
16753        synchronized(this) {
16754            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16755        }
16756    }
16757
16758    @Override
16759    public boolean stopServiceToken(ComponentName className, IBinder token,
16760            int startId) {
16761        synchronized(this) {
16762            return mServices.stopServiceTokenLocked(className, token, startId);
16763        }
16764    }
16765
16766    @Override
16767    public void setServiceForeground(ComponentName className, IBinder token,
16768            int id, Notification notification, int flags) {
16769        synchronized(this) {
16770            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16771        }
16772    }
16773
16774    @Override
16775    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16776            boolean requireFull, String name, String callerPackage) {
16777        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16778                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16779    }
16780
16781    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16782            String className, int flags) {
16783        boolean result = false;
16784        // For apps that don't have pre-defined UIDs, check for permission
16785        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16786            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16787                if (ActivityManager.checkUidPermission(
16788                        INTERACT_ACROSS_USERS,
16789                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16790                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16791                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16792                            + " requests FLAG_SINGLE_USER, but app does not hold "
16793                            + INTERACT_ACROSS_USERS;
16794                    Slog.w(TAG, msg);
16795                    throw new SecurityException(msg);
16796                }
16797                // Permission passed
16798                result = true;
16799            }
16800        } else if ("system".equals(componentProcessName)) {
16801            result = true;
16802        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16803            // Phone app and persistent apps are allowed to export singleuser providers.
16804            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16805                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16806        }
16807        if (DEBUG_MU) Slog.v(TAG_MU,
16808                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16809                + Integer.toHexString(flags) + ") = " + result);
16810        return result;
16811    }
16812
16813    /**
16814     * Checks to see if the caller is in the same app as the singleton
16815     * component, or the component is in a special app. It allows special apps
16816     * to export singleton components but prevents exporting singleton
16817     * components for regular apps.
16818     */
16819    boolean isValidSingletonCall(int callingUid, int componentUid) {
16820        int componentAppId = UserHandle.getAppId(componentUid);
16821        return UserHandle.isSameApp(callingUid, componentUid)
16822                || componentAppId == Process.SYSTEM_UID
16823                || componentAppId == Process.PHONE_UID
16824                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16825                        == PackageManager.PERMISSION_GRANTED;
16826    }
16827
16828    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16829            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16830            int userId) throws TransactionTooLargeException {
16831        enforceNotIsolatedCaller("bindService");
16832
16833        // Refuse possible leaked file descriptors
16834        if (service != null && service.hasFileDescriptors() == true) {
16835            throw new IllegalArgumentException("File descriptors passed in Intent");
16836        }
16837
16838        if (callingPackage == null) {
16839            throw new IllegalArgumentException("callingPackage cannot be null");
16840        }
16841
16842        synchronized(this) {
16843            return mServices.bindServiceLocked(caller, token, service,
16844                    resolvedType, connection, flags, callingPackage, userId);
16845        }
16846    }
16847
16848    public boolean unbindService(IServiceConnection connection) {
16849        synchronized (this) {
16850            return mServices.unbindServiceLocked(connection);
16851        }
16852    }
16853
16854    public void publishService(IBinder token, Intent intent, IBinder service) {
16855        // Refuse possible leaked file descriptors
16856        if (intent != null && intent.hasFileDescriptors() == true) {
16857            throw new IllegalArgumentException("File descriptors passed in Intent");
16858        }
16859
16860        synchronized(this) {
16861            if (!(token instanceof ServiceRecord)) {
16862                throw new IllegalArgumentException("Invalid service token");
16863            }
16864            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16865        }
16866    }
16867
16868    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16869        // Refuse possible leaked file descriptors
16870        if (intent != null && intent.hasFileDescriptors() == true) {
16871            throw new IllegalArgumentException("File descriptors passed in Intent");
16872        }
16873
16874        synchronized(this) {
16875            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16876        }
16877    }
16878
16879    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16880        synchronized(this) {
16881            if (!(token instanceof ServiceRecord)) {
16882                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16883                throw new IllegalArgumentException("Invalid service token");
16884            }
16885            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16886        }
16887    }
16888
16889    // =========================================================
16890    // BACKUP AND RESTORE
16891    // =========================================================
16892
16893    // Cause the target app to be launched if necessary and its backup agent
16894    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16895    // activity manager to announce its creation.
16896    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16897        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16898                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16899        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16900
16901        synchronized(this) {
16902            // !!! TODO: currently no check here that we're already bound
16903            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16904            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16905            synchronized (stats) {
16906                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16907            }
16908
16909            // Backup agent is now in use, its package can't be stopped.
16910            try {
16911                AppGlobals.getPackageManager().setPackageStoppedState(
16912                        app.packageName, false, UserHandle.getUserId(app.uid));
16913            } catch (RemoteException e) {
16914            } catch (IllegalArgumentException e) {
16915                Slog.w(TAG, "Failed trying to unstop package "
16916                        + app.packageName + ": " + e);
16917            }
16918
16919            BackupRecord r = new BackupRecord(ss, app, backupMode);
16920            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16921                    ? new ComponentName(app.packageName, app.backupAgentName)
16922                    : new ComponentName("android", "FullBackupAgent");
16923            // startProcessLocked() returns existing proc's record if it's already running
16924            ProcessRecord proc = startProcessLocked(app.processName, app,
16925                    false, 0, "backup", hostingName, false, false, false);
16926            if (proc == null) {
16927                Slog.e(TAG, "Unable to start backup agent process " + r);
16928                return false;
16929            }
16930
16931            // If the app is a regular app (uid >= 10000) and not the system server or phone
16932            // process, etc, then mark it as being in full backup so that certain calls to the
16933            // process can be blocked. This is not reset to false anywhere because we kill the
16934            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16935            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16936                proc.inFullBackup = true;
16937            }
16938            r.app = proc;
16939            mBackupTarget = r;
16940            mBackupAppName = app.packageName;
16941
16942            // Try not to kill the process during backup
16943            updateOomAdjLocked(proc);
16944
16945            // If the process is already attached, schedule the creation of the backup agent now.
16946            // If it is not yet live, this will be done when it attaches to the framework.
16947            if (proc.thread != null) {
16948                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16949                try {
16950                    proc.thread.scheduleCreateBackupAgent(app,
16951                            compatibilityInfoForPackageLocked(app), backupMode);
16952                } catch (RemoteException e) {
16953                    // Will time out on the backup manager side
16954                }
16955            } else {
16956                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16957            }
16958            // Invariants: at this point, the target app process exists and the application
16959            // is either already running or in the process of coming up.  mBackupTarget and
16960            // mBackupAppName describe the app, so that when it binds back to the AM we
16961            // know that it's scheduled for a backup-agent operation.
16962        }
16963
16964        return true;
16965    }
16966
16967    @Override
16968    public void clearPendingBackup() {
16969        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16970        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16971
16972        synchronized (this) {
16973            mBackupTarget = null;
16974            mBackupAppName = null;
16975        }
16976    }
16977
16978    // A backup agent has just come up
16979    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16980        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16981                + " = " + agent);
16982
16983        synchronized(this) {
16984            if (!agentPackageName.equals(mBackupAppName)) {
16985                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16986                return;
16987            }
16988        }
16989
16990        long oldIdent = Binder.clearCallingIdentity();
16991        try {
16992            IBackupManager bm = IBackupManager.Stub.asInterface(
16993                    ServiceManager.getService(Context.BACKUP_SERVICE));
16994            bm.agentConnected(agentPackageName, agent);
16995        } catch (RemoteException e) {
16996            // can't happen; the backup manager service is local
16997        } catch (Exception e) {
16998            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16999            e.printStackTrace();
17000        } finally {
17001            Binder.restoreCallingIdentity(oldIdent);
17002        }
17003    }
17004
17005    // done with this agent
17006    public void unbindBackupAgent(ApplicationInfo appInfo) {
17007        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17008        if (appInfo == null) {
17009            Slog.w(TAG, "unbind backup agent for null app");
17010            return;
17011        }
17012
17013        synchronized(this) {
17014            try {
17015                if (mBackupAppName == null) {
17016                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17017                    return;
17018                }
17019
17020                if (!mBackupAppName.equals(appInfo.packageName)) {
17021                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17022                    return;
17023                }
17024
17025                // Not backing this app up any more; reset its OOM adjustment
17026                final ProcessRecord proc = mBackupTarget.app;
17027                updateOomAdjLocked(proc);
17028
17029                // If the app crashed during backup, 'thread' will be null here
17030                if (proc.thread != null) {
17031                    try {
17032                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17033                                compatibilityInfoForPackageLocked(appInfo));
17034                    } catch (Exception e) {
17035                        Slog.e(TAG, "Exception when unbinding backup agent:");
17036                        e.printStackTrace();
17037                    }
17038                }
17039            } finally {
17040                mBackupTarget = null;
17041                mBackupAppName = null;
17042            }
17043        }
17044    }
17045    // =========================================================
17046    // BROADCASTS
17047    // =========================================================
17048
17049    boolean isPendingBroadcastProcessLocked(int pid) {
17050        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17051                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17052    }
17053
17054    void skipPendingBroadcastLocked(int pid) {
17055            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17056            for (BroadcastQueue queue : mBroadcastQueues) {
17057                queue.skipPendingBroadcastLocked(pid);
17058            }
17059    }
17060
17061    // The app just attached; send any pending broadcasts that it should receive
17062    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17063        boolean didSomething = false;
17064        for (BroadcastQueue queue : mBroadcastQueues) {
17065            didSomething |= queue.sendPendingBroadcastsLocked(app);
17066        }
17067        return didSomething;
17068    }
17069
17070    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17071            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17072        enforceNotIsolatedCaller("registerReceiver");
17073        ArrayList<Intent> stickyIntents = null;
17074        ProcessRecord callerApp = null;
17075        int callingUid;
17076        int callingPid;
17077        synchronized(this) {
17078            if (caller != null) {
17079                callerApp = getRecordForAppLocked(caller);
17080                if (callerApp == null) {
17081                    throw new SecurityException(
17082                            "Unable to find app for caller " + caller
17083                            + " (pid=" + Binder.getCallingPid()
17084                            + ") when registering receiver " + receiver);
17085                }
17086                if (callerApp.info.uid != Process.SYSTEM_UID &&
17087                        !callerApp.pkgList.containsKey(callerPackage) &&
17088                        !"android".equals(callerPackage)) {
17089                    throw new SecurityException("Given caller package " + callerPackage
17090                            + " is not running in process " + callerApp);
17091                }
17092                callingUid = callerApp.info.uid;
17093                callingPid = callerApp.pid;
17094            } else {
17095                callerPackage = null;
17096                callingUid = Binder.getCallingUid();
17097                callingPid = Binder.getCallingPid();
17098            }
17099
17100            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17101                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17102
17103            Iterator<String> actions = filter.actionsIterator();
17104            if (actions == null) {
17105                ArrayList<String> noAction = new ArrayList<String>(1);
17106                noAction.add(null);
17107                actions = noAction.iterator();
17108            }
17109
17110            // Collect stickies of users
17111            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17112            while (actions.hasNext()) {
17113                String action = actions.next();
17114                for (int id : userIds) {
17115                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17116                    if (stickies != null) {
17117                        ArrayList<Intent> intents = stickies.get(action);
17118                        if (intents != null) {
17119                            if (stickyIntents == null) {
17120                                stickyIntents = new ArrayList<Intent>();
17121                            }
17122                            stickyIntents.addAll(intents);
17123                        }
17124                    }
17125                }
17126            }
17127        }
17128
17129        ArrayList<Intent> allSticky = null;
17130        if (stickyIntents != null) {
17131            final ContentResolver resolver = mContext.getContentResolver();
17132            // Look for any matching sticky broadcasts...
17133            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17134                Intent intent = stickyIntents.get(i);
17135                // If intent has scheme "content", it will need to acccess
17136                // provider that needs to lock mProviderMap in ActivityThread
17137                // and also it may need to wait application response, so we
17138                // cannot lock ActivityManagerService here.
17139                if (filter.match(resolver, intent, true, TAG) >= 0) {
17140                    if (allSticky == null) {
17141                        allSticky = new ArrayList<Intent>();
17142                    }
17143                    allSticky.add(intent);
17144                }
17145            }
17146        }
17147
17148        // The first sticky in the list is returned directly back to the client.
17149        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17150        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17151        if (receiver == null) {
17152            return sticky;
17153        }
17154
17155        synchronized (this) {
17156            if (callerApp != null && (callerApp.thread == null
17157                    || callerApp.thread.asBinder() != caller.asBinder())) {
17158                // Original caller already died
17159                return null;
17160            }
17161            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17162            if (rl == null) {
17163                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17164                        userId, receiver);
17165                if (rl.app != null) {
17166                    rl.app.receivers.add(rl);
17167                } else {
17168                    try {
17169                        receiver.asBinder().linkToDeath(rl, 0);
17170                    } catch (RemoteException e) {
17171                        return sticky;
17172                    }
17173                    rl.linkedToDeath = true;
17174                }
17175                mRegisteredReceivers.put(receiver.asBinder(), rl);
17176            } else if (rl.uid != callingUid) {
17177                throw new IllegalArgumentException(
17178                        "Receiver requested to register for uid " + callingUid
17179                        + " was previously registered for uid " + rl.uid);
17180            } else if (rl.pid != callingPid) {
17181                throw new IllegalArgumentException(
17182                        "Receiver requested to register for pid " + callingPid
17183                        + " was previously registered for pid " + rl.pid);
17184            } else if (rl.userId != userId) {
17185                throw new IllegalArgumentException(
17186                        "Receiver requested to register for user " + userId
17187                        + " was previously registered for user " + rl.userId);
17188            }
17189            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17190                    permission, callingUid, userId);
17191            rl.add(bf);
17192            if (!bf.debugCheck()) {
17193                Slog.w(TAG, "==> For Dynamic broadcast");
17194            }
17195            mReceiverResolver.addFilter(bf);
17196
17197            // Enqueue broadcasts for all existing stickies that match
17198            // this filter.
17199            if (allSticky != null) {
17200                ArrayList receivers = new ArrayList();
17201                receivers.add(bf);
17202
17203                final int stickyCount = allSticky.size();
17204                for (int i = 0; i < stickyCount; i++) {
17205                    Intent intent = allSticky.get(i);
17206                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17207                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17208                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17209                            null, 0, null, null, false, true, true, -1);
17210                    queue.enqueueParallelBroadcastLocked(r);
17211                    queue.scheduleBroadcastsLocked();
17212                }
17213            }
17214
17215            return sticky;
17216        }
17217    }
17218
17219    public void unregisterReceiver(IIntentReceiver receiver) {
17220        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17221
17222        final long origId = Binder.clearCallingIdentity();
17223        try {
17224            boolean doTrim = false;
17225
17226            synchronized(this) {
17227                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17228                if (rl != null) {
17229                    final BroadcastRecord r = rl.curBroadcast;
17230                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17231                        final boolean doNext = r.queue.finishReceiverLocked(
17232                                r, r.resultCode, r.resultData, r.resultExtras,
17233                                r.resultAbort, false);
17234                        if (doNext) {
17235                            doTrim = true;
17236                            r.queue.processNextBroadcast(false);
17237                        }
17238                    }
17239
17240                    if (rl.app != null) {
17241                        rl.app.receivers.remove(rl);
17242                    }
17243                    removeReceiverLocked(rl);
17244                    if (rl.linkedToDeath) {
17245                        rl.linkedToDeath = false;
17246                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17247                    }
17248                }
17249            }
17250
17251            // If we actually concluded any broadcasts, we might now be able
17252            // to trim the recipients' apps from our working set
17253            if (doTrim) {
17254                trimApplications();
17255                return;
17256            }
17257
17258        } finally {
17259            Binder.restoreCallingIdentity(origId);
17260        }
17261    }
17262
17263    void removeReceiverLocked(ReceiverList rl) {
17264        mRegisteredReceivers.remove(rl.receiver.asBinder());
17265        for (int i = rl.size() - 1; i >= 0; i--) {
17266            mReceiverResolver.removeFilter(rl.get(i));
17267        }
17268    }
17269
17270    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17271        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17272            ProcessRecord r = mLruProcesses.get(i);
17273            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17274                try {
17275                    r.thread.dispatchPackageBroadcast(cmd, packages);
17276                } catch (RemoteException ex) {
17277                }
17278            }
17279        }
17280    }
17281
17282    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17283            int callingUid, int[] users) {
17284        // TODO: come back and remove this assumption to triage all broadcasts
17285        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17286
17287        List<ResolveInfo> receivers = null;
17288        try {
17289            HashSet<ComponentName> singleUserReceivers = null;
17290            boolean scannedFirstReceivers = false;
17291            for (int user : users) {
17292                // Skip users that have Shell restrictions, with exception of always permitted
17293                // Shell broadcasts
17294                if (callingUid == Process.SHELL_UID
17295                        && mUserController.hasUserRestriction(
17296                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17297                        && !isPermittedShellBroadcast(intent)) {
17298                    continue;
17299                }
17300                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17301                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17302                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17303                    // If this is not the system user, we need to check for
17304                    // any receivers that should be filtered out.
17305                    for (int i=0; i<newReceivers.size(); i++) {
17306                        ResolveInfo ri = newReceivers.get(i);
17307                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17308                            newReceivers.remove(i);
17309                            i--;
17310                        }
17311                    }
17312                }
17313                if (newReceivers != null && newReceivers.size() == 0) {
17314                    newReceivers = null;
17315                }
17316                if (receivers == null) {
17317                    receivers = newReceivers;
17318                } else if (newReceivers != null) {
17319                    // We need to concatenate the additional receivers
17320                    // found with what we have do far.  This would be easy,
17321                    // but we also need to de-dup any receivers that are
17322                    // singleUser.
17323                    if (!scannedFirstReceivers) {
17324                        // Collect any single user receivers we had already retrieved.
17325                        scannedFirstReceivers = true;
17326                        for (int i=0; i<receivers.size(); i++) {
17327                            ResolveInfo ri = receivers.get(i);
17328                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17329                                ComponentName cn = new ComponentName(
17330                                        ri.activityInfo.packageName, ri.activityInfo.name);
17331                                if (singleUserReceivers == null) {
17332                                    singleUserReceivers = new HashSet<ComponentName>();
17333                                }
17334                                singleUserReceivers.add(cn);
17335                            }
17336                        }
17337                    }
17338                    // Add the new results to the existing results, tracking
17339                    // and de-dupping single user receivers.
17340                    for (int i=0; i<newReceivers.size(); i++) {
17341                        ResolveInfo ri = newReceivers.get(i);
17342                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17343                            ComponentName cn = new ComponentName(
17344                                    ri.activityInfo.packageName, ri.activityInfo.name);
17345                            if (singleUserReceivers == null) {
17346                                singleUserReceivers = new HashSet<ComponentName>();
17347                            }
17348                            if (!singleUserReceivers.contains(cn)) {
17349                                singleUserReceivers.add(cn);
17350                                receivers.add(ri);
17351                            }
17352                        } else {
17353                            receivers.add(ri);
17354                        }
17355                    }
17356                }
17357            }
17358        } catch (RemoteException ex) {
17359            // pm is in same process, this will never happen.
17360        }
17361        return receivers;
17362    }
17363
17364    private boolean isPermittedShellBroadcast(Intent intent) {
17365        // remote bugreport should always be allowed to be taken
17366        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17367    }
17368
17369    final int broadcastIntentLocked(ProcessRecord callerApp,
17370            String callerPackage, Intent intent, String resolvedType,
17371            IIntentReceiver resultTo, int resultCode, String resultData,
17372            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17373            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17374        intent = new Intent(intent);
17375
17376        // By default broadcasts do not go to stopped apps.
17377        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17378
17379        // If we have not finished booting, don't allow this to launch new processes.
17380        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17381            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17382        }
17383
17384        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17385                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17386                + " ordered=" + ordered + " userid=" + userId);
17387        if ((resultTo != null) && !ordered) {
17388            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17389        }
17390
17391        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17392                ALLOW_NON_FULL, "broadcast", callerPackage);
17393
17394        // Make sure that the user who is receiving this broadcast is running.
17395        // If not, we will just skip it. Make an exception for shutdown broadcasts
17396        // and upgrade steps.
17397
17398        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17399            if ((callingUid != Process.SYSTEM_UID
17400                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17401                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17402                Slog.w(TAG, "Skipping broadcast of " + intent
17403                        + ": user " + userId + " is stopped");
17404                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17405            }
17406        }
17407
17408        BroadcastOptions brOptions = null;
17409        if (bOptions != null) {
17410            brOptions = new BroadcastOptions(bOptions);
17411            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17412                // See if the caller is allowed to do this.  Note we are checking against
17413                // the actual real caller (not whoever provided the operation as say a
17414                // PendingIntent), because that who is actually supplied the arguments.
17415                if (checkComponentPermission(
17416                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17417                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17418                        != PackageManager.PERMISSION_GRANTED) {
17419                    String msg = "Permission Denial: " + intent.getAction()
17420                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17421                            + ", uid=" + callingUid + ")"
17422                            + " requires "
17423                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17424                    Slog.w(TAG, msg);
17425                    throw new SecurityException(msg);
17426                }
17427            }
17428        }
17429
17430        // Verify that protected broadcasts are only being sent by system code,
17431        // and that system code is only sending protected broadcasts.
17432        final String action = intent.getAction();
17433        final boolean isProtectedBroadcast;
17434        try {
17435            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17436        } catch (RemoteException e) {
17437            Slog.w(TAG, "Remote exception", e);
17438            return ActivityManager.BROADCAST_SUCCESS;
17439        }
17440
17441        final boolean isCallerSystem;
17442        switch (UserHandle.getAppId(callingUid)) {
17443            case Process.ROOT_UID:
17444            case Process.SYSTEM_UID:
17445            case Process.PHONE_UID:
17446            case Process.BLUETOOTH_UID:
17447            case Process.NFC_UID:
17448                isCallerSystem = true;
17449                break;
17450            default:
17451                isCallerSystem = (callerApp != null) && callerApp.persistent;
17452                break;
17453        }
17454
17455        if (isCallerSystem) {
17456            if (isProtectedBroadcast
17457                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17458                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17459                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17460                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17461                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17462                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17463                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17464                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17465                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17466                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17467                // Broadcast is either protected, or it's a public action that
17468                // we've relaxed, so it's fine for system internals to send.
17469            } else {
17470                // The vast majority of broadcasts sent from system internals
17471                // should be protected to avoid security holes, so yell loudly
17472                // to ensure we examine these cases.
17473                if (callerApp != null) {
17474                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17475                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17476                            new Throwable());
17477                } else {
17478                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17479                            + " from system uid " + UserHandle.formatUid(callingUid)
17480                            + " pkg " + callerPackage,
17481                            new Throwable());
17482                }
17483            }
17484
17485        } else {
17486            if (isProtectedBroadcast) {
17487                String msg = "Permission Denial: not allowed to send broadcast "
17488                        + action + " from pid="
17489                        + callingPid + ", uid=" + callingUid;
17490                Slog.w(TAG, msg);
17491                throw new SecurityException(msg);
17492
17493            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17494                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17495                // Special case for compatibility: we don't want apps to send this,
17496                // but historically it has not been protected and apps may be using it
17497                // to poke their own app widget.  So, instead of making it protected,
17498                // just limit it to the caller.
17499                if (callerPackage == null) {
17500                    String msg = "Permission Denial: not allowed to send broadcast "
17501                            + action + " from unknown caller.";
17502                    Slog.w(TAG, msg);
17503                    throw new SecurityException(msg);
17504                } else if (intent.getComponent() != null) {
17505                    // They are good enough to send to an explicit component...  verify
17506                    // it is being sent to the calling app.
17507                    if (!intent.getComponent().getPackageName().equals(
17508                            callerPackage)) {
17509                        String msg = "Permission Denial: not allowed to send broadcast "
17510                                + action + " to "
17511                                + intent.getComponent().getPackageName() + " from "
17512                                + callerPackage;
17513                        Slog.w(TAG, msg);
17514                        throw new SecurityException(msg);
17515                    }
17516                } else {
17517                    // Limit broadcast to their own package.
17518                    intent.setPackage(callerPackage);
17519                }
17520            }
17521        }
17522
17523        if (action != null) {
17524            switch (action) {
17525                case Intent.ACTION_UID_REMOVED:
17526                case Intent.ACTION_PACKAGE_REMOVED:
17527                case Intent.ACTION_PACKAGE_CHANGED:
17528                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17529                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17530                case Intent.ACTION_PACKAGES_SUSPENDED:
17531                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17532                    // Handle special intents: if this broadcast is from the package
17533                    // manager about a package being removed, we need to remove all of
17534                    // its activities from the history stack.
17535                    if (checkComponentPermission(
17536                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17537                            callingPid, callingUid, -1, true)
17538                            != PackageManager.PERMISSION_GRANTED) {
17539                        String msg = "Permission Denial: " + intent.getAction()
17540                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17541                                + ", uid=" + callingUid + ")"
17542                                + " requires "
17543                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17544                        Slog.w(TAG, msg);
17545                        throw new SecurityException(msg);
17546                    }
17547                    switch (action) {
17548                        case Intent.ACTION_UID_REMOVED:
17549                            final Bundle intentExtras = intent.getExtras();
17550                            final int uid = intentExtras != null
17551                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17552                            if (uid >= 0) {
17553                                mBatteryStatsService.removeUid(uid);
17554                                mAppOpsService.uidRemoved(uid);
17555                            }
17556                            break;
17557                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17558                            // If resources are unavailable just force stop all those packages
17559                            // and flush the attribute cache as well.
17560                            String list[] =
17561                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17562                            if (list != null && list.length > 0) {
17563                                for (int i = 0; i < list.length; i++) {
17564                                    forceStopPackageLocked(list[i], -1, false, true, true,
17565                                            false, false, userId, "storage unmount");
17566                                }
17567                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17568                                sendPackageBroadcastLocked(
17569                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17570                                        userId);
17571                            }
17572                            break;
17573                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17574                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17575                            break;
17576                        case Intent.ACTION_PACKAGE_REMOVED:
17577                        case Intent.ACTION_PACKAGE_CHANGED:
17578                            Uri data = intent.getData();
17579                            String ssp;
17580                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17581                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17582                                final boolean replacing =
17583                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17584                                final boolean killProcess =
17585                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17586                                final boolean fullUninstall = removed && !replacing;
17587                                if (removed) {
17588                                    if (killProcess) {
17589                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17590                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17591                                                false, true, true, false, fullUninstall, userId,
17592                                                removed ? "pkg removed" : "pkg changed");
17593                                    }
17594                                    final int cmd = killProcess
17595                                            ? IApplicationThread.PACKAGE_REMOVED
17596                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17597                                    sendPackageBroadcastLocked(cmd,
17598                                            new String[] {ssp}, userId);
17599                                    if (fullUninstall) {
17600                                        mAppOpsService.packageRemoved(
17601                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17602
17603                                        // Remove all permissions granted from/to this package
17604                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17605
17606                                        removeTasksByPackageNameLocked(ssp, userId);
17607                                        mBatteryStatsService.notePackageUninstalled(ssp);
17608                                    }
17609                                } else {
17610                                    if (killProcess) {
17611                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17612                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17613                                                userId, ProcessList.INVALID_ADJ,
17614                                                false, true, true, false, "change " + ssp);
17615                                    }
17616                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17617                                            intent.getStringArrayExtra(
17618                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17619                                }
17620                            }
17621                            break;
17622                        case Intent.ACTION_PACKAGES_SUSPENDED:
17623                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17624                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17625                                    intent.getAction());
17626                            final String[] packageNames = intent.getStringArrayExtra(
17627                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17628                            final int userHandle = intent.getIntExtra(
17629                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17630
17631                            synchronized(ActivityManagerService.this) {
17632                                mRecentTasks.onPackagesSuspendedChanged(
17633                                        packageNames, suspended, userHandle);
17634                            }
17635                            break;
17636                    }
17637                    break;
17638                case Intent.ACTION_PACKAGE_REPLACED:
17639                {
17640                    final Uri data = intent.getData();
17641                    final String ssp;
17642                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17643                        final ApplicationInfo aInfo =
17644                                getPackageManagerInternalLocked().getApplicationInfo(
17645                                        ssp,
17646                                        userId);
17647                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17648                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17649                                new String[] {ssp}, userId);
17650                    }
17651                    break;
17652                }
17653                case Intent.ACTION_PACKAGE_ADDED:
17654                {
17655                    // Special case for adding a package: by default turn on compatibility mode.
17656                    Uri data = intent.getData();
17657                    String ssp;
17658                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17659                        final boolean replacing =
17660                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17661                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17662
17663                        try {
17664                            ApplicationInfo ai = AppGlobals.getPackageManager().
17665                                    getApplicationInfo(ssp, 0, 0);
17666                            mBatteryStatsService.notePackageInstalled(ssp,
17667                                    ai != null ? ai.versionCode : 0);
17668                        } catch (RemoteException e) {
17669                        }
17670                    }
17671                    break;
17672                }
17673                case Intent.ACTION_TIMEZONE_CHANGED:
17674                    // If this is the time zone changed action, queue up a message that will reset
17675                    // the timezone of all currently running processes. This message will get
17676                    // queued up before the broadcast happens.
17677                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17678                    break;
17679                case Intent.ACTION_TIME_CHANGED:
17680                    // If the user set the time, let all running processes know.
17681                    final int is24Hour =
17682                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17683                                    : 0;
17684                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17685                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17686                    synchronized (stats) {
17687                        stats.noteCurrentTimeChangedLocked();
17688                    }
17689                    break;
17690                case Intent.ACTION_CLEAR_DNS_CACHE:
17691                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17692                    break;
17693                case Proxy.PROXY_CHANGE_ACTION:
17694                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17695                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17696                    break;
17697                case android.hardware.Camera.ACTION_NEW_PICTURE:
17698                case android.hardware.Camera.ACTION_NEW_VIDEO:
17699                    // These broadcasts are no longer allowed by the system, since they can
17700                    // cause significant thrashing at a crictical point (using the camera).
17701                    // Apps should use JobScehduler to monitor for media provider changes.
17702                    Slog.w(TAG, action + " no longer allowed; dropping from "
17703                            + UserHandle.formatUid(callingUid));
17704                    // Lie; we don't want to crash the app.
17705                    return ActivityManager.BROADCAST_SUCCESS;
17706            }
17707        }
17708
17709        // Add to the sticky list if requested.
17710        if (sticky) {
17711            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17712                    callingPid, callingUid)
17713                    != PackageManager.PERMISSION_GRANTED) {
17714                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17715                        + callingPid + ", uid=" + callingUid
17716                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17717                Slog.w(TAG, msg);
17718                throw new SecurityException(msg);
17719            }
17720            if (requiredPermissions != null && requiredPermissions.length > 0) {
17721                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17722                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17723                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17724            }
17725            if (intent.getComponent() != null) {
17726                throw new SecurityException(
17727                        "Sticky broadcasts can't target a specific component");
17728            }
17729            // We use userId directly here, since the "all" target is maintained
17730            // as a separate set of sticky broadcasts.
17731            if (userId != UserHandle.USER_ALL) {
17732                // But first, if this is not a broadcast to all users, then
17733                // make sure it doesn't conflict with an existing broadcast to
17734                // all users.
17735                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17736                        UserHandle.USER_ALL);
17737                if (stickies != null) {
17738                    ArrayList<Intent> list = stickies.get(intent.getAction());
17739                    if (list != null) {
17740                        int N = list.size();
17741                        int i;
17742                        for (i=0; i<N; i++) {
17743                            if (intent.filterEquals(list.get(i))) {
17744                                throw new IllegalArgumentException(
17745                                        "Sticky broadcast " + intent + " for user "
17746                                        + userId + " conflicts with existing global broadcast");
17747                            }
17748                        }
17749                    }
17750                }
17751            }
17752            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17753            if (stickies == null) {
17754                stickies = new ArrayMap<>();
17755                mStickyBroadcasts.put(userId, stickies);
17756            }
17757            ArrayList<Intent> list = stickies.get(intent.getAction());
17758            if (list == null) {
17759                list = new ArrayList<>();
17760                stickies.put(intent.getAction(), list);
17761            }
17762            final int stickiesCount = list.size();
17763            int i;
17764            for (i = 0; i < stickiesCount; i++) {
17765                if (intent.filterEquals(list.get(i))) {
17766                    // This sticky already exists, replace it.
17767                    list.set(i, new Intent(intent));
17768                    break;
17769                }
17770            }
17771            if (i >= stickiesCount) {
17772                list.add(new Intent(intent));
17773            }
17774        }
17775
17776        int[] users;
17777        if (userId == UserHandle.USER_ALL) {
17778            // Caller wants broadcast to go to all started users.
17779            users = mUserController.getStartedUserArrayLocked();
17780        } else {
17781            // Caller wants broadcast to go to one specific user.
17782            users = new int[] {userId};
17783        }
17784
17785        // Figure out who all will receive this broadcast.
17786        List receivers = null;
17787        List<BroadcastFilter> registeredReceivers = null;
17788        // Need to resolve the intent to interested receivers...
17789        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17790                 == 0) {
17791            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17792        }
17793        if (intent.getComponent() == null) {
17794            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17795                // Query one target user at a time, excluding shell-restricted users
17796                for (int i = 0; i < users.length; i++) {
17797                    if (mUserController.hasUserRestriction(
17798                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17799                        continue;
17800                    }
17801                    List<BroadcastFilter> registeredReceiversForUser =
17802                            mReceiverResolver.queryIntent(intent,
17803                                    resolvedType, false, users[i]);
17804                    if (registeredReceivers == null) {
17805                        registeredReceivers = registeredReceiversForUser;
17806                    } else if (registeredReceiversForUser != null) {
17807                        registeredReceivers.addAll(registeredReceiversForUser);
17808                    }
17809                }
17810            } else {
17811                registeredReceivers = mReceiverResolver.queryIntent(intent,
17812                        resolvedType, false, userId);
17813            }
17814        }
17815
17816        final boolean replacePending =
17817                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17818
17819        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17820                + " replacePending=" + replacePending);
17821
17822        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17823        if (!ordered && NR > 0) {
17824            // If we are not serializing this broadcast, then send the
17825            // registered receivers separately so they don't wait for the
17826            // components to be launched.
17827            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17828            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17829                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17830                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17831                    resultExtras, ordered, sticky, false, userId);
17832            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17833            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17834            if (!replaced) {
17835                queue.enqueueParallelBroadcastLocked(r);
17836                queue.scheduleBroadcastsLocked();
17837            }
17838            registeredReceivers = null;
17839            NR = 0;
17840        }
17841
17842        // Merge into one list.
17843        int ir = 0;
17844        if (receivers != null) {
17845            // A special case for PACKAGE_ADDED: do not allow the package
17846            // being added to see this broadcast.  This prevents them from
17847            // using this as a back door to get run as soon as they are
17848            // installed.  Maybe in the future we want to have a special install
17849            // broadcast or such for apps, but we'd like to deliberately make
17850            // this decision.
17851            String skipPackages[] = null;
17852            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17853                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17854                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17855                Uri data = intent.getData();
17856                if (data != null) {
17857                    String pkgName = data.getSchemeSpecificPart();
17858                    if (pkgName != null) {
17859                        skipPackages = new String[] { pkgName };
17860                    }
17861                }
17862            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17863                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17864            }
17865            if (skipPackages != null && (skipPackages.length > 0)) {
17866                for (String skipPackage : skipPackages) {
17867                    if (skipPackage != null) {
17868                        int NT = receivers.size();
17869                        for (int it=0; it<NT; it++) {
17870                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17871                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17872                                receivers.remove(it);
17873                                it--;
17874                                NT--;
17875                            }
17876                        }
17877                    }
17878                }
17879            }
17880
17881            int NT = receivers != null ? receivers.size() : 0;
17882            int it = 0;
17883            ResolveInfo curt = null;
17884            BroadcastFilter curr = null;
17885            while (it < NT && ir < NR) {
17886                if (curt == null) {
17887                    curt = (ResolveInfo)receivers.get(it);
17888                }
17889                if (curr == null) {
17890                    curr = registeredReceivers.get(ir);
17891                }
17892                if (curr.getPriority() >= curt.priority) {
17893                    // Insert this broadcast record into the final list.
17894                    receivers.add(it, curr);
17895                    ir++;
17896                    curr = null;
17897                    it++;
17898                    NT++;
17899                } else {
17900                    // Skip to the next ResolveInfo in the final list.
17901                    it++;
17902                    curt = null;
17903                }
17904            }
17905        }
17906        while (ir < NR) {
17907            if (receivers == null) {
17908                receivers = new ArrayList();
17909            }
17910            receivers.add(registeredReceivers.get(ir));
17911            ir++;
17912        }
17913
17914        if ((receivers != null && receivers.size() > 0)
17915                || resultTo != null) {
17916            BroadcastQueue queue = broadcastQueueForIntent(intent);
17917            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17918                    callerPackage, callingPid, callingUid, resolvedType,
17919                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17920                    resultData, resultExtras, ordered, sticky, false, userId);
17921
17922            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17923                    + ": prev had " + queue.mOrderedBroadcasts.size());
17924            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17925                    "Enqueueing broadcast " + r.intent.getAction());
17926
17927            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17928            if (!replaced) {
17929                queue.enqueueOrderedBroadcastLocked(r);
17930                queue.scheduleBroadcastsLocked();
17931            }
17932        }
17933
17934        return ActivityManager.BROADCAST_SUCCESS;
17935    }
17936
17937    final Intent verifyBroadcastLocked(Intent intent) {
17938        // Refuse possible leaked file descriptors
17939        if (intent != null && intent.hasFileDescriptors() == true) {
17940            throw new IllegalArgumentException("File descriptors passed in Intent");
17941        }
17942
17943        int flags = intent.getFlags();
17944
17945        if (!mProcessesReady) {
17946            // if the caller really truly claims to know what they're doing, go
17947            // ahead and allow the broadcast without launching any receivers
17948            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17949                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17950            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17951                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17952                        + " before boot completion");
17953                throw new IllegalStateException("Cannot broadcast before boot completed");
17954            }
17955        }
17956
17957        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17958            throw new IllegalArgumentException(
17959                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17960        }
17961
17962        return intent;
17963    }
17964
17965    public final int broadcastIntent(IApplicationThread caller,
17966            Intent intent, String resolvedType, IIntentReceiver resultTo,
17967            int resultCode, String resultData, Bundle resultExtras,
17968            String[] requiredPermissions, int appOp, Bundle bOptions,
17969            boolean serialized, boolean sticky, int userId) {
17970        enforceNotIsolatedCaller("broadcastIntent");
17971        synchronized(this) {
17972            intent = verifyBroadcastLocked(intent);
17973
17974            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17975            final int callingPid = Binder.getCallingPid();
17976            final int callingUid = Binder.getCallingUid();
17977            final long origId = Binder.clearCallingIdentity();
17978            int res = broadcastIntentLocked(callerApp,
17979                    callerApp != null ? callerApp.info.packageName : null,
17980                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17981                    requiredPermissions, appOp, bOptions, serialized, sticky,
17982                    callingPid, callingUid, userId);
17983            Binder.restoreCallingIdentity(origId);
17984            return res;
17985        }
17986    }
17987
17988
17989    int broadcastIntentInPackage(String packageName, int uid,
17990            Intent intent, String resolvedType, IIntentReceiver resultTo,
17991            int resultCode, String resultData, Bundle resultExtras,
17992            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17993            int userId) {
17994        synchronized(this) {
17995            intent = verifyBroadcastLocked(intent);
17996
17997            final long origId = Binder.clearCallingIdentity();
17998            String[] requiredPermissions = requiredPermission == null ? null
17999                    : new String[] {requiredPermission};
18000            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18001                    resultTo, resultCode, resultData, resultExtras,
18002                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18003                    sticky, -1, uid, userId);
18004            Binder.restoreCallingIdentity(origId);
18005            return res;
18006        }
18007    }
18008
18009    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18010        // Refuse possible leaked file descriptors
18011        if (intent != null && intent.hasFileDescriptors() == true) {
18012            throw new IllegalArgumentException("File descriptors passed in Intent");
18013        }
18014
18015        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18016                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18017
18018        synchronized(this) {
18019            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18020                    != PackageManager.PERMISSION_GRANTED) {
18021                String msg = "Permission Denial: unbroadcastIntent() from pid="
18022                        + Binder.getCallingPid()
18023                        + ", uid=" + Binder.getCallingUid()
18024                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18025                Slog.w(TAG, msg);
18026                throw new SecurityException(msg);
18027            }
18028            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18029            if (stickies != null) {
18030                ArrayList<Intent> list = stickies.get(intent.getAction());
18031                if (list != null) {
18032                    int N = list.size();
18033                    int i;
18034                    for (i=0; i<N; i++) {
18035                        if (intent.filterEquals(list.get(i))) {
18036                            list.remove(i);
18037                            break;
18038                        }
18039                    }
18040                    if (list.size() <= 0) {
18041                        stickies.remove(intent.getAction());
18042                    }
18043                }
18044                if (stickies.size() <= 0) {
18045                    mStickyBroadcasts.remove(userId);
18046                }
18047            }
18048        }
18049    }
18050
18051    void backgroundServicesFinishedLocked(int userId) {
18052        for (BroadcastQueue queue : mBroadcastQueues) {
18053            queue.backgroundServicesFinishedLocked(userId);
18054        }
18055    }
18056
18057    public void finishReceiver(IBinder who, int resultCode, String resultData,
18058            Bundle resultExtras, boolean resultAbort, int flags) {
18059        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18060
18061        // Refuse possible leaked file descriptors
18062        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18063            throw new IllegalArgumentException("File descriptors passed in Bundle");
18064        }
18065
18066        final long origId = Binder.clearCallingIdentity();
18067        try {
18068            boolean doNext = false;
18069            BroadcastRecord r;
18070
18071            synchronized(this) {
18072                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18073                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18074                r = queue.getMatchingOrderedReceiver(who);
18075                if (r != null) {
18076                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18077                        resultData, resultExtras, resultAbort, true);
18078                }
18079            }
18080
18081            if (doNext) {
18082                r.queue.processNextBroadcast(false);
18083            }
18084            trimApplications();
18085        } finally {
18086            Binder.restoreCallingIdentity(origId);
18087        }
18088    }
18089
18090    // =========================================================
18091    // INSTRUMENTATION
18092    // =========================================================
18093
18094    public boolean startInstrumentation(ComponentName className,
18095            String profileFile, int flags, Bundle arguments,
18096            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18097            int userId, String abiOverride) {
18098        enforceNotIsolatedCaller("startInstrumentation");
18099        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18100                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18101        // Refuse possible leaked file descriptors
18102        if (arguments != null && arguments.hasFileDescriptors()) {
18103            throw new IllegalArgumentException("File descriptors passed in Bundle");
18104        }
18105
18106        synchronized(this) {
18107            InstrumentationInfo ii = null;
18108            ApplicationInfo ai = null;
18109            try {
18110                ii = mContext.getPackageManager().getInstrumentationInfo(
18111                    className, STOCK_PM_FLAGS);
18112                ai = AppGlobals.getPackageManager().getApplicationInfo(
18113                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18114            } catch (PackageManager.NameNotFoundException e) {
18115            } catch (RemoteException e) {
18116            }
18117            if (ii == null) {
18118                reportStartInstrumentationFailureLocked(watcher, className,
18119                        "Unable to find instrumentation info for: " + className);
18120                return false;
18121            }
18122            if (ai == null) {
18123                reportStartInstrumentationFailureLocked(watcher, className,
18124                        "Unable to find instrumentation target package: " + ii.targetPackage);
18125                return false;
18126            }
18127            if (!ai.hasCode()) {
18128                reportStartInstrumentationFailureLocked(watcher, className,
18129                        "Instrumentation target has no code: " + ii.targetPackage);
18130                return false;
18131            }
18132
18133            int match = mContext.getPackageManager().checkSignatures(
18134                    ii.targetPackage, ii.packageName);
18135            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18136                String msg = "Permission Denial: starting instrumentation "
18137                        + className + " from pid="
18138                        + Binder.getCallingPid()
18139                        + ", uid=" + Binder.getCallingPid()
18140                        + " not allowed because package " + ii.packageName
18141                        + " does not have a signature matching the target "
18142                        + ii.targetPackage;
18143                reportStartInstrumentationFailureLocked(watcher, className, msg);
18144                throw new SecurityException(msg);
18145            }
18146
18147            final long origId = Binder.clearCallingIdentity();
18148            // Instrumentation can kill and relaunch even persistent processes
18149            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18150                    "start instr");
18151            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18152            app.instrumentationClass = className;
18153            app.instrumentationInfo = ai;
18154            app.instrumentationProfileFile = profileFile;
18155            app.instrumentationArguments = arguments;
18156            app.instrumentationWatcher = watcher;
18157            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18158            app.instrumentationResultClass = className;
18159            Binder.restoreCallingIdentity(origId);
18160        }
18161
18162        return true;
18163    }
18164
18165    /**
18166     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18167     * error to the logs, but if somebody is watching, send the report there too.  This enables
18168     * the "am" command to report errors with more information.
18169     *
18170     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18171     * @param cn The component name of the instrumentation.
18172     * @param report The error report.
18173     */
18174    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18175            ComponentName cn, String report) {
18176        Slog.w(TAG, report);
18177        if (watcher != null) {
18178            Bundle results = new Bundle();
18179            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18180            results.putString("Error", report);
18181            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18182        }
18183    }
18184
18185    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18186        if (app.instrumentationWatcher != null) {
18187            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18188                    app.instrumentationClass, resultCode, results);
18189        }
18190
18191        // Can't call out of the system process with a lock held, so post a message.
18192        if (app.instrumentationUiAutomationConnection != null) {
18193            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18194                    app.instrumentationUiAutomationConnection).sendToTarget();
18195        }
18196
18197        app.instrumentationWatcher = null;
18198        app.instrumentationUiAutomationConnection = null;
18199        app.instrumentationClass = null;
18200        app.instrumentationInfo = null;
18201        app.instrumentationProfileFile = null;
18202        app.instrumentationArguments = null;
18203
18204        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18205                "finished inst");
18206    }
18207
18208    public void finishInstrumentation(IApplicationThread target,
18209            int resultCode, Bundle results) {
18210        int userId = UserHandle.getCallingUserId();
18211        // Refuse possible leaked file descriptors
18212        if (results != null && results.hasFileDescriptors()) {
18213            throw new IllegalArgumentException("File descriptors passed in Intent");
18214        }
18215
18216        synchronized(this) {
18217            ProcessRecord app = getRecordForAppLocked(target);
18218            if (app == null) {
18219                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18220                return;
18221            }
18222            final long origId = Binder.clearCallingIdentity();
18223            finishInstrumentationLocked(app, resultCode, results);
18224            Binder.restoreCallingIdentity(origId);
18225        }
18226    }
18227
18228    // =========================================================
18229    // CONFIGURATION
18230    // =========================================================
18231
18232    public ConfigurationInfo getDeviceConfigurationInfo() {
18233        ConfigurationInfo config = new ConfigurationInfo();
18234        synchronized (this) {
18235            config.reqTouchScreen = mConfiguration.touchscreen;
18236            config.reqKeyboardType = mConfiguration.keyboard;
18237            config.reqNavigation = mConfiguration.navigation;
18238            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18239                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18240                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18241            }
18242            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18243                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18244                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18245            }
18246            config.reqGlEsVersion = GL_ES_VERSION;
18247        }
18248        return config;
18249    }
18250
18251    ActivityStack getFocusedStack() {
18252        return mStackSupervisor.getFocusedStack();
18253    }
18254
18255    @Override
18256    public int getFocusedStackId() throws RemoteException {
18257        ActivityStack focusedStack = getFocusedStack();
18258        if (focusedStack != null) {
18259            return focusedStack.getStackId();
18260        }
18261        return -1;
18262    }
18263
18264    public Configuration getConfiguration() {
18265        Configuration ci;
18266        synchronized(this) {
18267            ci = new Configuration(mConfiguration);
18268            ci.userSetLocale = false;
18269        }
18270        return ci;
18271    }
18272
18273    @Override
18274    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18275        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18276        synchronized (this) {
18277            mSuppressResizeConfigChanges = suppress;
18278        }
18279    }
18280
18281    @Override
18282    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18283        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18284        if (fromStackId == HOME_STACK_ID) {
18285            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18286        }
18287        synchronized (this) {
18288            final long origId = Binder.clearCallingIdentity();
18289            try {
18290                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18291            } finally {
18292                Binder.restoreCallingIdentity(origId);
18293            }
18294        }
18295    }
18296
18297    @Override
18298    public void updatePersistentConfiguration(Configuration values) {
18299        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18300                "updateConfiguration()");
18301        enforceWriteSettingsPermission("updateConfiguration()");
18302        if (values == null) {
18303            throw new NullPointerException("Configuration must not be null");
18304        }
18305
18306        int userId = UserHandle.getCallingUserId();
18307
18308        synchronized(this) {
18309            final long origId = Binder.clearCallingIdentity();
18310            updateConfigurationLocked(values, null, false, true, userId);
18311            Binder.restoreCallingIdentity(origId);
18312        }
18313    }
18314
18315    private void updateFontScaleIfNeeded() {
18316        final int currentUserId;
18317        synchronized(this) {
18318            currentUserId = mUserController.getCurrentUserIdLocked();
18319        }
18320        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18321                FONT_SCALE, 1.0f, currentUserId);
18322        if (mConfiguration.fontScale != scaleFactor) {
18323            final Configuration configuration = mWindowManager.computeNewConfiguration();
18324            configuration.fontScale = scaleFactor;
18325            updatePersistentConfiguration(configuration);
18326        }
18327    }
18328
18329    private void enforceWriteSettingsPermission(String func) {
18330        int uid = Binder.getCallingUid();
18331        if (uid == Process.ROOT_UID) {
18332            return;
18333        }
18334
18335        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18336                Settings.getPackageNameForUid(mContext, uid), false)) {
18337            return;
18338        }
18339
18340        String msg = "Permission Denial: " + func + " from pid="
18341                + Binder.getCallingPid()
18342                + ", uid=" + uid
18343                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18344        Slog.w(TAG, msg);
18345        throw new SecurityException(msg);
18346    }
18347
18348    public void updateConfiguration(Configuration values) {
18349        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18350                "updateConfiguration()");
18351
18352        synchronized(this) {
18353            if (values == null && mWindowManager != null) {
18354                // sentinel: fetch the current configuration from the window manager
18355                values = mWindowManager.computeNewConfiguration();
18356            }
18357
18358            if (mWindowManager != null) {
18359                mProcessList.applyDisplaySize(mWindowManager);
18360            }
18361
18362            final long origId = Binder.clearCallingIdentity();
18363            if (values != null) {
18364                Settings.System.clearConfiguration(values);
18365            }
18366            updateConfigurationLocked(values, null, false);
18367            Binder.restoreCallingIdentity(origId);
18368        }
18369    }
18370
18371    void updateUserConfigurationLocked() {
18372        Configuration configuration = new Configuration(mConfiguration);
18373        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18374                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18375        updateConfigurationLocked(configuration, null, false);
18376    }
18377
18378    boolean updateConfigurationLocked(Configuration values,
18379            ActivityRecord starting, boolean initLocale) {
18380        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18381        return updateConfigurationLocked(values, starting, initLocale, false,
18382                UserHandle.USER_NULL);
18383    }
18384
18385    // To cache the list of supported system locales
18386    private String[] mSupportedSystemLocales = null;
18387
18388    /**
18389     * Do either or both things: (1) change the current configuration, and (2)
18390     * make sure the given activity is running with the (now) current
18391     * configuration.  Returns true if the activity has been left running, or
18392     * false if <var>starting</var> is being destroyed to match the new
18393     * configuration.
18394     *
18395     * @param userId is only used when persistent parameter is set to true to persist configuration
18396     *               for that particular user
18397     */
18398    private boolean updateConfigurationLocked(Configuration values,
18399            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18400        int changes = 0;
18401
18402        if (mWindowManager != null) {
18403            mWindowManager.deferSurfaceLayout();
18404        }
18405        if (values != null) {
18406            Configuration newConfig = new Configuration(mConfiguration);
18407            changes = newConfig.updateFrom(values);
18408            if (changes != 0) {
18409                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18410                        "Updating configuration to: " + values);
18411
18412                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18413
18414                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18415                    final LocaleList locales = values.getLocales();
18416                    int bestLocaleIndex = 0;
18417                    if (locales.size() > 1) {
18418                        if (mSupportedSystemLocales == null) {
18419                            mSupportedSystemLocales =
18420                                    Resources.getSystem().getAssets().getLocales();
18421                        }
18422                        bestLocaleIndex = Math.max(0,
18423                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18424                    }
18425                    SystemProperties.set("persist.sys.locale",
18426                            locales.get(bestLocaleIndex).toLanguageTag());
18427                    LocaleList.setDefault(locales, bestLocaleIndex);
18428                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18429                            locales.get(bestLocaleIndex)));
18430                }
18431
18432                mConfigurationSeq++;
18433                if (mConfigurationSeq <= 0) {
18434                    mConfigurationSeq = 1;
18435                }
18436                newConfig.seq = mConfigurationSeq;
18437                mConfiguration = newConfig;
18438                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18439                mUsageStatsService.reportConfigurationChange(newConfig,
18440                        mUserController.getCurrentUserIdLocked());
18441                //mUsageStatsService.noteStartConfig(newConfig);
18442
18443                final Configuration configCopy = new Configuration(mConfiguration);
18444
18445                // TODO: If our config changes, should we auto dismiss any currently
18446                // showing dialogs?
18447                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18448
18449                AttributeCache ac = AttributeCache.instance();
18450                if (ac != null) {
18451                    ac.updateConfiguration(configCopy);
18452                }
18453
18454                // Make sure all resources in our process are updated
18455                // right now, so that anyone who is going to retrieve
18456                // resource values after we return will be sure to get
18457                // the new ones.  This is especially important during
18458                // boot, where the first config change needs to guarantee
18459                // all resources have that config before following boot
18460                // code is executed.
18461                mSystemThread.applyConfigurationToResources(configCopy);
18462
18463                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18464                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18465                    msg.obj = new Configuration(configCopy);
18466                    msg.arg1 = userId;
18467                    mHandler.sendMessage(msg);
18468                }
18469
18470                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18471                if (isDensityChange) {
18472                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18473                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18474                }
18475
18476                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18477                    ProcessRecord app = mLruProcesses.get(i);
18478                    try {
18479                        if (app.thread != null) {
18480                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18481                                    + app.processName + " new config " + mConfiguration);
18482                            app.thread.scheduleConfigurationChanged(configCopy);
18483                        }
18484                    } catch (Exception e) {
18485                    }
18486                }
18487                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18488                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18489                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18490                        | Intent.FLAG_RECEIVER_FOREGROUND);
18491                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18492                        null, AppOpsManager.OP_NONE, null, false, false,
18493                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18494                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18495                    // Tell the shortcut manager that the system locale changed.  It needs to know
18496                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18497                    // we "push" from here, rather than having the service listen to the broadcast.
18498                    final ShortcutServiceInternal shortcutService =
18499                            LocalServices.getService(ShortcutServiceInternal.class);
18500                    if (shortcutService != null) {
18501                        shortcutService.onSystemLocaleChangedNoLock();
18502                    }
18503
18504                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18505                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18506                    if (!mProcessesReady) {
18507                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18508                    }
18509                    broadcastIntentLocked(null, null, intent,
18510                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18511                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18512                }
18513            }
18514            // Update the configuration with WM first and check if any of the stacks need to be
18515            // resized due to the configuration change. If so, resize the stacks now and do any
18516            // relaunches if necessary. This way we don't need to relaunch again below in
18517            // ensureActivityConfigurationLocked().
18518            if (mWindowManager != null) {
18519                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18520                if (resizedStacks != null) {
18521                    for (int stackId : resizedStacks) {
18522                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18523                        mStackSupervisor.resizeStackLocked(
18524                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18525                    }
18526                }
18527            }
18528        }
18529
18530        boolean kept = true;
18531        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18532        // mainStack is null during startup.
18533        if (mainStack != null) {
18534            if (changes != 0 && starting == null) {
18535                // If the configuration changed, and the caller is not already
18536                // in the process of starting an activity, then find the top
18537                // activity to check if its configuration needs to change.
18538                starting = mainStack.topRunningActivityLocked();
18539            }
18540
18541            if (starting != null) {
18542                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18543                // And we need to make sure at this point that all other activities
18544                // are made visible with the correct configuration.
18545                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18546                        !PRESERVE_WINDOWS);
18547            }
18548        }
18549        if (mWindowManager != null) {
18550            mWindowManager.continueSurfaceLayout();
18551        }
18552        return kept;
18553    }
18554
18555    /**
18556     * Decide based on the configuration whether we should shouw the ANR,
18557     * crash, etc dialogs.  The idea is that if there is no affordnace to
18558     * press the on-screen buttons, we shouldn't show the dialog.
18559     *
18560     * A thought: SystemUI might also want to get told about this, the Power
18561     * dialog / global actions also might want different behaviors.
18562     */
18563    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18564        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18565                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18566                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18567        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18568                                    == Configuration.UI_MODE_TYPE_CAR);
18569        return inputMethodExists && uiIsNotCarType && !inVrMode;
18570    }
18571
18572    @Override
18573    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18574        synchronized (this) {
18575            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18576            if (srec != null) {
18577                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18578            }
18579        }
18580        return false;
18581    }
18582
18583    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18584            Intent resultData) {
18585
18586        synchronized (this) {
18587            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18588            if (r != null) {
18589                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18590            }
18591            return false;
18592        }
18593    }
18594
18595    public int getLaunchedFromUid(IBinder activityToken) {
18596        ActivityRecord srec;
18597        synchronized (this) {
18598            srec = ActivityRecord.forTokenLocked(activityToken);
18599        }
18600        if (srec == null) {
18601            return -1;
18602        }
18603        return srec.launchedFromUid;
18604    }
18605
18606    public String getLaunchedFromPackage(IBinder activityToken) {
18607        ActivityRecord srec;
18608        synchronized (this) {
18609            srec = ActivityRecord.forTokenLocked(activityToken);
18610        }
18611        if (srec == null) {
18612            return null;
18613        }
18614        return srec.launchedFromPackage;
18615    }
18616
18617    // =========================================================
18618    // LIFETIME MANAGEMENT
18619    // =========================================================
18620
18621    // Returns which broadcast queue the app is the current [or imminent] receiver
18622    // on, or 'null' if the app is not an active broadcast recipient.
18623    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18624        BroadcastRecord r = app.curReceiver;
18625        if (r != null) {
18626            return r.queue;
18627        }
18628
18629        // It's not the current receiver, but it might be starting up to become one
18630        synchronized (this) {
18631            for (BroadcastQueue queue : mBroadcastQueues) {
18632                r = queue.mPendingBroadcast;
18633                if (r != null && r.curApp == app) {
18634                    // found it; report which queue it's in
18635                    return queue;
18636                }
18637            }
18638        }
18639
18640        return null;
18641    }
18642
18643    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18644            int targetUid, ComponentName targetComponent, String targetProcess) {
18645        if (!mTrackingAssociations) {
18646            return null;
18647        }
18648        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18649                = mAssociations.get(targetUid);
18650        if (components == null) {
18651            components = new ArrayMap<>();
18652            mAssociations.put(targetUid, components);
18653        }
18654        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18655        if (sourceUids == null) {
18656            sourceUids = new SparseArray<>();
18657            components.put(targetComponent, sourceUids);
18658        }
18659        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18660        if (sourceProcesses == null) {
18661            sourceProcesses = new ArrayMap<>();
18662            sourceUids.put(sourceUid, sourceProcesses);
18663        }
18664        Association ass = sourceProcesses.get(sourceProcess);
18665        if (ass == null) {
18666            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18667                    targetProcess);
18668            sourceProcesses.put(sourceProcess, ass);
18669        }
18670        ass.mCount++;
18671        ass.mNesting++;
18672        if (ass.mNesting == 1) {
18673            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18674            ass.mLastState = sourceState;
18675        }
18676        return ass;
18677    }
18678
18679    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18680            ComponentName targetComponent) {
18681        if (!mTrackingAssociations) {
18682            return;
18683        }
18684        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18685                = mAssociations.get(targetUid);
18686        if (components == null) {
18687            return;
18688        }
18689        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18690        if (sourceUids == null) {
18691            return;
18692        }
18693        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18694        if (sourceProcesses == null) {
18695            return;
18696        }
18697        Association ass = sourceProcesses.get(sourceProcess);
18698        if (ass == null || ass.mNesting <= 0) {
18699            return;
18700        }
18701        ass.mNesting--;
18702        if (ass.mNesting == 0) {
18703            long uptime = SystemClock.uptimeMillis();
18704            ass.mTime += uptime - ass.mStartTime;
18705            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18706                    += uptime - ass.mLastStateUptime;
18707            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18708        }
18709    }
18710
18711    private void noteUidProcessState(final int uid, final int state) {
18712        mBatteryStatsService.noteUidProcessState(uid, state);
18713        if (mTrackingAssociations) {
18714            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18715                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18716                        = mAssociations.valueAt(i1);
18717                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18718                    SparseArray<ArrayMap<String, Association>> sourceUids
18719                            = targetComponents.valueAt(i2);
18720                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18721                    if (sourceProcesses != null) {
18722                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18723                            Association ass = sourceProcesses.valueAt(i4);
18724                            if (ass.mNesting >= 1) {
18725                                // currently associated
18726                                long uptime = SystemClock.uptimeMillis();
18727                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18728                                        += uptime - ass.mLastStateUptime;
18729                                ass.mLastState = state;
18730                                ass.mLastStateUptime = uptime;
18731                            }
18732                        }
18733                    }
18734                }
18735            }
18736        }
18737    }
18738
18739    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18740            boolean doingAll, long now) {
18741        if (mAdjSeq == app.adjSeq) {
18742            // This adjustment has already been computed.
18743            return app.curRawAdj;
18744        }
18745
18746        if (app.thread == null) {
18747            app.adjSeq = mAdjSeq;
18748            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18749            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18750            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18751        }
18752
18753        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18754        app.adjSource = null;
18755        app.adjTarget = null;
18756        app.empty = false;
18757        app.cached = false;
18758
18759        final int activitiesSize = app.activities.size();
18760
18761        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18762            // The max adjustment doesn't allow this app to be anything
18763            // below foreground, so it is not worth doing work for it.
18764            app.adjType = "fixed";
18765            app.adjSeq = mAdjSeq;
18766            app.curRawAdj = app.maxAdj;
18767            app.foregroundActivities = false;
18768            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18769            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18770            // System processes can do UI, and when they do we want to have
18771            // them trim their memory after the user leaves the UI.  To
18772            // facilitate this, here we need to determine whether or not it
18773            // is currently showing UI.
18774            app.systemNoUi = true;
18775            if (app == TOP_APP) {
18776                app.systemNoUi = false;
18777                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18778                app.adjType = "pers-top-activity";
18779            } else if (activitiesSize > 0) {
18780                for (int j = 0; j < activitiesSize; j++) {
18781                    final ActivityRecord r = app.activities.get(j);
18782                    if (r.visible) {
18783                        app.systemNoUi = false;
18784                    }
18785                }
18786            }
18787            if (!app.systemNoUi) {
18788                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18789            }
18790            return (app.curAdj=app.maxAdj);
18791        }
18792
18793        app.systemNoUi = false;
18794
18795        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18796
18797        // Determine the importance of the process, starting with most
18798        // important to least, and assign an appropriate OOM adjustment.
18799        int adj;
18800        int schedGroup;
18801        int procState;
18802        boolean foregroundActivities = false;
18803        BroadcastQueue queue;
18804        if (app == TOP_APP) {
18805            // The last app on the list is the foreground app.
18806            adj = ProcessList.FOREGROUND_APP_ADJ;
18807            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18808            app.adjType = "top-activity";
18809            foregroundActivities = true;
18810            procState = PROCESS_STATE_CUR_TOP;
18811        } else if (app.instrumentationClass != null) {
18812            // Don't want to kill running instrumentation.
18813            adj = ProcessList.FOREGROUND_APP_ADJ;
18814            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18815            app.adjType = "instrumentation";
18816            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18817        } else if ((queue = isReceivingBroadcast(app)) != null) {
18818            // An app that is currently receiving a broadcast also
18819            // counts as being in the foreground for OOM killer purposes.
18820            // It's placed in a sched group based on the nature of the
18821            // broadcast as reflected by which queue it's active in.
18822            adj = ProcessList.FOREGROUND_APP_ADJ;
18823            schedGroup = (queue == mFgBroadcastQueue)
18824                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18825            app.adjType = "broadcast";
18826            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18827        } else if (app.executingServices.size() > 0) {
18828            // An app that is currently executing a service callback also
18829            // counts as being in the foreground.
18830            adj = ProcessList.FOREGROUND_APP_ADJ;
18831            schedGroup = app.execServicesFg ?
18832                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18833            app.adjType = "exec-service";
18834            procState = ActivityManager.PROCESS_STATE_SERVICE;
18835            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18836        } else {
18837            // As far as we know the process is empty.  We may change our mind later.
18838            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18839            // At this point we don't actually know the adjustment.  Use the cached adj
18840            // value that the caller wants us to.
18841            adj = cachedAdj;
18842            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18843            app.cached = true;
18844            app.empty = true;
18845            app.adjType = "cch-empty";
18846        }
18847
18848        // Examine all activities if not already foreground.
18849        if (!foregroundActivities && activitiesSize > 0) {
18850            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18851            for (int j = 0; j < activitiesSize; j++) {
18852                final ActivityRecord r = app.activities.get(j);
18853                if (r.app != app) {
18854                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18855                            + " instead of expected " + app);
18856                    if (r.app == null || (r.app.uid == app.uid)) {
18857                        // Only fix things up when they look sane
18858                        r.app = app;
18859                    } else {
18860                        continue;
18861                    }
18862                }
18863                if (r.visible) {
18864                    // App has a visible activity; only upgrade adjustment.
18865                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18866                        adj = ProcessList.VISIBLE_APP_ADJ;
18867                        app.adjType = "visible";
18868                    }
18869                    if (procState > PROCESS_STATE_CUR_TOP) {
18870                        procState = PROCESS_STATE_CUR_TOP;
18871                    }
18872                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18873                    app.cached = false;
18874                    app.empty = false;
18875                    foregroundActivities = true;
18876                    if (r.task != null && minLayer > 0) {
18877                        final int layer = r.task.mLayerRank;
18878                        if (layer >= 0 && minLayer > layer) {
18879                            minLayer = layer;
18880                        }
18881                    }
18882                    break;
18883                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18884                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18885                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18886                        app.adjType = "pausing";
18887                    }
18888                    if (procState > PROCESS_STATE_CUR_TOP) {
18889                        procState = PROCESS_STATE_CUR_TOP;
18890                    }
18891                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18892                    app.cached = false;
18893                    app.empty = false;
18894                    foregroundActivities = true;
18895                } else if (r.state == ActivityState.STOPPING) {
18896                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18897                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18898                        app.adjType = "stopping";
18899                    }
18900                    // For the process state, we will at this point consider the
18901                    // process to be cached.  It will be cached either as an activity
18902                    // or empty depending on whether the activity is finishing.  We do
18903                    // this so that we can treat the process as cached for purposes of
18904                    // memory trimming (determing current memory level, trim command to
18905                    // send to process) since there can be an arbitrary number of stopping
18906                    // processes and they should soon all go into the cached state.
18907                    if (!r.finishing) {
18908                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18909                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18910                        }
18911                    }
18912                    app.cached = false;
18913                    app.empty = false;
18914                    foregroundActivities = true;
18915                } else {
18916                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18917                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18918                        app.adjType = "cch-act";
18919                    }
18920                }
18921            }
18922            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18923                adj += minLayer;
18924            }
18925        }
18926
18927        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18928                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18929            if (app.foregroundServices) {
18930                // The user is aware of this app, so make it visible.
18931                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18932                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18933                app.cached = false;
18934                app.adjType = "fg-service";
18935                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18936            } else if (app.forcingToForeground != null) {
18937                // The user is aware of this app, so make it visible.
18938                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18939                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18940                app.cached = false;
18941                app.adjType = "force-fg";
18942                app.adjSource = app.forcingToForeground;
18943                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18944            }
18945        }
18946
18947        if (app == mHeavyWeightProcess) {
18948            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18949                // We don't want to kill the current heavy-weight process.
18950                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18951                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18952                app.cached = false;
18953                app.adjType = "heavy";
18954            }
18955            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18956                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18957            }
18958        }
18959
18960        if (app == mHomeProcess) {
18961            if (adj > ProcessList.HOME_APP_ADJ) {
18962                // This process is hosting what we currently consider to be the
18963                // home app, so we don't want to let it go into the background.
18964                adj = ProcessList.HOME_APP_ADJ;
18965                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18966                app.cached = false;
18967                app.adjType = "home";
18968            }
18969            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18970                procState = ActivityManager.PROCESS_STATE_HOME;
18971            }
18972        }
18973
18974        if (app == mPreviousProcess && app.activities.size() > 0) {
18975            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18976                // This was the previous process that showed UI to the user.
18977                // We want to try to keep it around more aggressively, to give
18978                // a good experience around switching between two apps.
18979                adj = ProcessList.PREVIOUS_APP_ADJ;
18980                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18981                app.cached = false;
18982                app.adjType = "previous";
18983            }
18984            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18985                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18986            }
18987        }
18988
18989        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18990                + " reason=" + app.adjType);
18991
18992        // By default, we use the computed adjustment.  It may be changed if
18993        // there are applications dependent on our services or providers, but
18994        // this gives us a baseline and makes sure we don't get into an
18995        // infinite recursion.
18996        app.adjSeq = mAdjSeq;
18997        app.curRawAdj = adj;
18998        app.hasStartedServices = false;
18999
19000        if (mBackupTarget != null && app == mBackupTarget.app) {
19001            // If possible we want to avoid killing apps while they're being backed up
19002            if (adj > ProcessList.BACKUP_APP_ADJ) {
19003                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19004                adj = ProcessList.BACKUP_APP_ADJ;
19005                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19006                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19007                }
19008                app.adjType = "backup";
19009                app.cached = false;
19010            }
19011            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19012                procState = ActivityManager.PROCESS_STATE_BACKUP;
19013            }
19014        }
19015
19016        boolean mayBeTop = false;
19017
19018        for (int is = app.services.size()-1;
19019                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19020                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19021                        || procState > ActivityManager.PROCESS_STATE_TOP);
19022                is--) {
19023            ServiceRecord s = app.services.valueAt(is);
19024            if (s.startRequested) {
19025                app.hasStartedServices = true;
19026                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19027                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19028                }
19029                if (app.hasShownUi && app != mHomeProcess) {
19030                    // If this process has shown some UI, let it immediately
19031                    // go to the LRU list because it may be pretty heavy with
19032                    // UI stuff.  We'll tag it with a label just to help
19033                    // debug and understand what is going on.
19034                    if (adj > ProcessList.SERVICE_ADJ) {
19035                        app.adjType = "cch-started-ui-services";
19036                    }
19037                } else {
19038                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19039                        // This service has seen some activity within
19040                        // recent memory, so we will keep its process ahead
19041                        // of the background processes.
19042                        if (adj > ProcessList.SERVICE_ADJ) {
19043                            adj = ProcessList.SERVICE_ADJ;
19044                            app.adjType = "started-services";
19045                            app.cached = false;
19046                        }
19047                    }
19048                    // If we have let the service slide into the background
19049                    // state, still have some text describing what it is doing
19050                    // even though the service no longer has an impact.
19051                    if (adj > ProcessList.SERVICE_ADJ) {
19052                        app.adjType = "cch-started-services";
19053                    }
19054                }
19055            }
19056
19057            app.whitelistManager = false;
19058
19059            for (int conni = s.connections.size()-1;
19060                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19061                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19062                            || procState > ActivityManager.PROCESS_STATE_TOP);
19063                    conni--) {
19064                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19065                for (int i = 0;
19066                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19067                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19068                                || procState > ActivityManager.PROCESS_STATE_TOP);
19069                        i++) {
19070                    // XXX should compute this based on the max of
19071                    // all connected clients.
19072                    ConnectionRecord cr = clist.get(i);
19073                    if (cr.binding.client == app) {
19074                        // Binding to ourself is not interesting.
19075                        continue;
19076                    }
19077                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19078                        app.whitelistManager = true;
19079                    }
19080
19081                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19082                        ProcessRecord client = cr.binding.client;
19083                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19084                                TOP_APP, doingAll, now);
19085                        int clientProcState = client.curProcState;
19086                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19087                            // If the other app is cached for any reason, for purposes here
19088                            // we are going to consider it empty.  The specific cached state
19089                            // doesn't propagate except under certain conditions.
19090                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19091                        }
19092                        String adjType = null;
19093                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19094                            // Not doing bind OOM management, so treat
19095                            // this guy more like a started service.
19096                            if (app.hasShownUi && app != mHomeProcess) {
19097                                // If this process has shown some UI, let it immediately
19098                                // go to the LRU list because it may be pretty heavy with
19099                                // UI stuff.  We'll tag it with a label just to help
19100                                // debug and understand what is going on.
19101                                if (adj > clientAdj) {
19102                                    adjType = "cch-bound-ui-services";
19103                                }
19104                                app.cached = false;
19105                                clientAdj = adj;
19106                                clientProcState = procState;
19107                            } else {
19108                                if (now >= (s.lastActivity
19109                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19110                                    // This service has not seen activity within
19111                                    // recent memory, so allow it to drop to the
19112                                    // LRU list if there is no other reason to keep
19113                                    // it around.  We'll also tag it with a label just
19114                                    // to help debug and undertand what is going on.
19115                                    if (adj > clientAdj) {
19116                                        adjType = "cch-bound-services";
19117                                    }
19118                                    clientAdj = adj;
19119                                }
19120                            }
19121                        }
19122                        if (adj > clientAdj) {
19123                            // If this process has recently shown UI, and
19124                            // the process that is binding to it is less
19125                            // important than being visible, then we don't
19126                            // care about the binding as much as we care
19127                            // about letting this process get into the LRU
19128                            // list to be killed and restarted if needed for
19129                            // memory.
19130                            if (app.hasShownUi && app != mHomeProcess
19131                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19132                                adjType = "cch-bound-ui-services";
19133                            } else {
19134                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19135                                        |Context.BIND_IMPORTANT)) != 0) {
19136                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19137                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19138                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19139                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19140                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19141                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19142                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19143                                    adj = clientAdj;
19144                                } else {
19145                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19146                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19147                                    }
19148                                }
19149                                if (!client.cached) {
19150                                    app.cached = false;
19151                                }
19152                                adjType = "service";
19153                            }
19154                        }
19155                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19156                            // This will treat important bound services identically to
19157                            // the top app, which may behave differently than generic
19158                            // foreground work.
19159                            if (client.curSchedGroup > schedGroup) {
19160                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19161                                    schedGroup = client.curSchedGroup;
19162                                } else {
19163                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19164                                }
19165                            }
19166                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19167                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19168                                    // Special handling of clients who are in the top state.
19169                                    // We *may* want to consider this process to be in the
19170                                    // top state as well, but only if there is not another
19171                                    // reason for it to be running.  Being on the top is a
19172                                    // special state, meaning you are specifically running
19173                                    // for the current top app.  If the process is already
19174                                    // running in the background for some other reason, it
19175                                    // is more important to continue considering it to be
19176                                    // in the background state.
19177                                    mayBeTop = true;
19178                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19179                                } else {
19180                                    // Special handling for above-top states (persistent
19181                                    // processes).  These should not bring the current process
19182                                    // into the top state, since they are not on top.  Instead
19183                                    // give them the best state after that.
19184                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19185                                        clientProcState =
19186                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19187                                    } else if (mWakefulness
19188                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19189                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19190                                                    != 0) {
19191                                        clientProcState =
19192                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19193                                    } else {
19194                                        clientProcState =
19195                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19196                                    }
19197                                }
19198                            }
19199                        } else {
19200                            if (clientProcState <
19201                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19202                                clientProcState =
19203                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19204                            }
19205                        }
19206                        if (procState > clientProcState) {
19207                            procState = clientProcState;
19208                        }
19209                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19210                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19211                            app.pendingUiClean = true;
19212                        }
19213                        if (adjType != null) {
19214                            app.adjType = adjType;
19215                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19216                                    .REASON_SERVICE_IN_USE;
19217                            app.adjSource = cr.binding.client;
19218                            app.adjSourceProcState = clientProcState;
19219                            app.adjTarget = s.name;
19220                        }
19221                    }
19222                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19223                        app.treatLikeActivity = true;
19224                    }
19225                    final ActivityRecord a = cr.activity;
19226                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19227                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19228                            (a.visible || a.state == ActivityState.RESUMED ||
19229                             a.state == ActivityState.PAUSING)) {
19230                            adj = ProcessList.FOREGROUND_APP_ADJ;
19231                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19232                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19233                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19234                                } else {
19235                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19236                                }
19237                            }
19238                            app.cached = false;
19239                            app.adjType = "service";
19240                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19241                                    .REASON_SERVICE_IN_USE;
19242                            app.adjSource = a;
19243                            app.adjSourceProcState = procState;
19244                            app.adjTarget = s.name;
19245                        }
19246                    }
19247                }
19248            }
19249        }
19250
19251        for (int provi = app.pubProviders.size()-1;
19252                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19253                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19254                        || procState > ActivityManager.PROCESS_STATE_TOP);
19255                provi--) {
19256            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19257            for (int i = cpr.connections.size()-1;
19258                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19259                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19260                            || procState > ActivityManager.PROCESS_STATE_TOP);
19261                    i--) {
19262                ContentProviderConnection conn = cpr.connections.get(i);
19263                ProcessRecord client = conn.client;
19264                if (client == app) {
19265                    // Being our own client is not interesting.
19266                    continue;
19267                }
19268                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19269                int clientProcState = client.curProcState;
19270                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19271                    // If the other app is cached for any reason, for purposes here
19272                    // we are going to consider it empty.
19273                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19274                }
19275                if (adj > clientAdj) {
19276                    if (app.hasShownUi && app != mHomeProcess
19277                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19278                        app.adjType = "cch-ui-provider";
19279                    } else {
19280                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19281                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19282                        app.adjType = "provider";
19283                    }
19284                    app.cached &= client.cached;
19285                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19286                            .REASON_PROVIDER_IN_USE;
19287                    app.adjSource = client;
19288                    app.adjSourceProcState = clientProcState;
19289                    app.adjTarget = cpr.name;
19290                }
19291                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19292                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19293                        // Special handling of clients who are in the top state.
19294                        // We *may* want to consider this process to be in the
19295                        // top state as well, but only if there is not another
19296                        // reason for it to be running.  Being on the top is a
19297                        // special state, meaning you are specifically running
19298                        // for the current top app.  If the process is already
19299                        // running in the background for some other reason, it
19300                        // is more important to continue considering it to be
19301                        // in the background state.
19302                        mayBeTop = true;
19303                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19304                    } else {
19305                        // Special handling for above-top states (persistent
19306                        // processes).  These should not bring the current process
19307                        // into the top state, since they are not on top.  Instead
19308                        // give them the best state after that.
19309                        clientProcState =
19310                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19311                    }
19312                }
19313                if (procState > clientProcState) {
19314                    procState = clientProcState;
19315                }
19316                if (client.curSchedGroup > schedGroup) {
19317                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19318                }
19319            }
19320            // If the provider has external (non-framework) process
19321            // dependencies, ensure that its adjustment is at least
19322            // FOREGROUND_APP_ADJ.
19323            if (cpr.hasExternalProcessHandles()) {
19324                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19325                    adj = ProcessList.FOREGROUND_APP_ADJ;
19326                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19327                    app.cached = false;
19328                    app.adjType = "provider";
19329                    app.adjTarget = cpr.name;
19330                }
19331                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19332                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19333                }
19334            }
19335        }
19336
19337        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19338            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19339                adj = ProcessList.PREVIOUS_APP_ADJ;
19340                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19341                app.cached = false;
19342                app.adjType = "provider";
19343            }
19344            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19345                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19346            }
19347        }
19348
19349        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19350            // A client of one of our services or providers is in the top state.  We
19351            // *may* want to be in the top state, but not if we are already running in
19352            // the background for some other reason.  For the decision here, we are going
19353            // to pick out a few specific states that we want to remain in when a client
19354            // is top (states that tend to be longer-term) and otherwise allow it to go
19355            // to the top state.
19356            switch (procState) {
19357                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19358                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19359                case ActivityManager.PROCESS_STATE_SERVICE:
19360                    // These all are longer-term states, so pull them up to the top
19361                    // of the background states, but not all the way to the top state.
19362                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19363                    break;
19364                default:
19365                    // Otherwise, top is a better choice, so take it.
19366                    procState = ActivityManager.PROCESS_STATE_TOP;
19367                    break;
19368            }
19369        }
19370
19371        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19372            if (app.hasClientActivities) {
19373                // This is a cached process, but with client activities.  Mark it so.
19374                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19375                app.adjType = "cch-client-act";
19376            } else if (app.treatLikeActivity) {
19377                // This is a cached process, but somebody wants us to treat it like it has
19378                // an activity, okay!
19379                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19380                app.adjType = "cch-as-act";
19381            }
19382        }
19383
19384        if (adj == ProcessList.SERVICE_ADJ) {
19385            if (doingAll) {
19386                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19387                mNewNumServiceProcs++;
19388                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19389                if (!app.serviceb) {
19390                    // This service isn't far enough down on the LRU list to
19391                    // normally be a B service, but if we are low on RAM and it
19392                    // is large we want to force it down since we would prefer to
19393                    // keep launcher over it.
19394                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19395                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19396                        app.serviceHighRam = true;
19397                        app.serviceb = true;
19398                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19399                    } else {
19400                        mNewNumAServiceProcs++;
19401                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19402                    }
19403                } else {
19404                    app.serviceHighRam = false;
19405                }
19406            }
19407            if (app.serviceb) {
19408                adj = ProcessList.SERVICE_B_ADJ;
19409            }
19410        }
19411
19412        app.curRawAdj = adj;
19413
19414        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19415        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19416        if (adj > app.maxAdj) {
19417            adj = app.maxAdj;
19418            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19419                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19420            }
19421        }
19422
19423        // Do final modification to adj.  Everything we do between here and applying
19424        // the final setAdj must be done in this function, because we will also use
19425        // it when computing the final cached adj later.  Note that we don't need to
19426        // worry about this for max adj above, since max adj will always be used to
19427        // keep it out of the cached vaues.
19428        app.curAdj = app.modifyRawOomAdj(adj);
19429        app.curSchedGroup = schedGroup;
19430        app.curProcState = procState;
19431        app.foregroundActivities = foregroundActivities;
19432
19433        return app.curRawAdj;
19434    }
19435
19436    /**
19437     * Record new PSS sample for a process.
19438     */
19439    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19440            long now) {
19441        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19442                swapPss * 1024);
19443        proc.lastPssTime = now;
19444        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19445        if (DEBUG_PSS) Slog.d(TAG_PSS,
19446                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19447                + " state=" + ProcessList.makeProcStateString(procState));
19448        if (proc.initialIdlePss == 0) {
19449            proc.initialIdlePss = pss;
19450        }
19451        proc.lastPss = pss;
19452        proc.lastSwapPss = swapPss;
19453        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19454            proc.lastCachedPss = pss;
19455            proc.lastCachedSwapPss = swapPss;
19456        }
19457
19458        final SparseArray<Pair<Long, String>> watchUids
19459                = mMemWatchProcesses.getMap().get(proc.processName);
19460        Long check = null;
19461        if (watchUids != null) {
19462            Pair<Long, String> val = watchUids.get(proc.uid);
19463            if (val == null) {
19464                val = watchUids.get(0);
19465            }
19466            if (val != null) {
19467                check = val.first;
19468            }
19469        }
19470        if (check != null) {
19471            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19472                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19473                if (!isDebuggable) {
19474                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19475                        isDebuggable = true;
19476                    }
19477                }
19478                if (isDebuggable) {
19479                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19480                    final ProcessRecord myProc = proc;
19481                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19482                    mMemWatchDumpProcName = proc.processName;
19483                    mMemWatchDumpFile = heapdumpFile.toString();
19484                    mMemWatchDumpPid = proc.pid;
19485                    mMemWatchDumpUid = proc.uid;
19486                    BackgroundThread.getHandler().post(new Runnable() {
19487                        @Override
19488                        public void run() {
19489                            revokeUriPermission(ActivityThread.currentActivityThread()
19490                                            .getApplicationThread(),
19491                                    DumpHeapActivity.JAVA_URI,
19492                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19493                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19494                                    UserHandle.myUserId());
19495                            ParcelFileDescriptor fd = null;
19496                            try {
19497                                heapdumpFile.delete();
19498                                fd = ParcelFileDescriptor.open(heapdumpFile,
19499                                        ParcelFileDescriptor.MODE_CREATE |
19500                                                ParcelFileDescriptor.MODE_TRUNCATE |
19501                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19502                                                ParcelFileDescriptor.MODE_APPEND);
19503                                IApplicationThread thread = myProc.thread;
19504                                if (thread != null) {
19505                                    try {
19506                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19507                                                "Requesting dump heap from "
19508                                                + myProc + " to " + heapdumpFile);
19509                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19510                                    } catch (RemoteException e) {
19511                                    }
19512                                }
19513                            } catch (FileNotFoundException e) {
19514                                e.printStackTrace();
19515                            } finally {
19516                                if (fd != null) {
19517                                    try {
19518                                        fd.close();
19519                                    } catch (IOException e) {
19520                                    }
19521                                }
19522                            }
19523                        }
19524                    });
19525                } else {
19526                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19527                            + ", but debugging not enabled");
19528                }
19529            }
19530        }
19531    }
19532
19533    /**
19534     * Schedule PSS collection of a process.
19535     */
19536    void requestPssLocked(ProcessRecord proc, int procState) {
19537        if (mPendingPssProcesses.contains(proc)) {
19538            return;
19539        }
19540        if (mPendingPssProcesses.size() == 0) {
19541            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19542        }
19543        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19544        proc.pssProcState = procState;
19545        mPendingPssProcesses.add(proc);
19546    }
19547
19548    /**
19549     * Schedule PSS collection of all processes.
19550     */
19551    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19552        if (!always) {
19553            if (now < (mLastFullPssTime +
19554                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19555                return;
19556            }
19557        }
19558        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19559        mLastFullPssTime = now;
19560        mFullPssPending = true;
19561        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19562        mPendingPssProcesses.clear();
19563        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19564            ProcessRecord app = mLruProcesses.get(i);
19565            if (app.thread == null
19566                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19567                continue;
19568            }
19569            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19570                app.pssProcState = app.setProcState;
19571                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19572                        mTestPssMode, isSleeping(), now);
19573                mPendingPssProcesses.add(app);
19574            }
19575        }
19576        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19577    }
19578
19579    public void setTestPssMode(boolean enabled) {
19580        synchronized (this) {
19581            mTestPssMode = enabled;
19582            if (enabled) {
19583                // Whenever we enable the mode, we want to take a snapshot all of current
19584                // process mem use.
19585                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19586            }
19587        }
19588    }
19589
19590    /**
19591     * Ask a given process to GC right now.
19592     */
19593    final void performAppGcLocked(ProcessRecord app) {
19594        try {
19595            app.lastRequestedGc = SystemClock.uptimeMillis();
19596            if (app.thread != null) {
19597                if (app.reportLowMemory) {
19598                    app.reportLowMemory = false;
19599                    app.thread.scheduleLowMemory();
19600                } else {
19601                    app.thread.processInBackground();
19602                }
19603            }
19604        } catch (Exception e) {
19605            // whatever.
19606        }
19607    }
19608
19609    /**
19610     * Returns true if things are idle enough to perform GCs.
19611     */
19612    private final boolean canGcNowLocked() {
19613        boolean processingBroadcasts = false;
19614        for (BroadcastQueue q : mBroadcastQueues) {
19615            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19616                processingBroadcasts = true;
19617            }
19618        }
19619        return !processingBroadcasts
19620                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19621    }
19622
19623    /**
19624     * Perform GCs on all processes that are waiting for it, but only
19625     * if things are idle.
19626     */
19627    final void performAppGcsLocked() {
19628        final int N = mProcessesToGc.size();
19629        if (N <= 0) {
19630            return;
19631        }
19632        if (canGcNowLocked()) {
19633            while (mProcessesToGc.size() > 0) {
19634                ProcessRecord proc = mProcessesToGc.remove(0);
19635                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19636                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19637                            <= SystemClock.uptimeMillis()) {
19638                        // To avoid spamming the system, we will GC processes one
19639                        // at a time, waiting a few seconds between each.
19640                        performAppGcLocked(proc);
19641                        scheduleAppGcsLocked();
19642                        return;
19643                    } else {
19644                        // It hasn't been long enough since we last GCed this
19645                        // process...  put it in the list to wait for its time.
19646                        addProcessToGcListLocked(proc);
19647                        break;
19648                    }
19649                }
19650            }
19651
19652            scheduleAppGcsLocked();
19653        }
19654    }
19655
19656    /**
19657     * If all looks good, perform GCs on all processes waiting for them.
19658     */
19659    final void performAppGcsIfAppropriateLocked() {
19660        if (canGcNowLocked()) {
19661            performAppGcsLocked();
19662            return;
19663        }
19664        // Still not idle, wait some more.
19665        scheduleAppGcsLocked();
19666    }
19667
19668    /**
19669     * Schedule the execution of all pending app GCs.
19670     */
19671    final void scheduleAppGcsLocked() {
19672        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19673
19674        if (mProcessesToGc.size() > 0) {
19675            // Schedule a GC for the time to the next process.
19676            ProcessRecord proc = mProcessesToGc.get(0);
19677            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19678
19679            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19680            long now = SystemClock.uptimeMillis();
19681            if (when < (now+GC_TIMEOUT)) {
19682                when = now + GC_TIMEOUT;
19683            }
19684            mHandler.sendMessageAtTime(msg, when);
19685        }
19686    }
19687
19688    /**
19689     * Add a process to the array of processes waiting to be GCed.  Keeps the
19690     * list in sorted order by the last GC time.  The process can't already be
19691     * on the list.
19692     */
19693    final void addProcessToGcListLocked(ProcessRecord proc) {
19694        boolean added = false;
19695        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19696            if (mProcessesToGc.get(i).lastRequestedGc <
19697                    proc.lastRequestedGc) {
19698                added = true;
19699                mProcessesToGc.add(i+1, proc);
19700                break;
19701            }
19702        }
19703        if (!added) {
19704            mProcessesToGc.add(0, proc);
19705        }
19706    }
19707
19708    /**
19709     * Set up to ask a process to GC itself.  This will either do it
19710     * immediately, or put it on the list of processes to gc the next
19711     * time things are idle.
19712     */
19713    final void scheduleAppGcLocked(ProcessRecord app) {
19714        long now = SystemClock.uptimeMillis();
19715        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19716            return;
19717        }
19718        if (!mProcessesToGc.contains(app)) {
19719            addProcessToGcListLocked(app);
19720            scheduleAppGcsLocked();
19721        }
19722    }
19723
19724    final void checkExcessivePowerUsageLocked(boolean doKills) {
19725        updateCpuStatsNow();
19726
19727        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19728        boolean doWakeKills = doKills;
19729        boolean doCpuKills = doKills;
19730        if (mLastPowerCheckRealtime == 0) {
19731            doWakeKills = false;
19732        }
19733        if (mLastPowerCheckUptime == 0) {
19734            doCpuKills = false;
19735        }
19736        if (stats.isScreenOn()) {
19737            doWakeKills = false;
19738        }
19739        final long curRealtime = SystemClock.elapsedRealtime();
19740        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19741        final long curUptime = SystemClock.uptimeMillis();
19742        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19743        mLastPowerCheckRealtime = curRealtime;
19744        mLastPowerCheckUptime = curUptime;
19745        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19746            doWakeKills = false;
19747        }
19748        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19749            doCpuKills = false;
19750        }
19751        int i = mLruProcesses.size();
19752        while (i > 0) {
19753            i--;
19754            ProcessRecord app = mLruProcesses.get(i);
19755            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19756                long wtime;
19757                synchronized (stats) {
19758                    wtime = stats.getProcessWakeTime(app.info.uid,
19759                            app.pid, curRealtime);
19760                }
19761                long wtimeUsed = wtime - app.lastWakeTime;
19762                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19763                if (DEBUG_POWER) {
19764                    StringBuilder sb = new StringBuilder(128);
19765                    sb.append("Wake for ");
19766                    app.toShortString(sb);
19767                    sb.append(": over ");
19768                    TimeUtils.formatDuration(realtimeSince, sb);
19769                    sb.append(" used ");
19770                    TimeUtils.formatDuration(wtimeUsed, sb);
19771                    sb.append(" (");
19772                    sb.append((wtimeUsed*100)/realtimeSince);
19773                    sb.append("%)");
19774                    Slog.i(TAG_POWER, sb.toString());
19775                    sb.setLength(0);
19776                    sb.append("CPU for ");
19777                    app.toShortString(sb);
19778                    sb.append(": over ");
19779                    TimeUtils.formatDuration(uptimeSince, sb);
19780                    sb.append(" used ");
19781                    TimeUtils.formatDuration(cputimeUsed, sb);
19782                    sb.append(" (");
19783                    sb.append((cputimeUsed*100)/uptimeSince);
19784                    sb.append("%)");
19785                    Slog.i(TAG_POWER, sb.toString());
19786                }
19787                // If a process has held a wake lock for more
19788                // than 50% of the time during this period,
19789                // that sounds bad.  Kill!
19790                if (doWakeKills && realtimeSince > 0
19791                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19792                    synchronized (stats) {
19793                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19794                                realtimeSince, wtimeUsed);
19795                    }
19796                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19797                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19798                } else if (doCpuKills && uptimeSince > 0
19799                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19800                    synchronized (stats) {
19801                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19802                                uptimeSince, cputimeUsed);
19803                    }
19804                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19805                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19806                } else {
19807                    app.lastWakeTime = wtime;
19808                    app.lastCpuTime = app.curCpuTime;
19809                }
19810            }
19811        }
19812    }
19813
19814    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19815            long nowElapsed) {
19816        boolean success = true;
19817
19818        if (app.curRawAdj != app.setRawAdj) {
19819            app.setRawAdj = app.curRawAdj;
19820        }
19821
19822        int changes = 0;
19823
19824        if (app.curAdj != app.setAdj) {
19825            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19826            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19827                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19828                    + app.adjType);
19829            app.setAdj = app.curAdj;
19830        }
19831
19832        if (app.setSchedGroup != app.curSchedGroup) {
19833            app.setSchedGroup = app.curSchedGroup;
19834            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19835                    "Setting sched group of " + app.processName
19836                    + " to " + app.curSchedGroup);
19837            if (app.waitingToKill != null && app.curReceiver == null
19838                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19839                app.kill(app.waitingToKill, true);
19840                success = false;
19841            } else {
19842                int processGroup;
19843                switch (app.curSchedGroup) {
19844                    case ProcessList.SCHED_GROUP_BACKGROUND:
19845                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19846                        break;
19847                    case ProcessList.SCHED_GROUP_TOP_APP:
19848                        processGroup = Process.THREAD_GROUP_TOP_APP;
19849                        break;
19850                    default:
19851                        processGroup = Process.THREAD_GROUP_DEFAULT;
19852                        break;
19853                }
19854                if (true) {
19855                    long oldId = Binder.clearCallingIdentity();
19856                    try {
19857                        Process.setProcessGroup(app.pid, processGroup);
19858                    } catch (Exception e) {
19859                        Slog.w(TAG, "Failed setting process group of " + app.pid
19860                                + " to " + app.curSchedGroup);
19861                        e.printStackTrace();
19862                    } finally {
19863                        Binder.restoreCallingIdentity(oldId);
19864                    }
19865                } else {
19866                    if (app.thread != null) {
19867                        try {
19868                            app.thread.setSchedulingGroup(processGroup);
19869                        } catch (RemoteException e) {
19870                        }
19871                    }
19872                }
19873            }
19874        }
19875        if (app.repForegroundActivities != app.foregroundActivities) {
19876            app.repForegroundActivities = app.foregroundActivities;
19877            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19878        }
19879        if (app.repProcState != app.curProcState) {
19880            app.repProcState = app.curProcState;
19881            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19882            if (app.thread != null) {
19883                try {
19884                    if (false) {
19885                        //RuntimeException h = new RuntimeException("here");
19886                        Slog.i(TAG, "Sending new process state " + app.repProcState
19887                                + " to " + app /*, h*/);
19888                    }
19889                    app.thread.setProcessState(app.repProcState);
19890                } catch (RemoteException e) {
19891                }
19892            }
19893        }
19894        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19895                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19896            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19897                // Experimental code to more aggressively collect pss while
19898                // running test...  the problem is that this tends to collect
19899                // the data right when a process is transitioning between process
19900                // states, which well tend to give noisy data.
19901                long start = SystemClock.uptimeMillis();
19902                long pss = Debug.getPss(app.pid, mTmpLong, null);
19903                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19904                mPendingPssProcesses.remove(app);
19905                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19906                        + " to " + app.curProcState + ": "
19907                        + (SystemClock.uptimeMillis()-start) + "ms");
19908            }
19909            app.lastStateTime = now;
19910            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19911                    mTestPssMode, isSleeping(), now);
19912            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19913                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19914                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19915                    + (app.nextPssTime-now) + ": " + app);
19916        } else {
19917            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19918                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19919                    mTestPssMode)))) {
19920                requestPssLocked(app, app.setProcState);
19921                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19922                        mTestPssMode, isSleeping(), now);
19923            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19924                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19925        }
19926        if (app.setProcState != app.curProcState) {
19927            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19928                    "Proc state change of " + app.processName
19929                            + " to " + app.curProcState);
19930            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19931            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19932            if (setImportant && !curImportant) {
19933                // This app is no longer something we consider important enough to allow to
19934                // use arbitrary amounts of battery power.  Note
19935                // its current wake lock time to later know to kill it if
19936                // it is not behaving well.
19937                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19938                synchronized (stats) {
19939                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19940                            app.pid, nowElapsed);
19941                }
19942                app.lastCpuTime = app.curCpuTime;
19943
19944            }
19945            // Inform UsageStats of important process state change
19946            // Must be called before updating setProcState
19947            maybeUpdateUsageStatsLocked(app, nowElapsed);
19948
19949            app.setProcState = app.curProcState;
19950            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19951                app.notCachedSinceIdle = false;
19952            }
19953            if (!doingAll) {
19954                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19955            } else {
19956                app.procStateChanged = true;
19957            }
19958        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19959                > USAGE_STATS_INTERACTION_INTERVAL) {
19960            // For apps that sit around for a long time in the interactive state, we need
19961            // to report this at least once a day so they don't go idle.
19962            maybeUpdateUsageStatsLocked(app, nowElapsed);
19963        }
19964
19965        if (changes != 0) {
19966            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19967                    "Changes in " + app + ": " + changes);
19968            int i = mPendingProcessChanges.size()-1;
19969            ProcessChangeItem item = null;
19970            while (i >= 0) {
19971                item = mPendingProcessChanges.get(i);
19972                if (item.pid == app.pid) {
19973                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19974                            "Re-using existing item: " + item);
19975                    break;
19976                }
19977                i--;
19978            }
19979            if (i < 0) {
19980                // No existing item in pending changes; need a new one.
19981                final int NA = mAvailProcessChanges.size();
19982                if (NA > 0) {
19983                    item = mAvailProcessChanges.remove(NA-1);
19984                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19985                            "Retrieving available item: " + item);
19986                } else {
19987                    item = new ProcessChangeItem();
19988                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19989                            "Allocating new item: " + item);
19990                }
19991                item.changes = 0;
19992                item.pid = app.pid;
19993                item.uid = app.info.uid;
19994                if (mPendingProcessChanges.size() == 0) {
19995                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19996                            "*** Enqueueing dispatch processes changed!");
19997                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19998                }
19999                mPendingProcessChanges.add(item);
20000            }
20001            item.changes |= changes;
20002            item.processState = app.repProcState;
20003            item.foregroundActivities = app.repForegroundActivities;
20004            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20005                    "Item " + Integer.toHexString(System.identityHashCode(item))
20006                    + " " + app.toShortString() + ": changes=" + item.changes
20007                    + " procState=" + item.processState
20008                    + " foreground=" + item.foregroundActivities
20009                    + " type=" + app.adjType + " source=" + app.adjSource
20010                    + " target=" + app.adjTarget);
20011        }
20012
20013        return success;
20014    }
20015
20016    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20017        final UidRecord.ChangeItem pendingChange;
20018        if (uidRec == null || uidRec.pendingChange == null) {
20019            if (mPendingUidChanges.size() == 0) {
20020                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20021                        "*** Enqueueing dispatch uid changed!");
20022                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20023            }
20024            final int NA = mAvailUidChanges.size();
20025            if (NA > 0) {
20026                pendingChange = mAvailUidChanges.remove(NA-1);
20027                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20028                        "Retrieving available item: " + pendingChange);
20029            } else {
20030                pendingChange = new UidRecord.ChangeItem();
20031                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20032                        "Allocating new item: " + pendingChange);
20033            }
20034            if (uidRec != null) {
20035                uidRec.pendingChange = pendingChange;
20036                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20037                    // If this uid is going away, and we haven't yet reported it is gone,
20038                    // then do so now.
20039                    change = UidRecord.CHANGE_GONE_IDLE;
20040                }
20041            } else if (uid < 0) {
20042                throw new IllegalArgumentException("No UidRecord or uid");
20043            }
20044            pendingChange.uidRecord = uidRec;
20045            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20046            mPendingUidChanges.add(pendingChange);
20047        } else {
20048            pendingChange = uidRec.pendingChange;
20049            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20050                change = UidRecord.CHANGE_GONE_IDLE;
20051            }
20052        }
20053        pendingChange.change = change;
20054        pendingChange.processState = uidRec != null
20055                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20056    }
20057
20058    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20059            String authority) {
20060        if (app == null) return;
20061        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20062            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20063            if (userState == null) return;
20064            final long now = SystemClock.elapsedRealtime();
20065            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20066            if (lastReported == null || lastReported < now - 60 * 1000L) {
20067                mUsageStatsService.reportContentProviderUsage(
20068                        authority, providerPkgName, app.userId);
20069                userState.mProviderLastReportedFg.put(authority, now);
20070            }
20071        }
20072    }
20073
20074    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20075        if (DEBUG_USAGE_STATS) {
20076            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20077                    + "] state changes: old = " + app.setProcState + ", new = "
20078                    + app.curProcState);
20079        }
20080        if (mUsageStatsService == null) {
20081            return;
20082        }
20083        boolean isInteraction;
20084        // To avoid some abuse patterns, we are going to be careful about what we consider
20085        // to be an app interaction.  Being the top activity doesn't count while the display
20086        // is sleeping, nor do short foreground services.
20087        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20088            isInteraction = true;
20089            app.fgInteractionTime = 0;
20090        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20091            if (app.fgInteractionTime == 0) {
20092                app.fgInteractionTime = nowElapsed;
20093                isInteraction = false;
20094            } else {
20095                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20096            }
20097        } else {
20098            isInteraction = app.curProcState
20099                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20100            app.fgInteractionTime = 0;
20101        }
20102        if (isInteraction && (!app.reportedInteraction
20103                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20104            app.interactionEventTime = nowElapsed;
20105            String[] packages = app.getPackageList();
20106            if (packages != null) {
20107                for (int i = 0; i < packages.length; i++) {
20108                    mUsageStatsService.reportEvent(packages[i], app.userId,
20109                            UsageEvents.Event.SYSTEM_INTERACTION);
20110                }
20111            }
20112        }
20113        app.reportedInteraction = isInteraction;
20114        if (!isInteraction) {
20115            app.interactionEventTime = 0;
20116        }
20117    }
20118
20119    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20120        if (proc.thread != null) {
20121            if (proc.baseProcessTracker != null) {
20122                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20123            }
20124        }
20125    }
20126
20127    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20128            ProcessRecord TOP_APP, boolean doingAll, long now) {
20129        if (app.thread == null) {
20130            return false;
20131        }
20132
20133        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20134
20135        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20136    }
20137
20138    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20139            boolean oomAdj) {
20140        if (isForeground != proc.foregroundServices) {
20141            proc.foregroundServices = isForeground;
20142            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20143                    proc.info.uid);
20144            if (isForeground) {
20145                if (curProcs == null) {
20146                    curProcs = new ArrayList<ProcessRecord>();
20147                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20148                }
20149                if (!curProcs.contains(proc)) {
20150                    curProcs.add(proc);
20151                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20152                            proc.info.packageName, proc.info.uid);
20153                }
20154            } else {
20155                if (curProcs != null) {
20156                    if (curProcs.remove(proc)) {
20157                        mBatteryStatsService.noteEvent(
20158                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20159                                proc.info.packageName, proc.info.uid);
20160                        if (curProcs.size() <= 0) {
20161                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20162                        }
20163                    }
20164                }
20165            }
20166            if (oomAdj) {
20167                updateOomAdjLocked();
20168            }
20169        }
20170    }
20171
20172    private final ActivityRecord resumedAppLocked() {
20173        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20174        String pkg;
20175        int uid;
20176        if (act != null) {
20177            pkg = act.packageName;
20178            uid = act.info.applicationInfo.uid;
20179        } else {
20180            pkg = null;
20181            uid = -1;
20182        }
20183        // Has the UID or resumed package name changed?
20184        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20185                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20186            if (mCurResumedPackage != null) {
20187                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20188                        mCurResumedPackage, mCurResumedUid);
20189            }
20190            mCurResumedPackage = pkg;
20191            mCurResumedUid = uid;
20192            if (mCurResumedPackage != null) {
20193                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20194                        mCurResumedPackage, mCurResumedUid);
20195            }
20196        }
20197        return act;
20198    }
20199
20200    final boolean updateOomAdjLocked(ProcessRecord app) {
20201        final ActivityRecord TOP_ACT = resumedAppLocked();
20202        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20203        final boolean wasCached = app.cached;
20204
20205        mAdjSeq++;
20206
20207        // This is the desired cached adjusment we want to tell it to use.
20208        // If our app is currently cached, we know it, and that is it.  Otherwise,
20209        // we don't know it yet, and it needs to now be cached we will then
20210        // need to do a complete oom adj.
20211        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20212                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20213        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20214                SystemClock.uptimeMillis());
20215        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20216            // Changed to/from cached state, so apps after it in the LRU
20217            // list may also be changed.
20218            updateOomAdjLocked();
20219        }
20220        return success;
20221    }
20222
20223    final void updateOomAdjLocked() {
20224        final ActivityRecord TOP_ACT = resumedAppLocked();
20225        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20226        final long now = SystemClock.uptimeMillis();
20227        final long nowElapsed = SystemClock.elapsedRealtime();
20228        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20229        final int N = mLruProcesses.size();
20230
20231        if (false) {
20232            RuntimeException e = new RuntimeException();
20233            e.fillInStackTrace();
20234            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20235        }
20236
20237        // Reset state in all uid records.
20238        for (int i=mActiveUids.size()-1; i>=0; i--) {
20239            final UidRecord uidRec = mActiveUids.valueAt(i);
20240            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20241                    "Starting update of " + uidRec);
20242            uidRec.reset();
20243        }
20244
20245        mStackSupervisor.rankTaskLayersIfNeeded();
20246
20247        mAdjSeq++;
20248        mNewNumServiceProcs = 0;
20249        mNewNumAServiceProcs = 0;
20250
20251        final int emptyProcessLimit;
20252        final int cachedProcessLimit;
20253        if (mProcessLimit <= 0) {
20254            emptyProcessLimit = cachedProcessLimit = 0;
20255        } else if (mProcessLimit == 1) {
20256            emptyProcessLimit = 1;
20257            cachedProcessLimit = 0;
20258        } else {
20259            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20260            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20261        }
20262
20263        // Let's determine how many processes we have running vs.
20264        // how many slots we have for background processes; we may want
20265        // to put multiple processes in a slot of there are enough of
20266        // them.
20267        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20268                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20269        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20270        if (numEmptyProcs > cachedProcessLimit) {
20271            // If there are more empty processes than our limit on cached
20272            // processes, then use the cached process limit for the factor.
20273            // This ensures that the really old empty processes get pushed
20274            // down to the bottom, so if we are running low on memory we will
20275            // have a better chance at keeping around more cached processes
20276            // instead of a gazillion empty processes.
20277            numEmptyProcs = cachedProcessLimit;
20278        }
20279        int emptyFactor = numEmptyProcs/numSlots;
20280        if (emptyFactor < 1) emptyFactor = 1;
20281        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20282        if (cachedFactor < 1) cachedFactor = 1;
20283        int stepCached = 0;
20284        int stepEmpty = 0;
20285        int numCached = 0;
20286        int numEmpty = 0;
20287        int numTrimming = 0;
20288
20289        mNumNonCachedProcs = 0;
20290        mNumCachedHiddenProcs = 0;
20291
20292        // First update the OOM adjustment for each of the
20293        // application processes based on their current state.
20294        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20295        int nextCachedAdj = curCachedAdj+1;
20296        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20297        int nextEmptyAdj = curEmptyAdj+2;
20298        for (int i=N-1; i>=0; i--) {
20299            ProcessRecord app = mLruProcesses.get(i);
20300            if (!app.killedByAm && app.thread != null) {
20301                app.procStateChanged = false;
20302                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20303
20304                // If we haven't yet assigned the final cached adj
20305                // to the process, do that now.
20306                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20307                    switch (app.curProcState) {
20308                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20309                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20310                            // This process is a cached process holding activities...
20311                            // assign it the next cached value for that type, and then
20312                            // step that cached level.
20313                            app.curRawAdj = curCachedAdj;
20314                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20315                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20316                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20317                                    + ")");
20318                            if (curCachedAdj != nextCachedAdj) {
20319                                stepCached++;
20320                                if (stepCached >= cachedFactor) {
20321                                    stepCached = 0;
20322                                    curCachedAdj = nextCachedAdj;
20323                                    nextCachedAdj += 2;
20324                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20325                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20326                                    }
20327                                }
20328                            }
20329                            break;
20330                        default:
20331                            // For everything else, assign next empty cached process
20332                            // level and bump that up.  Note that this means that
20333                            // long-running services that have dropped down to the
20334                            // cached level will be treated as empty (since their process
20335                            // state is still as a service), which is what we want.
20336                            app.curRawAdj = curEmptyAdj;
20337                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20338                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20339                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20340                                    + ")");
20341                            if (curEmptyAdj != nextEmptyAdj) {
20342                                stepEmpty++;
20343                                if (stepEmpty >= emptyFactor) {
20344                                    stepEmpty = 0;
20345                                    curEmptyAdj = nextEmptyAdj;
20346                                    nextEmptyAdj += 2;
20347                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20348                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20349                                    }
20350                                }
20351                            }
20352                            break;
20353                    }
20354                }
20355
20356                applyOomAdjLocked(app, true, now, nowElapsed);
20357
20358                // Count the number of process types.
20359                switch (app.curProcState) {
20360                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20361                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20362                        mNumCachedHiddenProcs++;
20363                        numCached++;
20364                        if (numCached > cachedProcessLimit) {
20365                            app.kill("cached #" + numCached, true);
20366                        }
20367                        break;
20368                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20369                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20370                                && app.lastActivityTime < oldTime) {
20371                            app.kill("empty for "
20372                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20373                                    / 1000) + "s", true);
20374                        } else {
20375                            numEmpty++;
20376                            if (numEmpty > emptyProcessLimit) {
20377                                app.kill("empty #" + numEmpty, true);
20378                            }
20379                        }
20380                        break;
20381                    default:
20382                        mNumNonCachedProcs++;
20383                        break;
20384                }
20385
20386                if (app.isolated && app.services.size() <= 0) {
20387                    // If this is an isolated process, and there are no
20388                    // services running in it, then the process is no longer
20389                    // needed.  We agressively kill these because we can by
20390                    // definition not re-use the same process again, and it is
20391                    // good to avoid having whatever code was running in them
20392                    // left sitting around after no longer needed.
20393                    app.kill("isolated not needed", true);
20394                } else {
20395                    // Keeping this process, update its uid.
20396                    final UidRecord uidRec = app.uidRecord;
20397                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20398                        uidRec.curProcState = app.curProcState;
20399                    }
20400                }
20401
20402                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20403                        && !app.killedByAm) {
20404                    numTrimming++;
20405                }
20406            }
20407        }
20408
20409        mNumServiceProcs = mNewNumServiceProcs;
20410
20411        // Now determine the memory trimming level of background processes.
20412        // Unfortunately we need to start at the back of the list to do this
20413        // properly.  We only do this if the number of background apps we
20414        // are managing to keep around is less than half the maximum we desire;
20415        // if we are keeping a good number around, we'll let them use whatever
20416        // memory they want.
20417        final int numCachedAndEmpty = numCached + numEmpty;
20418        int memFactor;
20419        if (numCached <= ProcessList.TRIM_CACHED_APPS
20420                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20421            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20422                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20423            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20424                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20425            } else {
20426                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20427            }
20428        } else {
20429            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20430        }
20431        // We always allow the memory level to go up (better).  We only allow it to go
20432        // down if we are in a state where that is allowed, *and* the total number of processes
20433        // has gone down since last time.
20434        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20435                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20436                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20437        if (memFactor > mLastMemoryLevel) {
20438            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20439                memFactor = mLastMemoryLevel;
20440                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20441            }
20442        }
20443        if (memFactor != mLastMemoryLevel) {
20444            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20445        }
20446        mLastMemoryLevel = memFactor;
20447        mLastNumProcesses = mLruProcesses.size();
20448        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20449        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20450        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20451            if (mLowRamStartTime == 0) {
20452                mLowRamStartTime = now;
20453            }
20454            int step = 0;
20455            int fgTrimLevel;
20456            switch (memFactor) {
20457                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20458                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20459                    break;
20460                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20461                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20462                    break;
20463                default:
20464                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20465                    break;
20466            }
20467            int factor = numTrimming/3;
20468            int minFactor = 2;
20469            if (mHomeProcess != null) minFactor++;
20470            if (mPreviousProcess != null) minFactor++;
20471            if (factor < minFactor) factor = minFactor;
20472            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20473            for (int i=N-1; i>=0; i--) {
20474                ProcessRecord app = mLruProcesses.get(i);
20475                if (allChanged || app.procStateChanged) {
20476                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20477                    app.procStateChanged = false;
20478                }
20479                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20480                        && !app.killedByAm) {
20481                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20482                        try {
20483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20484                                    "Trimming memory of " + app.processName + " to " + curLevel);
20485                            app.thread.scheduleTrimMemory(curLevel);
20486                        } catch (RemoteException e) {
20487                        }
20488                        if (false) {
20489                            // For now we won't do this; our memory trimming seems
20490                            // to be good enough at this point that destroying
20491                            // activities causes more harm than good.
20492                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20493                                    && app != mHomeProcess && app != mPreviousProcess) {
20494                                // Need to do this on its own message because the stack may not
20495                                // be in a consistent state at this point.
20496                                // For these apps we will also finish their activities
20497                                // to help them free memory.
20498                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20499                            }
20500                        }
20501                    }
20502                    app.trimMemoryLevel = curLevel;
20503                    step++;
20504                    if (step >= factor) {
20505                        step = 0;
20506                        switch (curLevel) {
20507                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20508                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20509                                break;
20510                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20511                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20512                                break;
20513                        }
20514                    }
20515                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20516                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20517                            && app.thread != null) {
20518                        try {
20519                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20520                                    "Trimming memory of heavy-weight " + app.processName
20521                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20522                            app.thread.scheduleTrimMemory(
20523                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20524                        } catch (RemoteException e) {
20525                        }
20526                    }
20527                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20528                } else {
20529                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20530                            || app.systemNoUi) && app.pendingUiClean) {
20531                        // If this application is now in the background and it
20532                        // had done UI, then give it the special trim level to
20533                        // have it free UI resources.
20534                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20535                        if (app.trimMemoryLevel < level && app.thread != null) {
20536                            try {
20537                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20538                                        "Trimming memory of bg-ui " + app.processName
20539                                        + " to " + level);
20540                                app.thread.scheduleTrimMemory(level);
20541                            } catch (RemoteException e) {
20542                            }
20543                        }
20544                        app.pendingUiClean = false;
20545                    }
20546                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20547                        try {
20548                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20549                                    "Trimming memory of fg " + app.processName
20550                                    + " to " + fgTrimLevel);
20551                            app.thread.scheduleTrimMemory(fgTrimLevel);
20552                        } catch (RemoteException e) {
20553                        }
20554                    }
20555                    app.trimMemoryLevel = fgTrimLevel;
20556                }
20557            }
20558        } else {
20559            if (mLowRamStartTime != 0) {
20560                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20561                mLowRamStartTime = 0;
20562            }
20563            for (int i=N-1; i>=0; i--) {
20564                ProcessRecord app = mLruProcesses.get(i);
20565                if (allChanged || app.procStateChanged) {
20566                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20567                    app.procStateChanged = false;
20568                }
20569                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20570                        || app.systemNoUi) && app.pendingUiClean) {
20571                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20572                            && app.thread != null) {
20573                        try {
20574                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20575                                    "Trimming memory of ui hidden " + app.processName
20576                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20577                            app.thread.scheduleTrimMemory(
20578                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20579                        } catch (RemoteException e) {
20580                        }
20581                    }
20582                    app.pendingUiClean = false;
20583                }
20584                app.trimMemoryLevel = 0;
20585            }
20586        }
20587
20588        if (mAlwaysFinishActivities) {
20589            // Need to do this on its own message because the stack may not
20590            // be in a consistent state at this point.
20591            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20592        }
20593
20594        if (allChanged) {
20595            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20596        }
20597
20598        // Update from any uid changes.
20599        for (int i=mActiveUids.size()-1; i>=0; i--) {
20600            final UidRecord uidRec = mActiveUids.valueAt(i);
20601            int uidChange = UidRecord.CHANGE_PROCSTATE;
20602            if (uidRec.setProcState != uidRec.curProcState) {
20603                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20604                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20605                        + " to " + uidRec.curProcState);
20606                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20607                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20608                        uidRec.lastBackgroundTime = nowElapsed;
20609                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20610                            // Note: the background settle time is in elapsed realtime, while
20611                            // the handler time base is uptime.  All this means is that we may
20612                            // stop background uids later than we had intended, but that only
20613                            // happens because the device was sleeping so we are okay anyway.
20614                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20615                        }
20616                    }
20617                } else {
20618                    if (uidRec.idle) {
20619                        uidChange = UidRecord.CHANGE_ACTIVE;
20620                        uidRec.idle = false;
20621                    }
20622                    uidRec.lastBackgroundTime = 0;
20623                }
20624                uidRec.setProcState = uidRec.curProcState;
20625                enqueueUidChangeLocked(uidRec, -1, uidChange);
20626                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20627            }
20628        }
20629
20630        if (mProcessStats.shouldWriteNowLocked(now)) {
20631            mHandler.post(new Runnable() {
20632                @Override public void run() {
20633                    synchronized (ActivityManagerService.this) {
20634                        mProcessStats.writeStateAsyncLocked();
20635                    }
20636                }
20637            });
20638        }
20639
20640        if (DEBUG_OOM_ADJ) {
20641            final long duration = SystemClock.uptimeMillis() - now;
20642            if (false) {
20643                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20644                        new RuntimeException("here").fillInStackTrace());
20645            } else {
20646                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20647            }
20648        }
20649    }
20650
20651    final void idleUids() {
20652        synchronized (this) {
20653            final long nowElapsed = SystemClock.elapsedRealtime();
20654            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20655            long nextTime = 0;
20656            for (int i=mActiveUids.size()-1; i>=0; i--) {
20657                final UidRecord uidRec = mActiveUids.valueAt(i);
20658                final long bgTime = uidRec.lastBackgroundTime;
20659                if (bgTime > 0 && !uidRec.idle) {
20660                    if (bgTime <= maxBgTime) {
20661                        uidRec.idle = true;
20662                        doStopUidLocked(uidRec.uid, uidRec);
20663                    } else {
20664                        if (nextTime == 0 || nextTime > bgTime) {
20665                            nextTime = bgTime;
20666                        }
20667                    }
20668                }
20669            }
20670            if (nextTime > 0) {
20671                mHandler.removeMessages(IDLE_UIDS_MSG);
20672                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20673                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20674            }
20675        }
20676    }
20677
20678    final void runInBackgroundDisabled(int uid) {
20679        synchronized (this) {
20680            UidRecord uidRec = mActiveUids.get(uid);
20681            if (uidRec != null) {
20682                // This uid is actually running...  should it be considered background now?
20683                if (uidRec.idle) {
20684                    doStopUidLocked(uidRec.uid, uidRec);
20685                }
20686            } else {
20687                // This uid isn't actually running...  still send a report about it being "stopped".
20688                doStopUidLocked(uid, null);
20689            }
20690        }
20691    }
20692
20693    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20694        mServices.stopInBackgroundLocked(uid);
20695        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20696    }
20697
20698    final void trimApplications() {
20699        synchronized (this) {
20700            int i;
20701
20702            // First remove any unused application processes whose package
20703            // has been removed.
20704            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20705                final ProcessRecord app = mRemovedProcesses.get(i);
20706                if (app.activities.size() == 0
20707                        && app.curReceiver == null && app.services.size() == 0) {
20708                    Slog.i(
20709                        TAG, "Exiting empty application process "
20710                        + app.toShortString() + " ("
20711                        + (app.thread != null ? app.thread.asBinder() : null)
20712                        + ")\n");
20713                    if (app.pid > 0 && app.pid != MY_PID) {
20714                        app.kill("empty", false);
20715                    } else {
20716                        try {
20717                            app.thread.scheduleExit();
20718                        } catch (Exception e) {
20719                            // Ignore exceptions.
20720                        }
20721                    }
20722                    cleanUpApplicationRecordLocked(app, false, true, -1);
20723                    mRemovedProcesses.remove(i);
20724
20725                    if (app.persistent) {
20726                        addAppLocked(app.info, false, null /* ABI override */);
20727                    }
20728                }
20729            }
20730
20731            // Now update the oom adj for all processes.
20732            updateOomAdjLocked();
20733        }
20734    }
20735
20736    /** This method sends the specified signal to each of the persistent apps */
20737    public void signalPersistentProcesses(int sig) throws RemoteException {
20738        if (sig != Process.SIGNAL_USR1) {
20739            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20740        }
20741
20742        synchronized (this) {
20743            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20744                    != PackageManager.PERMISSION_GRANTED) {
20745                throw new SecurityException("Requires permission "
20746                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20747            }
20748
20749            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20750                ProcessRecord r = mLruProcesses.get(i);
20751                if (r.thread != null && r.persistent) {
20752                    Process.sendSignal(r.pid, sig);
20753                }
20754            }
20755        }
20756    }
20757
20758    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20759        if (proc == null || proc == mProfileProc) {
20760            proc = mProfileProc;
20761            profileType = mProfileType;
20762            clearProfilerLocked();
20763        }
20764        if (proc == null) {
20765            return;
20766        }
20767        try {
20768            proc.thread.profilerControl(false, null, profileType);
20769        } catch (RemoteException e) {
20770            throw new IllegalStateException("Process disappeared");
20771        }
20772    }
20773
20774    private void clearProfilerLocked() {
20775        if (mProfileFd != null) {
20776            try {
20777                mProfileFd.close();
20778            } catch (IOException e) {
20779            }
20780        }
20781        mProfileApp = null;
20782        mProfileProc = null;
20783        mProfileFile = null;
20784        mProfileType = 0;
20785        mAutoStopProfiler = false;
20786        mSamplingInterval = 0;
20787    }
20788
20789    public boolean profileControl(String process, int userId, boolean start,
20790            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20791
20792        try {
20793            synchronized (this) {
20794                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20795                // its own permission.
20796                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20797                        != PackageManager.PERMISSION_GRANTED) {
20798                    throw new SecurityException("Requires permission "
20799                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20800                }
20801
20802                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20803                    throw new IllegalArgumentException("null profile info or fd");
20804                }
20805
20806                ProcessRecord proc = null;
20807                if (process != null) {
20808                    proc = findProcessLocked(process, userId, "profileControl");
20809                }
20810
20811                if (start && (proc == null || proc.thread == null)) {
20812                    throw new IllegalArgumentException("Unknown process: " + process);
20813                }
20814
20815                if (start) {
20816                    stopProfilerLocked(null, 0);
20817                    setProfileApp(proc.info, proc.processName, profilerInfo);
20818                    mProfileProc = proc;
20819                    mProfileType = profileType;
20820                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20821                    try {
20822                        fd = fd.dup();
20823                    } catch (IOException e) {
20824                        fd = null;
20825                    }
20826                    profilerInfo.profileFd = fd;
20827                    proc.thread.profilerControl(start, profilerInfo, profileType);
20828                    fd = null;
20829                    mProfileFd = null;
20830                } else {
20831                    stopProfilerLocked(proc, profileType);
20832                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20833                        try {
20834                            profilerInfo.profileFd.close();
20835                        } catch (IOException e) {
20836                        }
20837                    }
20838                }
20839
20840                return true;
20841            }
20842        } catch (RemoteException e) {
20843            throw new IllegalStateException("Process disappeared");
20844        } finally {
20845            if (profilerInfo != null && profilerInfo.profileFd != null) {
20846                try {
20847                    profilerInfo.profileFd.close();
20848                } catch (IOException e) {
20849                }
20850            }
20851        }
20852    }
20853
20854    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20855        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20856                userId, true, ALLOW_FULL_ONLY, callName, null);
20857        ProcessRecord proc = null;
20858        try {
20859            int pid = Integer.parseInt(process);
20860            synchronized (mPidsSelfLocked) {
20861                proc = mPidsSelfLocked.get(pid);
20862            }
20863        } catch (NumberFormatException e) {
20864        }
20865
20866        if (proc == null) {
20867            ArrayMap<String, SparseArray<ProcessRecord>> all
20868                    = mProcessNames.getMap();
20869            SparseArray<ProcessRecord> procs = all.get(process);
20870            if (procs != null && procs.size() > 0) {
20871                proc = procs.valueAt(0);
20872                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20873                    for (int i=1; i<procs.size(); i++) {
20874                        ProcessRecord thisProc = procs.valueAt(i);
20875                        if (thisProc.userId == userId) {
20876                            proc = thisProc;
20877                            break;
20878                        }
20879                    }
20880                }
20881            }
20882        }
20883
20884        return proc;
20885    }
20886
20887    public boolean dumpHeap(String process, int userId, boolean managed,
20888            String path, ParcelFileDescriptor fd) throws RemoteException {
20889
20890        try {
20891            synchronized (this) {
20892                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20893                // its own permission (same as profileControl).
20894                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20895                        != PackageManager.PERMISSION_GRANTED) {
20896                    throw new SecurityException("Requires permission "
20897                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20898                }
20899
20900                if (fd == null) {
20901                    throw new IllegalArgumentException("null fd");
20902                }
20903
20904                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20905                if (proc == null || proc.thread == null) {
20906                    throw new IllegalArgumentException("Unknown process: " + process);
20907                }
20908
20909                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20910                if (!isDebuggable) {
20911                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20912                        throw new SecurityException("Process not debuggable: " + proc);
20913                    }
20914                }
20915
20916                proc.thread.dumpHeap(managed, path, fd);
20917                fd = null;
20918                return true;
20919            }
20920        } catch (RemoteException e) {
20921            throw new IllegalStateException("Process disappeared");
20922        } finally {
20923            if (fd != null) {
20924                try {
20925                    fd.close();
20926                } catch (IOException e) {
20927                }
20928            }
20929        }
20930    }
20931
20932    @Override
20933    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20934            String reportPackage) {
20935        if (processName != null) {
20936            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20937                    "setDumpHeapDebugLimit()");
20938        } else {
20939            synchronized (mPidsSelfLocked) {
20940                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20941                if (proc == null) {
20942                    throw new SecurityException("No process found for calling pid "
20943                            + Binder.getCallingPid());
20944                }
20945                if (!Build.IS_DEBUGGABLE
20946                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20947                    throw new SecurityException("Not running a debuggable build");
20948                }
20949                processName = proc.processName;
20950                uid = proc.uid;
20951                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20952                    throw new SecurityException("Package " + reportPackage + " is not running in "
20953                            + proc);
20954                }
20955            }
20956        }
20957        synchronized (this) {
20958            if (maxMemSize > 0) {
20959                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20960            } else {
20961                if (uid != 0) {
20962                    mMemWatchProcesses.remove(processName, uid);
20963                } else {
20964                    mMemWatchProcesses.getMap().remove(processName);
20965                }
20966            }
20967        }
20968    }
20969
20970    @Override
20971    public void dumpHeapFinished(String path) {
20972        synchronized (this) {
20973            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20974                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20975                        + " does not match last pid " + mMemWatchDumpPid);
20976                return;
20977            }
20978            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20979                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20980                        + " does not match last path " + mMemWatchDumpFile);
20981                return;
20982            }
20983            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20984            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20985        }
20986    }
20987
20988    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20989    public void monitor() {
20990        synchronized (this) { }
20991    }
20992
20993    void onCoreSettingsChange(Bundle settings) {
20994        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20995            ProcessRecord processRecord = mLruProcesses.get(i);
20996            try {
20997                if (processRecord.thread != null) {
20998                    processRecord.thread.setCoreSettings(settings);
20999                }
21000            } catch (RemoteException re) {
21001                /* ignore */
21002            }
21003        }
21004    }
21005
21006    // Multi-user methods
21007
21008    /**
21009     * Start user, if its not already running, but don't bring it to foreground.
21010     */
21011    @Override
21012    public boolean startUserInBackground(final int userId) {
21013        return mUserController.startUser(userId, /* foreground */ false);
21014    }
21015
21016    @Override
21017    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21018        return mUserController.unlockUser(userId, token, secret, listener);
21019    }
21020
21021    @Override
21022    public boolean switchUser(final int targetUserId) {
21023        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21024        UserInfo currentUserInfo;
21025        UserInfo targetUserInfo;
21026        synchronized (this) {
21027            int currentUserId = mUserController.getCurrentUserIdLocked();
21028            currentUserInfo = mUserController.getUserInfo(currentUserId);
21029            targetUserInfo = mUserController.getUserInfo(targetUserId);
21030            if (targetUserInfo == null) {
21031                Slog.w(TAG, "No user info for user #" + targetUserId);
21032                return false;
21033            }
21034            if (!targetUserInfo.supportsSwitchTo()) {
21035                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21036                return false;
21037            }
21038            if (targetUserInfo.isManagedProfile()) {
21039                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21040                return false;
21041            }
21042            mUserController.setTargetUserIdLocked(targetUserId);
21043        }
21044        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21045        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21046        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21047        return true;
21048    }
21049
21050    void scheduleStartProfilesLocked() {
21051        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21052            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21053                    DateUtils.SECOND_IN_MILLIS);
21054        }
21055    }
21056
21057    @Override
21058    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21059        return mUserController.stopUser(userId, force, callback);
21060    }
21061
21062    @Override
21063    public UserInfo getCurrentUser() {
21064        return mUserController.getCurrentUser();
21065    }
21066
21067    @Override
21068    public boolean isUserRunning(int userId, int flags) {
21069        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21070                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21071            String msg = "Permission Denial: isUserRunning() from pid="
21072                    + Binder.getCallingPid()
21073                    + ", uid=" + Binder.getCallingUid()
21074                    + " requires " + INTERACT_ACROSS_USERS;
21075            Slog.w(TAG, msg);
21076            throw new SecurityException(msg);
21077        }
21078        synchronized (this) {
21079            return mUserController.isUserRunningLocked(userId, flags);
21080        }
21081    }
21082
21083    @Override
21084    public int[] getRunningUserIds() {
21085        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21086                != PackageManager.PERMISSION_GRANTED) {
21087            String msg = "Permission Denial: isUserRunning() from pid="
21088                    + Binder.getCallingPid()
21089                    + ", uid=" + Binder.getCallingUid()
21090                    + " requires " + INTERACT_ACROSS_USERS;
21091            Slog.w(TAG, msg);
21092            throw new SecurityException(msg);
21093        }
21094        synchronized (this) {
21095            return mUserController.getStartedUserArrayLocked();
21096        }
21097    }
21098
21099    @Override
21100    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21101        mUserController.registerUserSwitchObserver(observer);
21102    }
21103
21104    @Override
21105    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21106        mUserController.unregisterUserSwitchObserver(observer);
21107    }
21108
21109    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21110        if (info == null) return null;
21111        ApplicationInfo newInfo = new ApplicationInfo(info);
21112        newInfo.initForUser(userId);
21113        return newInfo;
21114    }
21115
21116    public boolean isUserStopped(int userId) {
21117        synchronized (this) {
21118            return mUserController.getStartedUserStateLocked(userId) == null;
21119        }
21120    }
21121
21122    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21123        if (aInfo == null
21124                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21125            return aInfo;
21126        }
21127
21128        ActivityInfo info = new ActivityInfo(aInfo);
21129        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21130        return info;
21131    }
21132
21133    private boolean processSanityChecksLocked(ProcessRecord process) {
21134        if (process == null || process.thread == null) {
21135            return false;
21136        }
21137
21138        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21139        if (!isDebuggable) {
21140            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21141                return false;
21142            }
21143        }
21144
21145        return true;
21146    }
21147
21148    public boolean startBinderTracking() throws RemoteException {
21149        synchronized (this) {
21150            mBinderTransactionTrackingEnabled = true;
21151            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21152            // permission (same as profileControl).
21153            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21154                    != PackageManager.PERMISSION_GRANTED) {
21155                throw new SecurityException("Requires permission "
21156                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21157            }
21158
21159            for (int i = 0; i < mLruProcesses.size(); i++) {
21160                ProcessRecord process = mLruProcesses.get(i);
21161                if (!processSanityChecksLocked(process)) {
21162                    continue;
21163                }
21164                try {
21165                    process.thread.startBinderTracking();
21166                } catch (RemoteException e) {
21167                    Log.v(TAG, "Process disappared");
21168                }
21169            }
21170            return true;
21171        }
21172    }
21173
21174    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21175        try {
21176            synchronized (this) {
21177                mBinderTransactionTrackingEnabled = false;
21178                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21179                // permission (same as profileControl).
21180                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21181                        != PackageManager.PERMISSION_GRANTED) {
21182                    throw new SecurityException("Requires permission "
21183                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21184                }
21185
21186                if (fd == null) {
21187                    throw new IllegalArgumentException("null fd");
21188                }
21189
21190                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21191                pw.println("Binder transaction traces for all processes.\n");
21192                for (ProcessRecord process : mLruProcesses) {
21193                    if (!processSanityChecksLocked(process)) {
21194                        continue;
21195                    }
21196
21197                    pw.println("Traces for process: " + process.processName);
21198                    pw.flush();
21199                    try {
21200                        TransferPipe tp = new TransferPipe();
21201                        try {
21202                            process.thread.stopBinderTrackingAndDump(
21203                                    tp.getWriteFd().getFileDescriptor());
21204                            tp.go(fd.getFileDescriptor());
21205                        } finally {
21206                            tp.kill();
21207                        }
21208                    } catch (IOException e) {
21209                        pw.println("Failure while dumping IPC traces from " + process +
21210                                ".  Exception: " + e);
21211                        pw.flush();
21212                    } catch (RemoteException e) {
21213                        pw.println("Got a RemoteException while dumping IPC traces from " +
21214                                process + ".  Exception: " + e);
21215                        pw.flush();
21216                    }
21217                }
21218                fd = null;
21219                return true;
21220            }
21221        } finally {
21222            if (fd != null) {
21223                try {
21224                    fd.close();
21225                } catch (IOException e) {
21226                }
21227            }
21228        }
21229    }
21230
21231    private final class LocalService extends ActivityManagerInternal {
21232        @Override
21233        public void onWakefulnessChanged(int wakefulness) {
21234            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21235        }
21236
21237        @Override
21238        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21239                String processName, String abiOverride, int uid, Runnable crashHandler) {
21240            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21241                    processName, abiOverride, uid, crashHandler);
21242        }
21243
21244        @Override
21245        public SleepToken acquireSleepToken(String tag) {
21246            Preconditions.checkNotNull(tag);
21247
21248            synchronized (ActivityManagerService.this) {
21249                SleepTokenImpl token = new SleepTokenImpl(tag);
21250                mSleepTokens.add(token);
21251                updateSleepIfNeededLocked();
21252                applyVrModeIfNeededLocked(mFocusedActivity, false);
21253                return token;
21254            }
21255        }
21256
21257        @Override
21258        public ComponentName getHomeActivityForUser(int userId) {
21259            synchronized (ActivityManagerService.this) {
21260                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21261                return homeActivity == null ? null : homeActivity.realActivity;
21262            }
21263        }
21264
21265        @Override
21266        public void onUserRemoved(int userId) {
21267            synchronized (ActivityManagerService.this) {
21268                ActivityManagerService.this.onUserStoppedLocked(userId);
21269            }
21270        }
21271
21272        @Override
21273        public void onLocalVoiceInteractionStarted(IBinder activity,
21274                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21275            synchronized (ActivityManagerService.this) {
21276                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21277                        voiceSession, voiceInteractor);
21278            }
21279        }
21280
21281        @Override
21282        public void notifyStartingWindowDrawn() {
21283            synchronized (ActivityManagerService.this) {
21284                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21285            }
21286        }
21287
21288        @Override
21289        public void notifyAppTransitionStarting(int reason) {
21290            synchronized (ActivityManagerService.this) {
21291                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21292            }
21293        }
21294
21295        @Override
21296        public void notifyAppTransitionFinished() {
21297            synchronized (ActivityManagerService.this) {
21298                mStackSupervisor.notifyAppTransitionDone();
21299            }
21300        }
21301
21302        @Override
21303        public void notifyAppTransitionCancelled() {
21304            synchronized (ActivityManagerService.this) {
21305                mStackSupervisor.notifyAppTransitionDone();
21306            }
21307        }
21308
21309        @Override
21310        public List<IBinder> getTopVisibleActivities() {
21311            synchronized (ActivityManagerService.this) {
21312                return mStackSupervisor.getTopVisibleActivities();
21313            }
21314        }
21315
21316        @Override
21317        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21318            synchronized (ActivityManagerService.this) {
21319                mStackSupervisor.setDockedStackMinimized(minimized);
21320            }
21321        }
21322
21323        @Override
21324        public void killForegroundAppsForUser(int userHandle) {
21325            synchronized (ActivityManagerService.this) {
21326                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21327                final int NP = mProcessNames.getMap().size();
21328                for (int ip = 0; ip < NP; ip++) {
21329                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21330                    final int NA = apps.size();
21331                    for (int ia = 0; ia < NA; ia++) {
21332                        final ProcessRecord app = apps.valueAt(ia);
21333                        if (app.persistent) {
21334                            // We don't kill persistent processes.
21335                            continue;
21336                        }
21337                        if (app.removed) {
21338                            procs.add(app);
21339                        } else if (app.userId == userHandle && app.foregroundActivities) {
21340                            app.removed = true;
21341                            procs.add(app);
21342                        }
21343                    }
21344                }
21345
21346                final int N = procs.size();
21347                for (int i = 0; i < N; i++) {
21348                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21349                }
21350            }
21351        }
21352
21353        @Override
21354        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21355            if (!(target instanceof PendingIntentRecord)) {
21356                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21357                return;
21358            }
21359            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21360        }
21361    }
21362
21363    private final class SleepTokenImpl extends SleepToken {
21364        private final String mTag;
21365        private final long mAcquireTime;
21366
21367        public SleepTokenImpl(String tag) {
21368            mTag = tag;
21369            mAcquireTime = SystemClock.uptimeMillis();
21370        }
21371
21372        @Override
21373        public void release() {
21374            synchronized (ActivityManagerService.this) {
21375                if (mSleepTokens.remove(this)) {
21376                    updateSleepIfNeededLocked();
21377                }
21378            }
21379        }
21380
21381        @Override
21382        public String toString() {
21383            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21384        }
21385    }
21386
21387    /**
21388     * An implementation of IAppTask, that allows an app to manage its own tasks via
21389     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21390     * only the process that calls getAppTasks() can call the AppTask methods.
21391     */
21392    class AppTaskImpl extends IAppTask.Stub {
21393        private int mTaskId;
21394        private int mCallingUid;
21395
21396        public AppTaskImpl(int taskId, int callingUid) {
21397            mTaskId = taskId;
21398            mCallingUid = callingUid;
21399        }
21400
21401        private void checkCaller() {
21402            if (mCallingUid != Binder.getCallingUid()) {
21403                throw new SecurityException("Caller " + mCallingUid
21404                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21405            }
21406        }
21407
21408        @Override
21409        public void finishAndRemoveTask() {
21410            checkCaller();
21411
21412            synchronized (ActivityManagerService.this) {
21413                long origId = Binder.clearCallingIdentity();
21414                try {
21415                    // We remove the task from recents to preserve backwards
21416                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21417                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21418                    }
21419                } finally {
21420                    Binder.restoreCallingIdentity(origId);
21421                }
21422            }
21423        }
21424
21425        @Override
21426        public ActivityManager.RecentTaskInfo getTaskInfo() {
21427            checkCaller();
21428
21429            synchronized (ActivityManagerService.this) {
21430                long origId = Binder.clearCallingIdentity();
21431                try {
21432                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21433                    if (tr == null) {
21434                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21435                    }
21436                    return createRecentTaskInfoFromTaskRecord(tr);
21437                } finally {
21438                    Binder.restoreCallingIdentity(origId);
21439                }
21440            }
21441        }
21442
21443        @Override
21444        public void moveToFront() {
21445            checkCaller();
21446            // Will bring task to front if it already has a root activity.
21447            final long origId = Binder.clearCallingIdentity();
21448            try {
21449                synchronized (this) {
21450                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21451                }
21452            } finally {
21453                Binder.restoreCallingIdentity(origId);
21454            }
21455        }
21456
21457        @Override
21458        public int startActivity(IBinder whoThread, String callingPackage,
21459                Intent intent, String resolvedType, Bundle bOptions) {
21460            checkCaller();
21461
21462            int callingUser = UserHandle.getCallingUserId();
21463            TaskRecord tr;
21464            IApplicationThread appThread;
21465            synchronized (ActivityManagerService.this) {
21466                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21467                if (tr == null) {
21468                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21469                }
21470                appThread = ApplicationThreadNative.asInterface(whoThread);
21471                if (appThread == null) {
21472                    throw new IllegalArgumentException("Bad app thread " + appThread);
21473                }
21474            }
21475            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21476                    resolvedType, null, null, null, null, 0, 0, null, null,
21477                    null, bOptions, false, callingUser, null, tr);
21478        }
21479
21480        @Override
21481        public void setExcludeFromRecents(boolean exclude) {
21482            checkCaller();
21483
21484            synchronized (ActivityManagerService.this) {
21485                long origId = Binder.clearCallingIdentity();
21486                try {
21487                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21488                    if (tr == null) {
21489                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21490                    }
21491                    Intent intent = tr.getBaseIntent();
21492                    if (exclude) {
21493                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21494                    } else {
21495                        intent.setFlags(intent.getFlags()
21496                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21497                    }
21498                } finally {
21499                    Binder.restoreCallingIdentity(origId);
21500                }
21501            }
21502        }
21503    }
21504
21505    /**
21506     * Kill processes for the user with id userId and that depend on the package named packageName
21507     */
21508    @Override
21509    public void killPackageDependents(String packageName, int userId) {
21510        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21511        if (packageName == null) {
21512            throw new NullPointerException(
21513                    "Cannot kill the dependents of a package without its name.");
21514        }
21515
21516        long callingId = Binder.clearCallingIdentity();
21517        IPackageManager pm = AppGlobals.getPackageManager();
21518        int pkgUid = -1;
21519        try {
21520            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21521        } catch (RemoteException e) {
21522        }
21523        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21524            throw new IllegalArgumentException(
21525                    "Cannot kill dependents of non-existing package " + packageName);
21526        }
21527        try {
21528            synchronized(this) {
21529                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21530                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21531                        "dep: " + packageName);
21532            }
21533        } finally {
21534            Binder.restoreCallingIdentity(callingId);
21535        }
21536    }
21537}
21538