ActivityManagerService.java revision 1de22da763576cd54b2d3d51bc47ce99cf89f1ab
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.telecom.TelecomManager;
203import android.text.format.DateUtils;
204import android.text.format.Time;
205import android.text.style.SuggestionSpan;
206import android.util.ArrayMap;
207import android.util.ArraySet;
208import android.util.AtomicFile;
209import android.util.DebugUtils;
210import android.util.EventLog;
211import android.util.Log;
212import android.util.Pair;
213import android.util.PrintWriterPrinter;
214import android.util.Slog;
215import android.util.SparseArray;
216import android.util.TimeUtils;
217import android.util.Xml;
218import android.view.Display;
219import android.view.Gravity;
220import android.view.LayoutInflater;
221import android.view.View;
222import android.view.WindowManager;
223
224import java.io.File;
225import java.io.FileDescriptor;
226import java.io.FileInputStream;
227import java.io.FileNotFoundException;
228import java.io.FileOutputStream;
229import java.io.IOException;
230import java.io.InputStreamReader;
231import java.io.PrintWriter;
232import java.io.StringWriter;
233import java.lang.ref.WeakReference;
234import java.nio.charset.StandardCharsets;
235import java.util.ArrayList;
236import java.util.Arrays;
237import java.util.Collections;
238import java.util.Comparator;
239import java.util.HashMap;
240import java.util.HashSet;
241import java.util.Iterator;
242import java.util.List;
243import java.util.Locale;
244import java.util.Map;
245import java.util.Objects;
246import java.util.Set;
247import java.util.concurrent.atomic.AtomicBoolean;
248import java.util.concurrent.atomic.AtomicLong;
249
250import dalvik.system.VMRuntime;
251
252import libcore.io.IoUtils;
253import libcore.util.EmptyArray;
254
255import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
268import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
270import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
271import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
272import static android.content.pm.PackageManager.GET_PROVIDERS;
273import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
274import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
275import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
276import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
277import static android.content.pm.PackageManager.PERMISSION_GRANTED;
278import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
279import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
280import static android.provider.Settings.Global.DEBUG_APP;
281import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
282import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
284import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
285import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
286import static android.provider.Settings.System.FONT_SCALE;
287import static com.android.internal.util.XmlUtils.readBooleanAttribute;
288import static com.android.internal.util.XmlUtils.readIntAttribute;
289import static com.android.internal.util.XmlUtils.readLongAttribute;
290import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
291import static com.android.internal.util.XmlUtils.writeIntAttribute;
292import static com.android.internal.util.XmlUtils.writeLongAttribute;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
350import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
352import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
353import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
354import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
355import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
356import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
357import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
358import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
359import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
360import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
363import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
365import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
368import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
369import static org.xmlpull.v1.XmlPullParser.START_TAG;
370
371public final class ActivityManagerService extends ActivityManagerNative
372        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
373
374    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
375    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
376    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
377    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
378    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
379    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
380    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
381    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
382    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
383    private static final String TAG_LRU = TAG + POSTFIX_LRU;
384    private static final String TAG_MU = TAG + POSTFIX_MU;
385    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
386    private static final String TAG_POWER = TAG + POSTFIX_POWER;
387    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
388    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
389    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
390    private static final String TAG_PSS = TAG + POSTFIX_PSS;
391    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
392    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
393    private static final String TAG_STACK = TAG + POSTFIX_STACK;
394    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
395    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
396    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
397    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
398    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
399
400    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
401    // here so that while the job scheduler can depend on AMS, the other way around
402    // need not be the case.
403    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
404
405    /** Control over CPU and battery monitoring */
406    // write battery stats every 30 minutes.
407    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
408    static final boolean MONITOR_CPU_USAGE = true;
409    // don't sample cpu less than every 5 seconds.
410    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
411    // wait possibly forever for next cpu sample.
412    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
413    static final boolean MONITOR_THREAD_CPU_USAGE = false;
414
415    // The flags that are set for all calls we make to the package manager.
416    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
417
418    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
419
420    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
421
422    // Amount of time after a call to stopAppSwitches() during which we will
423    // prevent further untrusted switches from happening.
424    static final long APP_SWITCH_DELAY_TIME = 5*1000;
425
426    // How long we wait for a launched process to attach to the activity manager
427    // before we decide it's never going to come up for real.
428    static final int PROC_START_TIMEOUT = 10*1000;
429    // How long we wait for an attached process to publish its content providers
430    // before we decide it must be hung.
431    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
432
433    // How long we will retain processes hosting content providers in the "last activity"
434    // state before allowing them to drop down to the regular cached LRU list.  This is
435    // to avoid thrashing of provider processes under low memory situations.
436    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
437
438    // How long we wait for a launched process to attach to the activity manager
439    // before we decide it's never going to come up for real, when the process was
440    // started with a wrapper for instrumentation (such as Valgrind) because it
441    // could take much longer than usual.
442    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
443
444    // How long to wait after going idle before forcing apps to GC.
445    static final int GC_TIMEOUT = 5*1000;
446
447    // The minimum amount of time between successive GC requests for a process.
448    static final int GC_MIN_INTERVAL = 60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process.
451    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
452
453    // The minimum amount of time between successive PSS requests for a process
454    // when the request is due to the memory state being lowered.
455    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
456
457    // The rate at which we check for apps using excessive power -- 15 mins.
458    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
459
460    // The minimum sample duration we will allow before deciding we have
461    // enough data on wake locks to start killing things.
462    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
463
464    // The minimum sample duration we will allow before deciding we have
465    // enough data on CPU usage to start killing things.
466    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467
468    // How long we allow a receiver to run before giving up on it.
469    static final int BROADCAST_FG_TIMEOUT = 10*1000;
470    static final int BROADCAST_BG_TIMEOUT = 60*1000;
471
472    // How long we wait until we timeout on key dispatching.
473    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
474
475    // How long we wait until we timeout on key dispatching during instrumentation.
476    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
477
478    // This is the amount of time an app needs to be running a foreground service before
479    // we will consider it to be doing interaction for usage stats.
480    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
481
482    // Maximum amount of time we will allow to elapse before re-reporting usage stats
483    // interaction with foreground processes.
484    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
485
486    // This is the amount of time we allow an app to settle after it goes into the background,
487    // before we start restricting what it can do.
488    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
489
490    // How long to wait in getAssistContextExtras for the activity and foreground services
491    // to respond with the result.
492    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
493
494    // How long top wait when going through the modern assist (which doesn't need to block
495    // on getting this result before starting to launch its UI).
496    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
497
498    // Maximum number of persisted Uri grants a package is allowed
499    static final int MAX_PERSISTED_URI_GRANTS = 128;
500
501    static final int MY_PID = Process.myPid();
502
503    static final String[] EMPTY_STRING_ARRAY = new String[0];
504
505    // How many bytes to write into the dropbox log before truncating
506    static final int DROPBOX_MAX_SIZE = 256 * 1024;
507
508    // Access modes for handleIncomingUser.
509    static final int ALLOW_NON_FULL = 0;
510    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
511    static final int ALLOW_FULL_ONLY = 2;
512
513    // Delay in notifying task stack change listeners (in millis)
514    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
515
516    // Necessary ApplicationInfo flags to mark an app as persistent
517    private static final int PERSISTENT_MASK =
518            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
519
520    // Intent sent when remote bugreport collection has been completed
521    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
522            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
523
524    // Delay to disable app launch boost
525    static final int APP_BOOST_MESSAGE_DELAY = 3000;
526    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
527    static final int APP_BOOST_TIMEOUT = 2500;
528
529    // Used to indicate that a task is removed it should also be removed from recents.
530    private static final boolean REMOVE_FROM_RECENTS = true;
531    // Used to indicate that an app transition should be animated.
532    static final boolean ANIMATE = true;
533
534    // Determines whether to take full screen screenshots
535    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
536    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
537
538    private static native int nativeMigrateToBoost();
539    private static native int nativeMigrateFromBoost();
540    private boolean mIsBoosted = false;
541    private long mBoostStartTime = 0;
542
543    /** All system services */
544    SystemServiceManager mSystemServiceManager;
545
546    private Installer mInstaller;
547
548    /** Run all ActivityStacks through this */
549    final ActivityStackSupervisor mStackSupervisor;
550
551    final ActivityStarter mActivityStarter;
552
553    /** Task stack change listeners. */
554    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
555            new RemoteCallbackList<ITaskStackListener>();
556
557    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559    public IntentFirewall mIntentFirewall;
560
561    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562    // default actuion automatically.  Important for devices without direct input
563    // devices.
564    private boolean mShowDialogs = true;
565    private boolean mInVrMode = false;
566
567    BroadcastQueue mFgBroadcastQueue;
568    BroadcastQueue mBgBroadcastQueue;
569    // Convenient for easy iteration over the queues. Foreground is first
570    // so that dispatch of foreground broadcasts gets precedence.
571    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
572
573    BroadcastQueue broadcastQueueForIntent(Intent intent) {
574        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576                "Broadcast intent " + intent + " on "
577                + (isFg ? "foreground" : "background") + " queue");
578        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
579    }
580
581    /**
582     * Activity we have told the window manager to have key focus.
583     */
584    ActivityRecord mFocusedActivity = null;
585
586    /**
587     * User id of the last activity mFocusedActivity was set to.
588     */
589    private int mLastFocusedUserId;
590
591    /**
592     * If non-null, we are tracking the time the user spends in the currently focused app.
593     */
594    private AppTimeTracker mCurAppTimeTracker;
595
596    /**
597     * List of intents that were used to start the most recent tasks.
598     */
599    final RecentTasks mRecentTasks;
600
601    /**
602     * For addAppTask: cached of the last activity component that was added.
603     */
604    ComponentName mLastAddedTaskComponent;
605
606    /**
607     * For addAppTask: cached of the last activity uid that was added.
608     */
609    int mLastAddedTaskUid;
610
611    /**
612     * For addAppTask: cached of the last ActivityInfo that was added.
613     */
614    ActivityInfo mLastAddedTaskActivity;
615
616    /**
617     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
618     */
619    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620
621    /**
622     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
623     */
624    String mDeviceOwnerName;
625
626    final UserController mUserController;
627
628    final AppErrors mAppErrors;
629
630    boolean mDoingSetFocusedActivity;
631
632    public boolean canShowErrorDialogs() {
633        return mShowDialogs && !mSleeping && !mShuttingDown;
634    }
635
636    // it's a semaphore; boost when 0->1, reset when 1->0
637    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638        @Override protected Integer initialValue() {
639            return 0;
640        }
641    };
642
643    static void boostPriorityForLockedSection() {
644        if (sIsBoosted.get() == 0) {
645            // boost to prio 118 while holding a global lock
646            Process.setThreadPriority(Process.myTid(), -2);
647            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
648        }
649        int cur = sIsBoosted.get();
650        sIsBoosted.set(cur + 1);
651    }
652
653    static void resetPriorityAfterLockedSection() {
654        sIsBoosted.set(sIsBoosted.get() - 1);
655        if (sIsBoosted.get() == 0) {
656            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
657            Process.setThreadPriority(Process.myTid(), 0);
658        }
659    }
660    public class PendingAssistExtras extends Binder implements Runnable {
661        public final ActivityRecord activity;
662        public final Bundle extras;
663        public final Intent intent;
664        public final String hint;
665        public final IResultReceiver receiver;
666        public final int userHandle;
667        public boolean haveResult = false;
668        public Bundle result = null;
669        public AssistStructure structure = null;
670        public AssistContent content = null;
671        public Bundle receiverExtras;
672
673        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675            activity = _activity;
676            extras = _extras;
677            intent = _intent;
678            hint = _hint;
679            receiver = _receiver;
680            receiverExtras = _receiverExtras;
681            userHandle = _userHandle;
682        }
683        @Override
684        public void run() {
685            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686            synchronized (this) {
687                haveResult = true;
688                notifyAll();
689            }
690            pendingAssistExtrasTimedOut(this);
691        }
692    }
693
694    final ArrayList<PendingAssistExtras> mPendingAssistExtras
695            = new ArrayList<PendingAssistExtras>();
696
697    /**
698     * Process management.
699     */
700    final ProcessList mProcessList = new ProcessList();
701
702    /**
703     * All of the applications we currently have running organized by name.
704     * The keys are strings of the application package name (as
705     * returned by the package manager), and the keys are ApplicationRecord
706     * objects.
707     */
708    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709
710    /**
711     * Tracking long-term execution of processes to look for abuse and other
712     * bad app behavior.
713     */
714    final ProcessStatsService mProcessStats;
715
716    /**
717     * The currently running isolated processes.
718     */
719    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720
721    /**
722     * Counter for assigning isolated process uids, to avoid frequently reusing the
723     * same ones.
724     */
725    int mNextIsolatedProcessUid = 0;
726
727    /**
728     * The currently running heavy-weight process, if any.
729     */
730    ProcessRecord mHeavyWeightProcess = null;
731
732    /**
733     * All of the processes we currently have running organized by pid.
734     * The keys are the pid running the application.
735     *
736     * <p>NOTE: This object is protected by its own lock, NOT the global
737     * activity manager lock!
738     */
739    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740
741    /**
742     * All of the processes that have been forced to be foreground.  The key
743     * is the pid of the caller who requested it (we hold a death
744     * link on it).
745     */
746    abstract class ForegroundToken implements IBinder.DeathRecipient {
747        int pid;
748        IBinder token;
749    }
750    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751
752    /**
753     * List of records for processes that someone had tried to start before the
754     * system was ready.  We don't start them at that point, but ensure they
755     * are started by the time booting is complete.
756     */
757    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758
759    /**
760     * List of persistent applications that are in the process
761     * of being started.
762     */
763    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764
765    /**
766     * Processes that are being forcibly torn down.
767     */
768    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769
770    /**
771     * List of running applications, sorted by recent usage.
772     * The first entry in the list is the least recently used.
773     */
774    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775
776    /**
777     * Where in mLruProcesses that the processes hosting activities start.
778     */
779    int mLruProcessActivityStart = 0;
780
781    /**
782     * Where in mLruProcesses that the processes hosting services start.
783     * This is after (lower index) than mLruProcessesActivityStart.
784     */
785    int mLruProcessServiceStart = 0;
786
787    /**
788     * List of processes that should gc as soon as things are idle.
789     */
790    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791
792    /**
793     * Processes we want to collect PSS data from.
794     */
795    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
796
797    private boolean mBinderTransactionTrackingEnabled = false;
798
799    /**
800     * Last time we requested PSS data of all processes.
801     */
802    long mLastFullPssTime = SystemClock.uptimeMillis();
803
804    /**
805     * If set, the next time we collect PSS data we should do a full collection
806     * with data from native processes and the kernel.
807     */
808    boolean mFullPssPending = false;
809
810    /**
811     * This is the process holding what we currently consider to be
812     * the "home" activity.
813     */
814    ProcessRecord mHomeProcess;
815
816    /**
817     * This is the process holding the activity the user last visited that
818     * is in a different process from the one they are currently in.
819     */
820    ProcessRecord mPreviousProcess;
821
822    /**
823     * The time at which the previous process was last visible.
824     */
825    long mPreviousProcessVisibleTime;
826
827    /**
828     * Track all uids that have actively running processes.
829     */
830    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831
832    /**
833     * This is for verifying the UID report flow.
834     */
835    static final boolean VALIDATE_UID_STATES = true;
836    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837
838    /**
839     * Packages that the user has asked to have run in screen size
840     * compatibility mode instead of filling the screen.
841     */
842    final CompatModePackages mCompatModePackages;
843
844    /**
845     * Set of IntentSenderRecord objects that are currently active.
846     */
847    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849
850    /**
851     * Fingerprints (hashCode()) of stack traces that we've
852     * already logged DropBox entries for.  Guarded by itself.  If
853     * something (rogue user app) forces this over
854     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
855     */
856    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858
859    /**
860     * Strict Mode background batched logging state.
861     *
862     * The string buffer is guarded by itself, and its lock is also
863     * used to determine if another batched write is already
864     * in-flight.
865     */
866    private final StringBuilder mStrictModeBuffer = new StringBuilder();
867
868    /**
869     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
871     */
872    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873
874    /**
875     * Resolver for broadcast intents to registered receivers.
876     * Holds BroadcastFilter (subclass of IntentFilter).
877     */
878    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
880        @Override
881        protected boolean allowFilterResult(
882                BroadcastFilter filter, List<BroadcastFilter> dest) {
883            IBinder target = filter.receiverList.receiver.asBinder();
884            for (int i = dest.size() - 1; i >= 0; i--) {
885                if (dest.get(i).receiverList.receiver.asBinder() == target) {
886                    return false;
887                }
888            }
889            return true;
890        }
891
892        @Override
893        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895                    || userId == filter.owningUserId) {
896                return super.newResult(filter, match, userId);
897            }
898            return null;
899        }
900
901        @Override
902        protected BroadcastFilter[] newArray(int size) {
903            return new BroadcastFilter[size];
904        }
905
906        @Override
907        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908            return packageName.equals(filter.packageName);
909        }
910    };
911
912    /**
913     * State of all active sticky broadcasts per user.  Keys are the action of the
914     * sticky Intent, values are an ArrayList of all broadcasted intents with
915     * that action (which should usually be one).  The SparseArray is keyed
916     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917     * for stickies that are sent to all users.
918     */
919    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
921
922    final ActiveServices mServices;
923
924    final static class Association {
925        final int mSourceUid;
926        final String mSourceProcess;
927        final int mTargetUid;
928        final ComponentName mTargetComponent;
929        final String mTargetProcess;
930
931        int mCount;
932        long mTime;
933
934        int mNesting;
935        long mStartTime;
936
937        // states of the source process when the bind occurred.
938        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939        long mLastStateUptime;
940        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941                - ActivityManager.MIN_PROCESS_STATE+1];
942
943        Association(int sourceUid, String sourceProcess, int targetUid,
944                ComponentName targetComponent, String targetProcess) {
945            mSourceUid = sourceUid;
946            mSourceProcess = sourceProcess;
947            mTargetUid = targetUid;
948            mTargetComponent = targetComponent;
949            mTargetProcess = targetProcess;
950        }
951    }
952
953    /**
954     * When service association tracking is enabled, this is all of the associations we
955     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
956     * -> association data.
957     */
958    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959            mAssociations = new SparseArray<>();
960    boolean mTrackingAssociations;
961
962    /**
963     * Backup/restore process management
964     */
965    String mBackupAppName = null;
966    BackupRecord mBackupTarget = null;
967
968    final ProviderMap mProviderMap;
969
970    /**
971     * List of content providers who have clients waiting for them.  The
972     * application is currently being launched and the provider will be
973     * removed from this list once it is published.
974     */
975    final ArrayList<ContentProviderRecord> mLaunchingProviders
976            = new ArrayList<ContentProviderRecord>();
977
978    /**
979     * File storing persisted {@link #mGrantedUriPermissions}.
980     */
981    private final AtomicFile mGrantFile;
982
983    /** XML constants used in {@link #mGrantFile} */
984    private static final String TAG_URI_GRANTS = "uri-grants";
985    private static final String TAG_URI_GRANT = "uri-grant";
986    private static final String ATTR_USER_HANDLE = "userHandle";
987    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988    private static final String ATTR_TARGET_USER_ID = "targetUserId";
989    private static final String ATTR_SOURCE_PKG = "sourcePkg";
990    private static final String ATTR_TARGET_PKG = "targetPkg";
991    private static final String ATTR_URI = "uri";
992    private static final String ATTR_MODE_FLAGS = "modeFlags";
993    private static final String ATTR_CREATED_TIME = "createdTime";
994    private static final String ATTR_PREFIX = "prefix";
995
996    /**
997     * Global set of specific {@link Uri} permissions that have been granted.
998     * This optimized lookup structure maps from {@link UriPermission#targetUid}
999     * to {@link UriPermission#uri} to {@link UriPermission}.
1000     */
1001    @GuardedBy("this")
1002    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1004
1005    public static class GrantUri {
1006        public final int sourceUserId;
1007        public final Uri uri;
1008        public boolean prefix;
1009
1010        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011            this.sourceUserId = sourceUserId;
1012            this.uri = uri;
1013            this.prefix = prefix;
1014        }
1015
1016        @Override
1017        public int hashCode() {
1018            int hashCode = 1;
1019            hashCode = 31 * hashCode + sourceUserId;
1020            hashCode = 31 * hashCode + uri.hashCode();
1021            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1022            return hashCode;
1023        }
1024
1025        @Override
1026        public boolean equals(Object o) {
1027            if (o instanceof GrantUri) {
1028                GrantUri other = (GrantUri) o;
1029                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030                        && prefix == other.prefix;
1031            }
1032            return false;
1033        }
1034
1035        @Override
1036        public String toString() {
1037            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038            if (prefix) result += " [prefix]";
1039            return result;
1040        }
1041
1042        public String toSafeString() {
1043            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044            if (prefix) result += " [prefix]";
1045            return result;
1046        }
1047
1048        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050                    ContentProvider.getUriWithoutUserId(uri), false);
1051        }
1052    }
1053
1054    CoreSettingsObserver mCoreSettingsObserver;
1055
1056    FontScaleSettingObserver mFontScaleSettingObserver;
1057
1058    private final class FontScaleSettingObserver extends ContentObserver {
1059        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1060
1061        public FontScaleSettingObserver() {
1062            super(mHandler);
1063            ContentResolver resolver = mContext.getContentResolver();
1064            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1065        }
1066
1067        @Override
1068        public void onChange(boolean selfChange, Uri uri) {
1069            if (mFontScaleUri.equals(uri)) {
1070                updateFontScaleIfNeeded();
1071            }
1072        }
1073    }
1074
1075    /**
1076     * Thread-local storage used to carry caller permissions over through
1077     * indirect content-provider access.
1078     */
1079    private class Identity {
1080        public final IBinder token;
1081        public final int pid;
1082        public final int uid;
1083
1084        Identity(IBinder _token, int _pid, int _uid) {
1085            token = _token;
1086            pid = _pid;
1087            uid = _uid;
1088        }
1089    }
1090
1091    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092
1093    /**
1094     * All information we have collected about the runtime performance of
1095     * any user id that can impact battery performance.
1096     */
1097    final BatteryStatsService mBatteryStatsService;
1098
1099    /**
1100     * Information about component usage
1101     */
1102    UsageStatsManagerInternal mUsageStatsService;
1103
1104    /**
1105     * Access to DeviceIdleController service.
1106     */
1107    DeviceIdleController.LocalService mLocalDeviceIdleController;
1108
1109    /**
1110     * Information about and control over application operations
1111     */
1112    final AppOpsService mAppOpsService;
1113
1114    /**
1115     * Current configuration information.  HistoryRecord objects are given
1116     * a reference to this object to indicate which configuration they are
1117     * currently running in, so this object must be kept immutable.
1118     */
1119    Configuration mConfiguration = new Configuration();
1120
1121    /**
1122     * Current sequencing integer of the configuration, for skipping old
1123     * configurations.
1124     */
1125    int mConfigurationSeq = 0;
1126
1127    boolean mSuppressResizeConfigChanges = false;
1128
1129    /**
1130     * Hardware-reported OpenGLES version.
1131     */
1132    final int GL_ES_VERSION;
1133
1134    /**
1135     * List of initialization arguments to pass to all processes when binding applications to them.
1136     * For example, references to the commonly used services.
1137     */
1138    HashMap<String, IBinder> mAppBindArgs;
1139
1140    /**
1141     * Temporary to avoid allocations.  Protected by main lock.
1142     */
1143    final StringBuilder mStringBuilder = new StringBuilder(256);
1144
1145    /**
1146     * Used to control how we initialize the service.
1147     */
1148    ComponentName mTopComponent;
1149    String mTopAction = Intent.ACTION_MAIN;
1150    String mTopData;
1151
1152    volatile boolean mProcessesReady = false;
1153    volatile boolean mSystemReady = false;
1154    volatile boolean mOnBattery = false;
1155    volatile int mFactoryTest;
1156
1157    @GuardedBy("this") boolean mBooting = false;
1158    @GuardedBy("this") boolean mCallFinishBooting = false;
1159    @GuardedBy("this") boolean mBootAnimationComplete = false;
1160    @GuardedBy("this") boolean mLaunchWarningShown = false;
1161    @GuardedBy("this") boolean mCheckedForSetup = false;
1162
1163    Context mContext;
1164
1165    /**
1166     * The time at which we will allow normal application switches again,
1167     * after a call to {@link #stopAppSwitches()}.
1168     */
1169    long mAppSwitchesAllowedTime;
1170
1171    /**
1172     * This is set to true after the first switch after mAppSwitchesAllowedTime
1173     * is set; any switches after that will clear the time.
1174     */
1175    boolean mDidAppSwitch;
1176
1177    /**
1178     * Last time (in realtime) at which we checked for power usage.
1179     */
1180    long mLastPowerCheckRealtime;
1181
1182    /**
1183     * Last time (in uptime) at which we checked for power usage.
1184     */
1185    long mLastPowerCheckUptime;
1186
1187    /**
1188     * Set while we are wanting to sleep, to prevent any
1189     * activities from being started/resumed.
1190     */
1191    private boolean mSleeping = false;
1192
1193    /**
1194     * The process state used for processes that are running the top activities.
1195     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1196     */
1197    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198
1199    /**
1200     * Set while we are running a voice interaction.  This overrides
1201     * sleeping while it is active.
1202     */
1203    private IVoiceInteractionSession mRunningVoice;
1204
1205    /**
1206     * For some direct access we need to power manager.
1207     */
1208    PowerManagerInternal mLocalPowerManager;
1209
1210    /**
1211     * We want to hold a wake lock while running a voice interaction session, since
1212     * this may happen with the screen off and we need to keep the CPU running to
1213     * be able to continue to interact with the user.
1214     */
1215    PowerManager.WakeLock mVoiceWakeLock;
1216
1217    /**
1218     * State of external calls telling us if the device is awake or asleep.
1219     */
1220    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221
1222    /**
1223     * A list of tokens that cause the top activity to be put to sleep.
1224     * They are used by components that may hide and block interaction with underlying
1225     * activities.
1226     */
1227    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1228
1229    static final int LOCK_SCREEN_HIDDEN = 0;
1230    static final int LOCK_SCREEN_LEAVING = 1;
1231    static final int LOCK_SCREEN_SHOWN = 2;
1232    /**
1233     * State of external call telling us if the lock screen is shown.
1234     */
1235    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236
1237    /**
1238     * Set if we are shutting down the system, similar to sleeping.
1239     */
1240    boolean mShuttingDown = false;
1241
1242    /**
1243     * Current sequence id for oom_adj computation traversal.
1244     */
1245    int mAdjSeq = 0;
1246
1247    /**
1248     * Current sequence id for process LRU updating.
1249     */
1250    int mLruSeq = 0;
1251
1252    /**
1253     * Keep track of the non-cached/empty process we last found, to help
1254     * determine how to distribute cached/empty processes next time.
1255     */
1256    int mNumNonCachedProcs = 0;
1257
1258    /**
1259     * Keep track of the number of cached hidden procs, to balance oom adj
1260     * distribution between those and empty procs.
1261     */
1262    int mNumCachedHiddenProcs = 0;
1263
1264    /**
1265     * Keep track of the number of service processes we last found, to
1266     * determine on the next iteration which should be B services.
1267     */
1268    int mNumServiceProcs = 0;
1269    int mNewNumAServiceProcs = 0;
1270    int mNewNumServiceProcs = 0;
1271
1272    /**
1273     * Allow the current computed overall memory level of the system to go down?
1274     * This is set to false when we are killing processes for reasons other than
1275     * memory management, so that the now smaller process list will not be taken as
1276     * an indication that memory is tighter.
1277     */
1278    boolean mAllowLowerMemLevel = false;
1279
1280    /**
1281     * The last computed memory level, for holding when we are in a state that
1282     * processes are going away for other reasons.
1283     */
1284    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285
1286    /**
1287     * The last total number of process we have, to determine if changes actually look
1288     * like a shrinking number of process due to lower RAM.
1289     */
1290    int mLastNumProcesses;
1291
1292    /**
1293     * The uptime of the last time we performed idle maintenance.
1294     */
1295    long mLastIdleTime = SystemClock.uptimeMillis();
1296
1297    /**
1298     * Total time spent with RAM that has been added in the past since the last idle time.
1299     */
1300    long mLowRamTimeSinceLastIdle = 0;
1301
1302    /**
1303     * If RAM is currently low, when that horrible situation started.
1304     */
1305    long mLowRamStartTime = 0;
1306
1307    /**
1308     * For reporting to battery stats the current top application.
1309     */
1310    private String mCurResumedPackage = null;
1311    private int mCurResumedUid = -1;
1312
1313    /**
1314     * For reporting to battery stats the apps currently running foreground
1315     * service.  The ProcessMap is package/uid tuples; each of these contain
1316     * an array of the currently foreground processes.
1317     */
1318    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319            = new ProcessMap<ArrayList<ProcessRecord>>();
1320
1321    /**
1322     * This is set if we had to do a delayed dexopt of an app before launching
1323     * it, to increase the ANR timeouts in that case.
1324     */
1325    boolean mDidDexOpt;
1326
1327    /**
1328     * Set if the systemServer made a call to enterSafeMode.
1329     */
1330    boolean mSafeMode;
1331
1332    /**
1333     * If true, we are running under a test environment so will sample PSS from processes
1334     * much more rapidly to try to collect better data when the tests are rapidly
1335     * running through apps.
1336     */
1337    boolean mTestPssMode = false;
1338
1339    String mDebugApp = null;
1340    boolean mWaitForDebugger = false;
1341    boolean mDebugTransient = false;
1342    String mOrigDebugApp = null;
1343    boolean mOrigWaitForDebugger = false;
1344    boolean mAlwaysFinishActivities = false;
1345    boolean mLenientBackgroundCheck = false;
1346    boolean mForceResizableActivities;
1347    boolean mSupportsMultiWindow;
1348    boolean mSupportsFreeformWindowManagement;
1349    boolean mSupportsPictureInPicture;
1350    boolean mSupportsLeanbackOnly;
1351    Rect mDefaultPinnedStackBounds;
1352    IActivityController mController = null;
1353    boolean mControllerIsAMonkey = false;
1354    String mProfileApp = null;
1355    ProcessRecord mProfileProc = null;
1356    String mProfileFile;
1357    ParcelFileDescriptor mProfileFd;
1358    int mSamplingInterval = 0;
1359    boolean mAutoStopProfiler = false;
1360    int mProfileType = 0;
1361    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362    String mMemWatchDumpProcName;
1363    String mMemWatchDumpFile;
1364    int mMemWatchDumpPid;
1365    int mMemWatchDumpUid;
1366    String mTrackAllocationApp = null;
1367    String mNativeDebuggingApp = null;
1368
1369    final long[] mTmpLong = new long[2];
1370
1371    static final class ProcessChangeItem {
1372        static final int CHANGE_ACTIVITIES = 1<<0;
1373        static final int CHANGE_PROCESS_STATE = 1<<1;
1374        int changes;
1375        int uid;
1376        int pid;
1377        int processState;
1378        boolean foregroundActivities;
1379    }
1380
1381    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1383
1384    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1386
1387    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1389
1390    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1392
1393    /**
1394     * Runtime CPU use collection thread.  This object's lock is used to
1395     * perform synchronization with the thread (notifying it to run).
1396     */
1397    final Thread mProcessCpuThread;
1398
1399    /**
1400     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401     * Must acquire this object's lock when accessing it.
1402     * NOTE: this lock will be held while doing long operations (trawling
1403     * through all processes in /proc), so it should never be acquired by
1404     * any critical paths such as when holding the main activity manager lock.
1405     */
1406    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407            MONITOR_THREAD_CPU_USAGE);
1408    final AtomicLong mLastCpuTime = new AtomicLong(0);
1409    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1410
1411    long mLastWriteTime = 0;
1412
1413    /**
1414     * Used to retain an update lock when the foreground activity is in
1415     * immersive mode.
1416     */
1417    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1418
1419    /**
1420     * Set to true after the system has finished booting.
1421     */
1422    boolean mBooted = false;
1423
1424    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425    int mProcessLimitOverride = -1;
1426
1427    WindowManagerService mWindowManager;
1428    final ActivityThread mSystemThread;
1429
1430    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431        final ProcessRecord mApp;
1432        final int mPid;
1433        final IApplicationThread mAppThread;
1434
1435        AppDeathRecipient(ProcessRecord app, int pid,
1436                IApplicationThread thread) {
1437            if (DEBUG_ALL) Slog.v(
1438                TAG, "New death recipient " + this
1439                + " for thread " + thread.asBinder());
1440            mApp = app;
1441            mPid = pid;
1442            mAppThread = thread;
1443        }
1444
1445        @Override
1446        public void binderDied() {
1447            if (DEBUG_ALL) Slog.v(
1448                TAG, "Death received in " + this
1449                + " for thread " + mAppThread.asBinder());
1450            synchronized(ActivityManagerService.this) {
1451                appDiedLocked(mApp, mPid, mAppThread, true);
1452            }
1453        }
1454    }
1455
1456    static final int SHOW_ERROR_UI_MSG = 1;
1457    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459    static final int UPDATE_CONFIGURATION_MSG = 4;
1460    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462    static final int SERVICE_TIMEOUT_MSG = 12;
1463    static final int UPDATE_TIME_ZONE = 13;
1464    static final int SHOW_UID_ERROR_UI_MSG = 14;
1465    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466    static final int PROC_START_TIMEOUT_MSG = 20;
1467    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468    static final int KILL_APPLICATION_MSG = 22;
1469    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474    static final int CLEAR_DNS_CACHE_MSG = 28;
1475    static final int UPDATE_HTTP_PROXY_MSG = 29;
1476    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479    static final int REPORT_MEM_USAGE_MSG = 33;
1480    static final int REPORT_USER_SWITCH_MSG = 34;
1481    static final int CONTINUE_USER_SWITCH_MSG = 35;
1482    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484    static final int PERSIST_URI_GRANTS_MSG = 38;
1485    static final int REQUEST_ALL_PSS_MSG = 39;
1486    static final int START_PROFILES_MSG = 40;
1487    static final int UPDATE_TIME = 41;
1488    static final int SYSTEM_USER_START_MSG = 42;
1489    static final int SYSTEM_USER_CURRENT_MSG = 43;
1490    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491    static final int FINISH_BOOTING_MSG = 45;
1492    static final int START_USER_SWITCH_UI_MSG = 46;
1493    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494    static final int DISMISS_DIALOG_UI_MSG = 48;
1495    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498    static final int DELETE_DUMPHEAP_MSG = 52;
1499    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501    static final int REPORT_TIME_TRACKER_MSG = 55;
1502    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506    static final int IDLE_UIDS_MSG = 60;
1507    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508    static final int LOG_STACK_STATE = 62;
1509    static final int VR_MODE_CHANGE_MSG = 63;
1510    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1516
1517    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519    static final int FIRST_COMPAT_MODE_MSG = 300;
1520    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1521
1522    static ServiceThread sKillThread = null;
1523    static KillHandler sKillHandler = null;
1524
1525    CompatModeDialog mCompatModeDialog;
1526    long mLastMemUsageReportTime = 0;
1527
1528    /**
1529     * Flag whether the current user is a "monkey", i.e. whether
1530     * the UI is driven by a UI automation tool.
1531     */
1532    private boolean mUserIsMonkey;
1533
1534    /** Flag whether the device has a Recents UI */
1535    boolean mHasRecents;
1536
1537    /** The dimensions of the thumbnails in the Recents UI. */
1538    int mThumbnailWidth;
1539    int mThumbnailHeight;
1540    float mFullscreenThumbnailScale;
1541
1542    final ServiceThread mHandlerThread;
1543    final MainHandler mHandler;
1544    final UiHandler mUiHandler;
1545
1546    PackageManagerInternal mPackageManagerInt;
1547
1548    // VoiceInteraction session ID that changes for each new request except when
1549    // being called for multiwindow assist in a single session.
1550    private int mViSessionId = 1000;
1551
1552    final class KillHandler extends Handler {
1553        static final int KILL_PROCESS_GROUP_MSG = 4000;
1554
1555        public KillHandler(Looper looper) {
1556            super(looper, null, true);
1557        }
1558
1559        @Override
1560        public void handleMessage(Message msg) {
1561            switch (msg.what) {
1562                case KILL_PROCESS_GROUP_MSG:
1563                {
1564                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1567                }
1568                break;
1569
1570                default:
1571                    super.handleMessage(msg);
1572            }
1573        }
1574    }
1575
1576    final class UiHandler extends Handler {
1577        public UiHandler() {
1578            super(com.android.server.UiThread.get().getLooper(), null, true);
1579        }
1580
1581        @Override
1582        public void handleMessage(Message msg) {
1583            switch (msg.what) {
1584            case SHOW_ERROR_UI_MSG: {
1585                mAppErrors.handleShowAppErrorUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_NOT_RESPONDING_UI_MSG: {
1589                mAppErrors.handleShowAnrUi(msg);
1590                ensureBootCompleted();
1591            } break;
1592            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord proc = (ProcessRecord) data.get("app");
1596                    if (proc == null) {
1597                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1598                        break;
1599                    }
1600                    if (proc.crashDialog != null) {
1601                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1602                        return;
1603                    }
1604                    AppErrorResult res = (AppErrorResult) data.get("result");
1605                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606                        Dialog d = new StrictModeViolationDialog(mContext,
1607                                ActivityManagerService.this, res, proc);
1608                        d.show();
1609                        proc.crashDialog = d;
1610                    } else {
1611                        // The device is asleep, so just pretend that the user
1612                        // saw a crash dialog and hit "force quit".
1613                        res.set(0);
1614                    }
1615                }
1616                ensureBootCompleted();
1617            } break;
1618            case SHOW_FACTORY_ERROR_UI_MSG: {
1619                Dialog d = new FactoryErrorDialog(
1620                    mContext, msg.getData().getCharSequence("msg"));
1621                d.show();
1622                ensureBootCompleted();
1623            } break;
1624            case WAIT_FOR_DEBUGGER_UI_MSG: {
1625                synchronized (ActivityManagerService.this) {
1626                    ProcessRecord app = (ProcessRecord)msg.obj;
1627                    if (msg.arg1 != 0) {
1628                        if (!app.waitedForDebugger) {
1629                            Dialog d = new AppWaitingForDebuggerDialog(
1630                                    ActivityManagerService.this,
1631                                    mContext, app);
1632                            app.waitDialog = d;
1633                            app.waitedForDebugger = true;
1634                            d.show();
1635                        }
1636                    } else {
1637                        if (app.waitDialog != null) {
1638                            app.waitDialog.dismiss();
1639                            app.waitDialog = null;
1640                        }
1641                    }
1642                }
1643            } break;
1644            case SHOW_UID_ERROR_UI_MSG: {
1645                if (mShowDialogs) {
1646                    AlertDialog d = new BaseErrorDialog(mContext);
1647                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648                    d.setCancelable(false);
1649                    d.setTitle(mContext.getText(R.string.android_system_label));
1650                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653                    d.show();
1654                }
1655            } break;
1656            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1657                if (mShowDialogs) {
1658                    AlertDialog d = new BaseErrorDialog(mContext);
1659                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660                    d.setCancelable(false);
1661                    d.setTitle(mContext.getText(R.string.android_system_label));
1662                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665                    d.show();
1666                }
1667            } break;
1668            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669                synchronized (ActivityManagerService.this) {
1670                    ActivityRecord ar = (ActivityRecord) msg.obj;
1671                    if (mCompatModeDialog != null) {
1672                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1673                                ar.info.applicationInfo.packageName)) {
1674                            return;
1675                        }
1676                        mCompatModeDialog.dismiss();
1677                        mCompatModeDialog = null;
1678                    }
1679                    if (ar != null && false) {
1680                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1681                                ar.packageName)) {
1682                            int mode = mCompatModePackages.computeCompatModeLocked(
1683                                    ar.info.applicationInfo);
1684                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686                                mCompatModeDialog = new CompatModeDialog(
1687                                        ActivityManagerService.this, mContext,
1688                                        ar.info.applicationInfo);
1689                                mCompatModeDialog.show();
1690                            }
1691                        }
1692                    }
1693                }
1694                break;
1695            }
1696            case START_USER_SWITCH_UI_MSG: {
1697                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1698                break;
1699            }
1700            case DISMISS_DIALOG_UI_MSG: {
1701                final Dialog d = (Dialog) msg.obj;
1702                d.dismiss();
1703                break;
1704            }
1705            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706                dispatchProcessesChanged();
1707                break;
1708            }
1709            case DISPATCH_PROCESS_DIED_UI_MSG: {
1710                final int pid = msg.arg1;
1711                final int uid = msg.arg2;
1712                dispatchProcessDied(pid, uid);
1713                break;
1714            }
1715            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716                dispatchUidsChanged();
1717            } break;
1718            }
1719        }
1720    }
1721
1722    final class MainHandler extends Handler {
1723        public MainHandler(Looper looper) {
1724            super(looper, null, true);
1725        }
1726
1727        @Override
1728        public void handleMessage(Message msg) {
1729            switch (msg.what) {
1730            case UPDATE_CONFIGURATION_MSG: {
1731                final ContentResolver resolver = mContext.getContentResolver();
1732                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1733                        msg.arg1);
1734            } break;
1735            case GC_BACKGROUND_PROCESSES_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    performAppGcsIfAppropriateLocked();
1738                }
1739            } break;
1740            case SERVICE_TIMEOUT_MSG: {
1741                if (mDidDexOpt) {
1742                    mDidDexOpt = false;
1743                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1744                    nmsg.obj = msg.obj;
1745                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1746                    return;
1747                }
1748                mServices.serviceTimeout((ProcessRecord)msg.obj);
1749            } break;
1750            case UPDATE_TIME_ZONE: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimeZone();
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763            } break;
1764            case CLEAR_DNS_CACHE_MSG: {
1765                synchronized (ActivityManagerService.this) {
1766                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767                        ProcessRecord r = mLruProcesses.get(i);
1768                        if (r.thread != null) {
1769                            try {
1770                                r.thread.clearDnsCache();
1771                            } catch (RemoteException ex) {
1772                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1773                            }
1774                        }
1775                    }
1776                }
1777            } break;
1778            case UPDATE_HTTP_PROXY_MSG: {
1779                ProxyInfo proxy = (ProxyInfo)msg.obj;
1780                String host = "";
1781                String port = "";
1782                String exclList = "";
1783                Uri pacFileUrl = Uri.EMPTY;
1784                if (proxy != null) {
1785                    host = proxy.getHost();
1786                    port = Integer.toString(proxy.getPort());
1787                    exclList = proxy.getExclusionListAsString();
1788                    pacFileUrl = proxy.getPacFileUrl();
1789                }
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to update http proxy for: " +
1798                                        r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case PROC_START_TIMEOUT_MSG: {
1805                if (mDidDexOpt) {
1806                    mDidDexOpt = false;
1807                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1808                    nmsg.obj = msg.obj;
1809                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1810                    return;
1811                }
1812                ProcessRecord app = (ProcessRecord)msg.obj;
1813                synchronized (ActivityManagerService.this) {
1814                    processStartTimedOutLocked(app);
1815                }
1816            } break;
1817            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818                ProcessRecord app = (ProcessRecord)msg.obj;
1819                synchronized (ActivityManagerService.this) {
1820                    processContentProviderPublishTimedOutLocked(app);
1821                }
1822            } break;
1823            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824                synchronized (ActivityManagerService.this) {
1825                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1826                }
1827            } break;
1828            case KILL_APPLICATION_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    int appid = msg.arg1;
1831                    boolean restart = (msg.arg2 == 1);
1832                    Bundle bundle = (Bundle)msg.obj;
1833                    String pkg = bundle.getString("pkg");
1834                    String reason = bundle.getString("reason");
1835                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836                            false, UserHandle.USER_ALL, reason);
1837                }
1838            } break;
1839            case FINALIZE_PENDING_INTENT_MSG: {
1840                ((PendingIntentRecord)msg.obj).completeFinalize();
1841            } break;
1842            case POST_HEAVY_NOTIFICATION_MSG: {
1843                INotificationManager inm = NotificationManager.getService();
1844                if (inm == null) {
1845                    return;
1846                }
1847
1848                ActivityRecord root = (ActivityRecord)msg.obj;
1849                ProcessRecord process = root.app;
1850                if (process == null) {
1851                    return;
1852                }
1853
1854                try {
1855                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1856                    String text = mContext.getString(R.string.heavy_weight_notification,
1857                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858                    Notification notification = new Notification.Builder(context)
1859                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860                            .setWhen(0)
1861                            .setOngoing(true)
1862                            .setTicker(text)
1863                            .setColor(mContext.getColor(
1864                                    com.android.internal.R.color.system_notification_accent_color))
1865                            .setContentTitle(text)
1866                            .setContentText(
1867                                    mContext.getText(R.string.heavy_weight_notification_detail))
1868                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870                                    new UserHandle(root.userId)))
1871                            .build();
1872                    try {
1873                        int[] outId = new int[1];
1874                        inm.enqueueNotificationWithTag("android", "android", null,
1875                                R.string.heavy_weight_notification,
1876                                notification, outId, root.userId);
1877                    } catch (RuntimeException e) {
1878                        Slog.w(ActivityManagerService.TAG,
1879                                "Error showing notification for heavy-weight app", e);
1880                    } catch (RemoteException e) {
1881                    }
1882                } catch (NameNotFoundException e) {
1883                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1884                }
1885            } break;
1886            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887                INotificationManager inm = NotificationManager.getService();
1888                if (inm == null) {
1889                    return;
1890                }
1891                try {
1892                    inm.cancelNotificationWithTag("android", null,
1893                            R.string.heavy_weight_notification,  msg.arg1);
1894                } catch (RuntimeException e) {
1895                    Slog.w(ActivityManagerService.TAG,
1896                            "Error canceling notification for service", e);
1897                } catch (RemoteException e) {
1898                }
1899            } break;
1900            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    checkExcessivePowerUsageLocked(true);
1903                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1906                }
1907            } break;
1908            case REPORT_MEM_USAGE_MSG: {
1909                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910                Thread thread = new Thread() {
1911                    @Override public void run() {
1912                        reportMemUsage(memInfos);
1913                    }
1914                };
1915                thread.start();
1916                break;
1917            }
1918            case REPORT_USER_SWITCH_MSG: {
1919                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case CONTINUE_USER_SWITCH_MSG: {
1923                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case USER_SWITCH_TIMEOUT_MSG: {
1927                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1928                break;
1929            }
1930            case IMMERSIVE_MODE_LOCK_MSG: {
1931                final boolean nextState = (msg.arg1 != 0);
1932                if (mUpdateLock.isHeld() != nextState) {
1933                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934                            "Applying new update lock state '" + nextState
1935                            + "' for " + (ActivityRecord)msg.obj);
1936                    if (nextState) {
1937                        mUpdateLock.acquire();
1938                    } else {
1939                        mUpdateLock.release();
1940                    }
1941                }
1942                break;
1943            }
1944            case PERSIST_URI_GRANTS_MSG: {
1945                writeGrantedUriPermissions();
1946                break;
1947            }
1948            case REQUEST_ALL_PSS_MSG: {
1949                synchronized (ActivityManagerService.this) {
1950                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951                }
1952                break;
1953            }
1954            case START_PROFILES_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    mUserController.startProfilesLocked();
1957                }
1958                break;
1959            }
1960            case UPDATE_TIME: {
1961                synchronized (ActivityManagerService.this) {
1962                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963                        ProcessRecord r = mLruProcesses.get(i);
1964                        if (r.thread != null) {
1965                            try {
1966                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967                            } catch (RemoteException ex) {
1968                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1969                            }
1970                        }
1971                    }
1972                }
1973                break;
1974            }
1975            case SYSTEM_USER_START_MSG: {
1976                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977                        Integer.toString(msg.arg1), msg.arg1);
1978                mSystemServiceManager.startUser(msg.arg1);
1979                break;
1980            }
1981            case SYSTEM_USER_UNLOCK_MSG: {
1982                final int userId = msg.arg1;
1983                mSystemServiceManager.unlockUser(userId);
1984                synchronized (ActivityManagerService.this) {
1985                    mRecentTasks.loadUserRecentsLocked(userId);
1986                }
1987                if (userId == UserHandle.USER_SYSTEM) {
1988                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1989                }
1990                installEncryptionUnawareProviders(userId);
1991                mUserController.finishUserUnlocked((UserState) msg.obj);
1992                break;
1993            }
1994            case SYSTEM_USER_CURRENT_MSG: {
1995                mBatteryStatsService.noteEvent(
1996                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997                        Integer.toString(msg.arg2), msg.arg2);
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000                        Integer.toString(msg.arg1), msg.arg1);
2001                mSystemServiceManager.switchUser(msg.arg1);
2002                break;
2003            }
2004            case ENTER_ANIMATION_COMPLETE_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007                    if (r != null && r.app != null && r.app.thread != null) {
2008                        try {
2009                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010                        } catch (RemoteException e) {
2011                        }
2012                    }
2013                }
2014                break;
2015            }
2016            case FINISH_BOOTING_MSG: {
2017                if (msg.arg1 != 0) {
2018                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2019                    finishBooting();
2020                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2021                }
2022                if (msg.arg2 != 0) {
2023                    enableScreenAfterBoot();
2024                }
2025                break;
2026            }
2027            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2028                try {
2029                    Locale l = (Locale) msg.obj;
2030                    IBinder service = ServiceManager.getService("mount");
2031                    IMountService mountService = IMountService.Stub.asInterface(service);
2032                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034                } catch (RemoteException e) {
2035                    Log.e(TAG, "Error storing locale for decryption UI", e);
2036                }
2037                break;
2038            }
2039            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059                        } catch (RemoteException e){
2060                            // Handled by the RemoteCallbackList
2061                        }
2062                    }
2063                    mTaskStackListeners.finishBroadcast();
2064                }
2065                break;
2066            }
2067            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2070                        try {
2071                            // Make a one-way callback to the listener
2072                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073                        } catch (RemoteException e){
2074                            // Handled by the RemoteCallbackList
2075                        }
2076                    }
2077                    mTaskStackListeners.finishBroadcast();
2078                }
2079                break;
2080            }
2081            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082                synchronized (ActivityManagerService.this) {
2083                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2084                        try {
2085                            // Make a one-way callback to the listener
2086                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087                        } catch (RemoteException e){
2088                            // Handled by the RemoteCallbackList
2089                        }
2090                    }
2091                    mTaskStackListeners.finishBroadcast();
2092                }
2093                break;
2094            }
2095            case NOTIFY_FORCED_RESIZABLE_MSG: {
2096                synchronized (ActivityManagerService.this) {
2097                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2098                        try {
2099                            // Make a one-way callback to the listener
2100                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101                                    (String) msg.obj, msg.arg1);
2102                        } catch (RemoteException e){
2103                            // Handled by the RemoteCallbackList
2104                        }
2105                    }
2106                    mTaskStackListeners.finishBroadcast();
2107                }
2108                break;
2109            }
2110                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111                    synchronized (ActivityManagerService.this) {
2112                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113                            try {
2114                                // Make a one-way callback to the listener
2115                                mTaskStackListeners.getBroadcastItem(i)
2116                                        .onActivityDismissingDockedStack();
2117                            } catch (RemoteException e){
2118                                // Handled by the RemoteCallbackList
2119                            }
2120                        }
2121                        mTaskStackListeners.finishBroadcast();
2122                    }
2123                    break;
2124                }
2125            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126                final int uid = msg.arg1;
2127                final byte[] firstPacket = (byte[]) msg.obj;
2128
2129                synchronized (mPidsSelfLocked) {
2130                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2132                        if (p.uid == uid) {
2133                            try {
2134                                p.thread.notifyCleartextNetwork(firstPacket);
2135                            } catch (RemoteException ignored) {
2136                            }
2137                        }
2138                    }
2139                }
2140                break;
2141            }
2142            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143                final String procName;
2144                final int uid;
2145                final long memLimit;
2146                final String reportPackage;
2147                synchronized (ActivityManagerService.this) {
2148                    procName = mMemWatchDumpProcName;
2149                    uid = mMemWatchDumpUid;
2150                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2151                    if (val == null) {
2152                        val = mMemWatchProcesses.get(procName, 0);
2153                    }
2154                    if (val != null) {
2155                        memLimit = val.first;
2156                        reportPackage = val.second;
2157                    } else {
2158                        memLimit = 0;
2159                        reportPackage = null;
2160                    }
2161                }
2162                if (procName == null) {
2163                    return;
2164                }
2165
2166                if (DEBUG_PSS) Slog.d(TAG_PSS,
2167                        "Showing dump heap notification from " + procName + "/" + uid);
2168
2169                INotificationManager inm = NotificationManager.getService();
2170                if (inm == null) {
2171                    return;
2172                }
2173
2174                String text = mContext.getString(R.string.dump_heap_notification, procName);
2175
2176
2177                Intent deleteIntent = new Intent();
2178                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179                Intent intent = new Intent();
2180                intent.setClassName("android", DumpHeapActivity.class.getName());
2181                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183                if (reportPackage != null) {
2184                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2185                }
2186                int userId = UserHandle.getUserId(uid);
2187                Notification notification = new Notification.Builder(mContext)
2188                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2189                        .setWhen(0)
2190                        .setOngoing(true)
2191                        .setAutoCancel(true)
2192                        .setTicker(text)
2193                        .setColor(mContext.getColor(
2194                                com.android.internal.R.color.system_notification_accent_color))
2195                        .setContentTitle(text)
2196                        .setContentText(
2197                                mContext.getText(R.string.dump_heap_notification_detail))
2198                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200                                new UserHandle(userId)))
2201                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202                                deleteIntent, 0, UserHandle.SYSTEM))
2203                        .build();
2204
2205                try {
2206                    int[] outId = new int[1];
2207                    inm.enqueueNotificationWithTag("android", "android", null,
2208                            R.string.dump_heap_notification,
2209                            notification, outId, userId);
2210                } catch (RuntimeException e) {
2211                    Slog.w(ActivityManagerService.TAG,
2212                            "Error showing notification for dump heap", e);
2213                } catch (RemoteException e) {
2214                }
2215            } break;
2216            case DELETE_DUMPHEAP_MSG: {
2217                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218                        DumpHeapActivity.JAVA_URI,
2219                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2220                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221                        UserHandle.myUserId());
2222                synchronized (ActivityManagerService.this) {
2223                    mMemWatchDumpFile = null;
2224                    mMemWatchDumpProcName = null;
2225                    mMemWatchDumpPid = -1;
2226                    mMemWatchDumpUid = -1;
2227                }
2228            } break;
2229            case FOREGROUND_PROFILE_CHANGED_MSG: {
2230                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2231            } break;
2232            case REPORT_TIME_TRACKER_MSG: {
2233                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234                tracker.deliverResult(mContext);
2235            } break;
2236            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237                mUserController.dispatchUserSwitchComplete(msg.arg1);
2238            } break;
2239            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2241                try {
2242                    connection.shutdown();
2243                } catch (RemoteException e) {
2244                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2245                }
2246                // Only a UiAutomation can set this flag and now that
2247                // it is finished we make sure it is reset to its default.
2248                mUserIsMonkey = false;
2249            } break;
2250            case APP_BOOST_DEACTIVATE_MSG: {
2251                synchronized(ActivityManagerService.this) {
2252                    if (mIsBoosted) {
2253                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254                            nativeMigrateFromBoost();
2255                            mIsBoosted = false;
2256                            mBoostStartTime = 0;
2257                        } else {
2258                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2260                        }
2261                    }
2262                }
2263            } break;
2264            case IDLE_UIDS_MSG: {
2265                idleUids();
2266            } break;
2267            case LOG_STACK_STATE: {
2268                synchronized (ActivityManagerService.this) {
2269                    mStackSupervisor.logStackState();
2270                }
2271            } break;
2272            case VR_MODE_CHANGE_MSG: {
2273                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274                final ActivityRecord r = (ActivityRecord) msg.obj;
2275                boolean vrMode;
2276                ComponentName requestedPackage;
2277                ComponentName callingPackage;
2278                int userId;
2279                synchronized (ActivityManagerService.this) {
2280                    vrMode = r.requestedVrComponent != null;
2281                    requestedPackage = r.requestedVrComponent;
2282                    userId = r.userId;
2283                    callingPackage = r.info.getComponentName();
2284                    if (mInVrMode != vrMode) {
2285                        mInVrMode = vrMode;
2286                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2287                    }
2288                }
2289                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2290            } break;
2291            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292                final ActivityRecord r = (ActivityRecord) msg.obj;
2293                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2294                if (needsVrMode) {
2295                    VrManagerInternal vrService =
2296                            LocalServices.getService(VrManagerInternal.class);
2297                    boolean enable = msg.arg1 == 1;
2298                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2299                            r.info.getComponentName());
2300                }
2301            } break;
2302            }
2303        }
2304    };
2305
2306    static final int COLLECT_PSS_BG_MSG = 1;
2307
2308    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2309        @Override
2310        public void handleMessage(Message msg) {
2311            switch (msg.what) {
2312            case COLLECT_PSS_BG_MSG: {
2313                long start = SystemClock.uptimeMillis();
2314                MemInfoReader memInfo = null;
2315                synchronized (ActivityManagerService.this) {
2316                    if (mFullPssPending) {
2317                        mFullPssPending = false;
2318                        memInfo = new MemInfoReader();
2319                    }
2320                }
2321                if (memInfo != null) {
2322                    updateCpuStatsNow();
2323                    long nativeTotalPss = 0;
2324                    synchronized (mProcessCpuTracker) {
2325                        final int N = mProcessCpuTracker.countStats();
2326                        for (int j=0; j<N; j++) {
2327                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2328                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2329                                // This is definitely an application process; skip it.
2330                                continue;
2331                            }
2332                            synchronized (mPidsSelfLocked) {
2333                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2334                                    // This is one of our own processes; skip it.
2335                                    continue;
2336                                }
2337                            }
2338                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2339                        }
2340                    }
2341                    memInfo.readMemInfo();
2342                    synchronized (ActivityManagerService.this) {
2343                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2344                                + (SystemClock.uptimeMillis()-start) + "ms");
2345                        final long cachedKb = memInfo.getCachedSizeKb();
2346                        final long freeKb = memInfo.getFreeSizeKb();
2347                        final long zramKb = memInfo.getZramTotalSizeKb();
2348                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2349                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2350                                kernelKb*1024, nativeTotalPss*1024);
2351                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2352                                nativeTotalPss);
2353                    }
2354                }
2355
2356                int num = 0;
2357                long[] tmp = new long[2];
2358                do {
2359                    ProcessRecord proc;
2360                    int procState;
2361                    int pid;
2362                    long lastPssTime;
2363                    synchronized (ActivityManagerService.this) {
2364                        if (mPendingPssProcesses.size() <= 0) {
2365                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2366                                    "Collected PSS of " + num + " processes in "
2367                                    + (SystemClock.uptimeMillis() - start) + "ms");
2368                            mPendingPssProcesses.clear();
2369                            return;
2370                        }
2371                        proc = mPendingPssProcesses.remove(0);
2372                        procState = proc.pssProcState;
2373                        lastPssTime = proc.lastPssTime;
2374                        if (proc.thread != null && procState == proc.setProcState
2375                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2376                                        < SystemClock.uptimeMillis()) {
2377                            pid = proc.pid;
2378                        } else {
2379                            proc = null;
2380                            pid = 0;
2381                        }
2382                    }
2383                    if (proc != null) {
2384                        long pss = Debug.getPss(pid, tmp, null);
2385                        synchronized (ActivityManagerService.this) {
2386                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2387                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2388                                num++;
2389                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2390                                        SystemClock.uptimeMillis());
2391                            }
2392                        }
2393                    }
2394                } while (true);
2395            }
2396            }
2397        }
2398    };
2399
2400    public void setSystemProcess() {
2401        try {
2402            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2403            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2404            ServiceManager.addService("meminfo", new MemBinder(this));
2405            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2406            ServiceManager.addService("dbinfo", new DbBinder(this));
2407            if (MONITOR_CPU_USAGE) {
2408                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2409            }
2410            ServiceManager.addService("permission", new PermissionController(this));
2411            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2412
2413            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2414                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2415            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2416
2417            synchronized (this) {
2418                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2419                app.persistent = true;
2420                app.pid = MY_PID;
2421                app.maxAdj = ProcessList.SYSTEM_ADJ;
2422                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2423                synchronized (mPidsSelfLocked) {
2424                    mPidsSelfLocked.put(app.pid, app);
2425                }
2426                updateLruProcessLocked(app, false, null);
2427                updateOomAdjLocked();
2428            }
2429        } catch (PackageManager.NameNotFoundException e) {
2430            throw new RuntimeException(
2431                    "Unable to find android system package", e);
2432        }
2433    }
2434
2435    public void setWindowManager(WindowManagerService wm) {
2436        mWindowManager = wm;
2437        mStackSupervisor.setWindowManager(wm);
2438        mActivityStarter.setWindowManager(wm);
2439    }
2440
2441    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2442        mUsageStatsService = usageStatsManager;
2443    }
2444
2445    public void startObservingNativeCrashes() {
2446        final NativeCrashListener ncl = new NativeCrashListener(this);
2447        ncl.start();
2448    }
2449
2450    public IAppOpsService getAppOpsService() {
2451        return mAppOpsService;
2452    }
2453
2454    static class MemBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        MemBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump meminfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2471        }
2472    }
2473
2474    static class GraphicsBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        GraphicsBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2491        }
2492    }
2493
2494    static class DbBinder extends Binder {
2495        ActivityManagerService mActivityManagerService;
2496        DbBinder(ActivityManagerService activityManagerService) {
2497            mActivityManagerService = activityManagerService;
2498        }
2499
2500        @Override
2501        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503                    != PackageManager.PERMISSION_GRANTED) {
2504                pw.println("Permission Denial: can't dump dbinfo from from pid="
2505                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506                        + " without permission " + android.Manifest.permission.DUMP);
2507                return;
2508            }
2509
2510            mActivityManagerService.dumpDbInfo(fd, pw, args);
2511        }
2512    }
2513
2514    static class CpuBinder extends Binder {
2515        ActivityManagerService mActivityManagerService;
2516        CpuBinder(ActivityManagerService activityManagerService) {
2517            mActivityManagerService = activityManagerService;
2518        }
2519
2520        @Override
2521        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523                    != PackageManager.PERMISSION_GRANTED) {
2524                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2525                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526                        + " without permission " + android.Manifest.permission.DUMP);
2527                return;
2528            }
2529
2530            synchronized (mActivityManagerService.mProcessCpuTracker) {
2531                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2532                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2533                        SystemClock.uptimeMillis()));
2534            }
2535        }
2536    }
2537
2538    public static final class Lifecycle extends SystemService {
2539        private final ActivityManagerService mService;
2540
2541        public Lifecycle(Context context) {
2542            super(context);
2543            mService = new ActivityManagerService(context);
2544        }
2545
2546        @Override
2547        public void onStart() {
2548            mService.start();
2549        }
2550
2551        public ActivityManagerService getService() {
2552            return mService;
2553        }
2554    }
2555
2556    // Note: This method is invoked on the main thread but may need to attach various
2557    // handlers to other threads.  So take care to be explicit about the looper.
2558    public ActivityManagerService(Context systemContext) {
2559        mContext = systemContext;
2560        mFactoryTest = FactoryTest.getMode();
2561        mSystemThread = ActivityThread.currentActivityThread();
2562
2563        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2564
2565        mHandlerThread = new ServiceThread(TAG,
2566                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2567        mHandlerThread.start();
2568        mHandler = new MainHandler(mHandlerThread.getLooper());
2569        mUiHandler = new UiHandler();
2570
2571        /* static; one-time init here */
2572        if (sKillHandler == null) {
2573            sKillThread = new ServiceThread(TAG + ":kill",
2574                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2575            sKillThread.start();
2576            sKillHandler = new KillHandler(sKillThread.getLooper());
2577        }
2578
2579        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580                "foreground", BROADCAST_FG_TIMEOUT, false);
2581        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2582                "background", BROADCAST_BG_TIMEOUT, true);
2583        mBroadcastQueues[0] = mFgBroadcastQueue;
2584        mBroadcastQueues[1] = mBgBroadcastQueue;
2585
2586        mServices = new ActiveServices(this);
2587        mProviderMap = new ProviderMap(this);
2588        mAppErrors = new AppErrors(mContext, this);
2589
2590        // TODO: Move creation of battery stats service outside of activity manager service.
2591        File dataDir = Environment.getDataDirectory();
2592        File systemDir = new File(dataDir, "system");
2593        systemDir.mkdirs();
2594        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2595        mBatteryStatsService.getActiveStatistics().readLocked();
2596        mBatteryStatsService.scheduleWriteToDisk();
2597        mOnBattery = DEBUG_POWER ? true
2598                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2599        mBatteryStatsService.getActiveStatistics().setCallback(this);
2600
2601        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2602
2603        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2604        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2605                new IAppOpsCallback.Stub() {
2606                    @Override public void opChanged(int op, int uid, String packageName) {
2607                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2608                            if (mAppOpsService.checkOperation(op, uid, packageName)
2609                                    != AppOpsManager.MODE_ALLOWED) {
2610                                runInBackgroundDisabled(uid);
2611                            }
2612                        }
2613                    }
2614                });
2615
2616        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2617
2618        mUserController = new UserController(this);
2619
2620        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2621            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2622
2623        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2624
2625        mConfiguration.setToDefaults();
2626        mConfiguration.setLocales(LocaleList.getDefault());
2627
2628        mConfigurationSeq = mConfiguration.seq = 1;
2629        mProcessCpuTracker.init();
2630
2631        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2632        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2633        mStackSupervisor = new ActivityStackSupervisor(this);
2634        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2636
2637        mProcessCpuThread = new Thread("CpuTracker") {
2638            @Override
2639            public void run() {
2640                while (true) {
2641                    try {
2642                        try {
2643                            synchronized(this) {
2644                                final long now = SystemClock.uptimeMillis();
2645                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648                                //        + ", write delay=" + nextWriteDelay);
2649                                if (nextWriteDelay < nextCpuDelay) {
2650                                    nextCpuDelay = nextWriteDelay;
2651                                }
2652                                if (nextCpuDelay > 0) {
2653                                    mProcessCpuMutexFree.set(true);
2654                                    this.wait(nextCpuDelay);
2655                                }
2656                            }
2657                        } catch (InterruptedException e) {
2658                        }
2659                        updateCpuStatsNow();
2660                    } catch (Exception e) {
2661                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2662                    }
2663                }
2664            }
2665        };
2666
2667        Watchdog.getInstance().addMonitor(this);
2668        Watchdog.getInstance().addThread(mHandler);
2669    }
2670
2671    public void setSystemServiceManager(SystemServiceManager mgr) {
2672        mSystemServiceManager = mgr;
2673    }
2674
2675    public void setInstaller(Installer installer) {
2676        mInstaller = installer;
2677    }
2678
2679    private void start() {
2680        Process.removeAllProcessGroups();
2681        mProcessCpuThread.start();
2682
2683        mBatteryStatsService.publish(mContext);
2684        mAppOpsService.publish(mContext);
2685        Slog.d("AppOps", "AppOpsService published");
2686        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2687    }
2688
2689    void onUserStoppedLocked(int userId) {
2690        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2691    }
2692
2693    public void initPowerManagement() {
2694        mStackSupervisor.initPowerManagement();
2695        mBatteryStatsService.initPowerManagement();
2696        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699        mVoiceWakeLock.setReferenceCounted(false);
2700    }
2701
2702    @Override
2703    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704            throws RemoteException {
2705        if (code == SYSPROPS_TRANSACTION) {
2706            // We need to tell all apps about the system property change.
2707            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708            synchronized(this) {
2709                final int NP = mProcessNames.getMap().size();
2710                for (int ip=0; ip<NP; ip++) {
2711                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712                    final int NA = apps.size();
2713                    for (int ia=0; ia<NA; ia++) {
2714                        ProcessRecord app = apps.valueAt(ia);
2715                        if (app.thread != null) {
2716                            procs.add(app.thread.asBinder());
2717                        }
2718                    }
2719                }
2720            }
2721
2722            int N = procs.size();
2723            for (int i=0; i<N; i++) {
2724                Parcel data2 = Parcel.obtain();
2725                try {
2726                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727                } catch (RemoteException e) {
2728                }
2729                data2.recycle();
2730            }
2731        }
2732        try {
2733            return super.onTransact(code, data, reply, flags);
2734        } catch (RuntimeException e) {
2735            // The activity manager only throws security exceptions, so let's
2736            // log all others.
2737            if (!(e instanceof SecurityException)) {
2738                Slog.wtf(TAG, "Activity Manager Crash", e);
2739            }
2740            throw e;
2741        }
2742    }
2743
2744    void updateCpuStats() {
2745        final long now = SystemClock.uptimeMillis();
2746        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2747            return;
2748        }
2749        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750            synchronized (mProcessCpuThread) {
2751                mProcessCpuThread.notify();
2752            }
2753        }
2754    }
2755
2756    void updateCpuStatsNow() {
2757        synchronized (mProcessCpuTracker) {
2758            mProcessCpuMutexFree.set(false);
2759            final long now = SystemClock.uptimeMillis();
2760            boolean haveNewCpuStats = false;
2761
2762            if (MONITOR_CPU_USAGE &&
2763                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764                mLastCpuTime.set(now);
2765                mProcessCpuTracker.update();
2766                if (mProcessCpuTracker.hasGoodLastStats()) {
2767                    haveNewCpuStats = true;
2768                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2769                    //Slog.i(TAG, "Total CPU usage: "
2770                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2771
2772                    // Slog the cpu usage if the property is set.
2773                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2774                        int user = mProcessCpuTracker.getLastUserTime();
2775                        int system = mProcessCpuTracker.getLastSystemTime();
2776                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777                        int irq = mProcessCpuTracker.getLastIrqTime();
2778                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779                        int idle = mProcessCpuTracker.getLastIdleTime();
2780
2781                        int total = user + system + iowait + irq + softIrq + idle;
2782                        if (total == 0) total = 1;
2783
2784                        EventLog.writeEvent(EventLogTags.CPU,
2785                                ((user+system+iowait+irq+softIrq) * 100) / total,
2786                                (user * 100) / total,
2787                                (system * 100) / total,
2788                                (iowait * 100) / total,
2789                                (irq * 100) / total,
2790                                (softIrq * 100) / total);
2791                    }
2792                }
2793            }
2794
2795            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796            synchronized(bstats) {
2797                synchronized(mPidsSelfLocked) {
2798                    if (haveNewCpuStats) {
2799                        if (bstats.startAddingCpuLocked()) {
2800                            int totalUTime = 0;
2801                            int totalSTime = 0;
2802                            final int N = mProcessCpuTracker.countStats();
2803                            for (int i=0; i<N; i++) {
2804                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805                                if (!st.working) {
2806                                    continue;
2807                                }
2808                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809                                totalUTime += st.rel_utime;
2810                                totalSTime += st.rel_stime;
2811                                if (pr != null) {
2812                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813                                    if (ps == null || !ps.isActive()) {
2814                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815                                                pr.info.uid, pr.processName);
2816                                    }
2817                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2819                                } else {
2820                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821                                    if (ps == null || !ps.isActive()) {
2822                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2823                                                bstats.mapUid(st.uid), st.name);
2824                                    }
2825                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2826                                }
2827                            }
2828                            final int userTime = mProcessCpuTracker.getLastUserTime();
2829                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2836                        }
2837                    }
2838                }
2839
2840                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841                    mLastWriteTime = now;
2842                    mBatteryStatsService.scheduleWriteToDisk();
2843                }
2844            }
2845        }
2846    }
2847
2848    @Override
2849    public void batteryNeedsCpuUpdate() {
2850        updateCpuStatsNow();
2851    }
2852
2853    @Override
2854    public void batteryPowerChanged(boolean onBattery) {
2855        // When plugging in, update the CPU stats first before changing
2856        // the plug state.
2857        updateCpuStatsNow();
2858        synchronized (this) {
2859            synchronized(mPidsSelfLocked) {
2860                mOnBattery = DEBUG_POWER ? true : onBattery;
2861            }
2862        }
2863    }
2864
2865    @Override
2866    public void batterySendBroadcast(Intent intent) {
2867        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868                AppOpsManager.OP_NONE, null, false, false,
2869                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870    }
2871
2872    /**
2873     * Initialize the application bind args. These are passed to each
2874     * process when the bindApplication() IPC is sent to the process. They're
2875     * lazily setup to make sure the services are running when they're asked for.
2876     */
2877    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878        if (mAppBindArgs == null) {
2879            mAppBindArgs = new HashMap<>();
2880
2881            // Isolated processes won't get this optimization, so that we don't
2882            // violate the rules about which services they have access to.
2883            if (!isolated) {
2884                // Setup the application init args
2885                mAppBindArgs.put("package", ServiceManager.getService("package"));
2886                mAppBindArgs.put("window", ServiceManager.getService("window"));
2887                mAppBindArgs.put(Context.ALARM_SERVICE,
2888                        ServiceManager.getService(Context.ALARM_SERVICE));
2889            }
2890        }
2891        return mAppBindArgs;
2892    }
2893
2894    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2895        if (r == null || mFocusedActivity == r) {
2896            return false;
2897        }
2898
2899        if (!r.isFocusable()) {
2900            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2901            return false;
2902        }
2903
2904        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2905
2906        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2907        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2908                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2909        mDoingSetFocusedActivity = true;
2910
2911        final ActivityRecord last = mFocusedActivity;
2912        mFocusedActivity = r;
2913        if (r.task.isApplicationTask()) {
2914            if (mCurAppTimeTracker != r.appTimeTracker) {
2915                // We are switching app tracking.  Complete the current one.
2916                if (mCurAppTimeTracker != null) {
2917                    mCurAppTimeTracker.stop();
2918                    mHandler.obtainMessage(
2919                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2920                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2921                    mCurAppTimeTracker = null;
2922                }
2923                if (r.appTimeTracker != null) {
2924                    mCurAppTimeTracker = r.appTimeTracker;
2925                    startTimeTrackingFocusedActivityLocked();
2926                }
2927            } else {
2928                startTimeTrackingFocusedActivityLocked();
2929            }
2930        } else {
2931            r.appTimeTracker = null;
2932        }
2933        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2934        // TODO: Probably not, because we don't want to resume voice on switching
2935        // back to this activity
2936        if (r.task.voiceInteractor != null) {
2937            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2938        } else {
2939            finishRunningVoiceLocked();
2940            IVoiceInteractionSession session;
2941            if (last != null && ((session = last.task.voiceSession) != null
2942                    || (session = last.voiceSession) != null)) {
2943                // We had been in a voice interaction session, but now focused has
2944                // move to something different.  Just finish the session, we can't
2945                // return to it and retain the proper state and synchronization with
2946                // the voice interaction service.
2947                finishVoiceTask(session);
2948            }
2949        }
2950        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2951            mWindowManager.setFocusedApp(r.appToken, true);
2952        }
2953        applyUpdateLockStateLocked(r);
2954        applyUpdateVrModeLocked(r);
2955        if (mFocusedActivity.userId != mLastFocusedUserId) {
2956            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2957            mHandler.obtainMessage(
2958                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2959            mLastFocusedUserId = mFocusedActivity.userId;
2960        }
2961
2962        // Log a warning if the focused app is changed during the process. This could
2963        // indicate a problem of the focus setting logic!
2964        if (mFocusedActivity != r) Slog.w(TAG,
2965                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2966        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2967
2968        EventLogTags.writeAmFocusedActivity(
2969                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2970                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2971                reason);
2972        return true;
2973    }
2974
2975    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2976        if (mFocusedActivity != goingAway) {
2977            return;
2978        }
2979
2980        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2981        if (focusedStack != null) {
2982            final ActivityRecord top = focusedStack.topActivity();
2983            if (top != null && top.userId != mLastFocusedUserId) {
2984                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2985                mHandler.sendMessage(
2986                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2987                mLastFocusedUserId = top.userId;
2988            }
2989        }
2990
2991        // Try to move focus to another activity if possible.
2992        if (setFocusedActivityLocked(
2993                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2994            return;
2995        }
2996
2997        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2998                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2999        mFocusedActivity = null;
3000        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3001    }
3002
3003    @Override
3004    public void setFocusedStack(int stackId) {
3005        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3006        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3007        final long callingId = Binder.clearCallingIdentity();
3008        try {
3009            synchronized (this) {
3010                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3011                if (stack == null) {
3012                    return;
3013                }
3014                final ActivityRecord r = stack.topRunningActivityLocked();
3015                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3016                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3017                }
3018            }
3019        } finally {
3020            Binder.restoreCallingIdentity(callingId);
3021        }
3022    }
3023
3024    @Override
3025    public void setFocusedTask(int taskId) {
3026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3027        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3028        final long callingId = Binder.clearCallingIdentity();
3029        try {
3030            synchronized (this) {
3031                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3032                if (task == null) {
3033                    return;
3034                }
3035                final ActivityRecord r = task.topRunningActivityLocked();
3036                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3037                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3038                }
3039            }
3040        } finally {
3041            Binder.restoreCallingIdentity(callingId);
3042        }
3043    }
3044
3045    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3046    @Override
3047    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3049        synchronized (this) {
3050            if (listener != null) {
3051                mTaskStackListeners.register(listener);
3052            }
3053        }
3054    }
3055
3056    @Override
3057    public void notifyActivityDrawn(IBinder token) {
3058        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3059        synchronized (this) {
3060            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3061            if (r != null) {
3062                r.task.stack.notifyActivityDrawnLocked(r);
3063            }
3064        }
3065    }
3066
3067    final void applyUpdateLockStateLocked(ActivityRecord r) {
3068        // Modifications to the UpdateLock state are done on our handler, outside
3069        // the activity manager's locks.  The new state is determined based on the
3070        // state *now* of the relevant activity record.  The object is passed to
3071        // the handler solely for logging detail, not to be consulted/modified.
3072        final boolean nextState = r != null && r.immersive;
3073        mHandler.sendMessage(
3074                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3075    }
3076
3077    final void applyUpdateVrModeLocked(ActivityRecord r) {
3078        mHandler.sendMessage(
3079                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3080    }
3081
3082    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3083        mHandler.sendMessage(
3084                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3085    }
3086
3087    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3088        Message msg = Message.obtain();
3089        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3090        msg.obj = r.task.askedCompatMode ? null : r;
3091        mUiHandler.sendMessage(msg);
3092    }
3093
3094    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3095            String what, Object obj, ProcessRecord srcApp) {
3096        app.lastActivityTime = now;
3097
3098        if (app.activities.size() > 0) {
3099            // Don't want to touch dependent processes that are hosting activities.
3100            return index;
3101        }
3102
3103        int lrui = mLruProcesses.lastIndexOf(app);
3104        if (lrui < 0) {
3105            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3106                    + what + " " + obj + " from " + srcApp);
3107            return index;
3108        }
3109
3110        if (lrui >= index) {
3111            // Don't want to cause this to move dependent processes *back* in the
3112            // list as if they were less frequently used.
3113            return index;
3114        }
3115
3116        if (lrui >= mLruProcessActivityStart) {
3117            // Don't want to touch dependent processes that are hosting activities.
3118            return index;
3119        }
3120
3121        mLruProcesses.remove(lrui);
3122        if (index > 0) {
3123            index--;
3124        }
3125        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3126                + " in LRU list: " + app);
3127        mLruProcesses.add(index, app);
3128        return index;
3129    }
3130
3131    static void killProcessGroup(int uid, int pid) {
3132        if (sKillHandler != null) {
3133            sKillHandler.sendMessage(
3134                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3135        } else {
3136            Slog.w(TAG, "Asked to kill process group before system bringup!");
3137            Process.killProcessGroup(uid, pid);
3138        }
3139    }
3140
3141    final void removeLruProcessLocked(ProcessRecord app) {
3142        int lrui = mLruProcesses.lastIndexOf(app);
3143        if (lrui >= 0) {
3144            if (!app.killed) {
3145                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3146                Process.killProcessQuiet(app.pid);
3147                killProcessGroup(app.uid, app.pid);
3148            }
3149            if (lrui <= mLruProcessActivityStart) {
3150                mLruProcessActivityStart--;
3151            }
3152            if (lrui <= mLruProcessServiceStart) {
3153                mLruProcessServiceStart--;
3154            }
3155            mLruProcesses.remove(lrui);
3156        }
3157    }
3158
3159    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3160            ProcessRecord client) {
3161        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3162                || app.treatLikeActivity;
3163        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3164        if (!activityChange && hasActivity) {
3165            // The process has activities, so we are only allowing activity-based adjustments
3166            // to move it.  It should be kept in the front of the list with other
3167            // processes that have activities, and we don't want those to change their
3168            // order except due to activity operations.
3169            return;
3170        }
3171
3172        mLruSeq++;
3173        final long now = SystemClock.uptimeMillis();
3174        app.lastActivityTime = now;
3175
3176        // First a quick reject: if the app is already at the position we will
3177        // put it, then there is nothing to do.
3178        if (hasActivity) {
3179            final int N = mLruProcesses.size();
3180            if (N > 0 && mLruProcesses.get(N-1) == app) {
3181                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3182                return;
3183            }
3184        } else {
3185            if (mLruProcessServiceStart > 0
3186                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3187                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3188                return;
3189            }
3190        }
3191
3192        int lrui = mLruProcesses.lastIndexOf(app);
3193
3194        if (app.persistent && lrui >= 0) {
3195            // We don't care about the position of persistent processes, as long as
3196            // they are in the list.
3197            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3198            return;
3199        }
3200
3201        /* In progress: compute new position first, so we can avoid doing work
3202           if the process is not actually going to move.  Not yet working.
3203        int addIndex;
3204        int nextIndex;
3205        boolean inActivity = false, inService = false;
3206        if (hasActivity) {
3207            // Process has activities, put it at the very tipsy-top.
3208            addIndex = mLruProcesses.size();
3209            nextIndex = mLruProcessServiceStart;
3210            inActivity = true;
3211        } else if (hasService) {
3212            // Process has services, put it at the top of the service list.
3213            addIndex = mLruProcessActivityStart;
3214            nextIndex = mLruProcessServiceStart;
3215            inActivity = true;
3216            inService = true;
3217        } else  {
3218            // Process not otherwise of interest, it goes to the top of the non-service area.
3219            addIndex = mLruProcessServiceStart;
3220            if (client != null) {
3221                int clientIndex = mLruProcesses.lastIndexOf(client);
3222                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3223                        + app);
3224                if (clientIndex >= 0 && addIndex > clientIndex) {
3225                    addIndex = clientIndex;
3226                }
3227            }
3228            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3229        }
3230
3231        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3232                + mLruProcessActivityStart + "): " + app);
3233        */
3234
3235        if (lrui >= 0) {
3236            if (lrui < mLruProcessActivityStart) {
3237                mLruProcessActivityStart--;
3238            }
3239            if (lrui < mLruProcessServiceStart) {
3240                mLruProcessServiceStart--;
3241            }
3242            /*
3243            if (addIndex > lrui) {
3244                addIndex--;
3245            }
3246            if (nextIndex > lrui) {
3247                nextIndex--;
3248            }
3249            */
3250            mLruProcesses.remove(lrui);
3251        }
3252
3253        /*
3254        mLruProcesses.add(addIndex, app);
3255        if (inActivity) {
3256            mLruProcessActivityStart++;
3257        }
3258        if (inService) {
3259            mLruProcessActivityStart++;
3260        }
3261        */
3262
3263        int nextIndex;
3264        if (hasActivity) {
3265            final int N = mLruProcesses.size();
3266            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3267                // Process doesn't have activities, but has clients with
3268                // activities...  move it up, but one below the top (the top
3269                // should always have a real activity).
3270                if (DEBUG_LRU) Slog.d(TAG_LRU,
3271                        "Adding to second-top of LRU activity list: " + app);
3272                mLruProcesses.add(N - 1, app);
3273                // To keep it from spamming the LRU list (by making a bunch of clients),
3274                // we will push down any other entries owned by the app.
3275                final int uid = app.info.uid;
3276                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3277                    ProcessRecord subProc = mLruProcesses.get(i);
3278                    if (subProc.info.uid == uid) {
3279                        // We want to push this one down the list.  If the process after
3280                        // it is for the same uid, however, don't do so, because we don't
3281                        // want them internally to be re-ordered.
3282                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3283                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3284                                    "Pushing uid " + uid + " swapping at " + i + ": "
3285                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3286                            ProcessRecord tmp = mLruProcesses.get(i);
3287                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3288                            mLruProcesses.set(i - 1, tmp);
3289                            i--;
3290                        }
3291                    } else {
3292                        // A gap, we can stop here.
3293                        break;
3294                    }
3295                }
3296            } else {
3297                // Process has activities, put it at the very tipsy-top.
3298                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3299                mLruProcesses.add(app);
3300            }
3301            nextIndex = mLruProcessServiceStart;
3302        } else if (hasService) {
3303            // Process has services, put it at the top of the service list.
3304            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3305            mLruProcesses.add(mLruProcessActivityStart, app);
3306            nextIndex = mLruProcessServiceStart;
3307            mLruProcessActivityStart++;
3308        } else  {
3309            // Process not otherwise of interest, it goes to the top of the non-service area.
3310            int index = mLruProcessServiceStart;
3311            if (client != null) {
3312                // If there is a client, don't allow the process to be moved up higher
3313                // in the list than that client.
3314                int clientIndex = mLruProcesses.lastIndexOf(client);
3315                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3316                        + " when updating " + app);
3317                if (clientIndex <= lrui) {
3318                    // Don't allow the client index restriction to push it down farther in the
3319                    // list than it already is.
3320                    clientIndex = lrui;
3321                }
3322                if (clientIndex >= 0 && index > clientIndex) {
3323                    index = clientIndex;
3324                }
3325            }
3326            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3327            mLruProcesses.add(index, app);
3328            nextIndex = index-1;
3329            mLruProcessActivityStart++;
3330            mLruProcessServiceStart++;
3331        }
3332
3333        // If the app is currently using a content provider or service,
3334        // bump those processes as well.
3335        for (int j=app.connections.size()-1; j>=0; j--) {
3336            ConnectionRecord cr = app.connections.valueAt(j);
3337            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3338                    && cr.binding.service.app != null
3339                    && cr.binding.service.app.lruSeq != mLruSeq
3340                    && !cr.binding.service.app.persistent) {
3341                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3342                        "service connection", cr, app);
3343            }
3344        }
3345        for (int j=app.conProviders.size()-1; j>=0; j--) {
3346            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3347            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3348                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3349                        "provider reference", cpr, app);
3350            }
3351        }
3352    }
3353
3354    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3355        if (uid == Process.SYSTEM_UID) {
3356            // The system gets to run in any process.  If there are multiple
3357            // processes with the same uid, just pick the first (this
3358            // should never happen).
3359            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3360            if (procs == null) return null;
3361            final int procCount = procs.size();
3362            for (int i = 0; i < procCount; i++) {
3363                final int procUid = procs.keyAt(i);
3364                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3365                    // Don't use an app process or different user process for system component.
3366                    continue;
3367                }
3368                return procs.valueAt(i);
3369            }
3370        }
3371        ProcessRecord proc = mProcessNames.get(processName, uid);
3372        if (false && proc != null && !keepIfLarge
3373                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3374                && proc.lastCachedPss >= 4000) {
3375            // Turn this condition on to cause killing to happen regularly, for testing.
3376            if (proc.baseProcessTracker != null) {
3377                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3378            }
3379            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3380        } else if (proc != null && !keepIfLarge
3381                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3382                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3383            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3384            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3385                if (proc.baseProcessTracker != null) {
3386                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3387                }
3388                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3389            }
3390        }
3391        return proc;
3392    }
3393
3394    void notifyPackageUse(String packageName, int reason) {
3395        IPackageManager pm = AppGlobals.getPackageManager();
3396        try {
3397            pm.notifyPackageUse(packageName, reason);
3398        } catch (RemoteException e) {
3399        }
3400    }
3401
3402    boolean isNextTransitionForward() {
3403        int transit = mWindowManager.getPendingAppTransition();
3404        return transit == TRANSIT_ACTIVITY_OPEN
3405                || transit == TRANSIT_TASK_OPEN
3406                || transit == TRANSIT_TASK_TO_FRONT;
3407    }
3408
3409    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3410            String processName, String abiOverride, int uid, Runnable crashHandler) {
3411        synchronized(this) {
3412            ApplicationInfo info = new ApplicationInfo();
3413            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3414            // For isolated processes, the former contains the parent's uid and the latter the
3415            // actual uid of the isolated process.
3416            // In the special case introduced by this method (which is, starting an isolated
3417            // process directly from the SystemServer without an actual parent app process) the
3418            // closest thing to a parent's uid is SYSTEM_UID.
3419            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3420            // the |isolated| logic in the ProcessRecord constructor.
3421            info.uid = Process.SYSTEM_UID;
3422            info.processName = processName;
3423            info.className = entryPoint;
3424            info.packageName = "android";
3425            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3426                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3427                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3428                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3429                    crashHandler);
3430            return proc != null ? proc.pid : 0;
3431        }
3432    }
3433
3434    final ProcessRecord startProcessLocked(String processName,
3435            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3436            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3437            boolean isolated, boolean keepIfLarge) {
3438        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3439                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3440                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3441                null /* crashHandler */);
3442    }
3443
3444    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3445            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3446            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3447            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3448        long startTime = SystemClock.elapsedRealtime();
3449        ProcessRecord app;
3450        if (!isolated) {
3451            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3452            checkTime(startTime, "startProcess: after getProcessRecord");
3453
3454            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3455                // If we are in the background, then check to see if this process
3456                // is bad.  If so, we will just silently fail.
3457                if (mAppErrors.isBadProcessLocked(info)) {
3458                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3459                            + "/" + info.processName);
3460                    return null;
3461                }
3462            } else {
3463                // When the user is explicitly starting a process, then clear its
3464                // crash count so that we won't make it bad until they see at
3465                // least one crash dialog again, and make the process good again
3466                // if it had been bad.
3467                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3468                        + "/" + info.processName);
3469                mAppErrors.resetProcessCrashTimeLocked(info);
3470                if (mAppErrors.isBadProcessLocked(info)) {
3471                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3472                            UserHandle.getUserId(info.uid), info.uid,
3473                            info.processName);
3474                    mAppErrors.clearBadProcessLocked(info);
3475                    if (app != null) {
3476                        app.bad = false;
3477                    }
3478                }
3479            }
3480        } else {
3481            // If this is an isolated process, it can't re-use an existing process.
3482            app = null;
3483        }
3484
3485        // app launch boost for big.little configurations
3486        // use cpusets to migrate freshly launched tasks to big cores
3487        synchronized(ActivityManagerService.this) {
3488            nativeMigrateToBoost();
3489            mIsBoosted = true;
3490            mBoostStartTime = SystemClock.uptimeMillis();
3491            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3492            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3493        }
3494
3495        // We don't have to do anything more if:
3496        // (1) There is an existing application record; and
3497        // (2) The caller doesn't think it is dead, OR there is no thread
3498        //     object attached to it so we know it couldn't have crashed; and
3499        // (3) There is a pid assigned to it, so it is either starting or
3500        //     already running.
3501        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3502                + " app=" + app + " knownToBeDead=" + knownToBeDead
3503                + " thread=" + (app != null ? app.thread : null)
3504                + " pid=" + (app != null ? app.pid : -1));
3505        if (app != null && app.pid > 0) {
3506            if (!knownToBeDead || app.thread == null) {
3507                // We already have the app running, or are waiting for it to
3508                // come up (we have a pid but not yet its thread), so keep it.
3509                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3510                // If this is a new package in the process, add the package to the list
3511                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3512                checkTime(startTime, "startProcess: done, added package to proc");
3513                return app;
3514            }
3515
3516            // An application record is attached to a previous process,
3517            // clean it up now.
3518            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3519            checkTime(startTime, "startProcess: bad proc running, killing");
3520            killProcessGroup(app.uid, app.pid);
3521            handleAppDiedLocked(app, true, true);
3522            checkTime(startTime, "startProcess: done killing old proc");
3523        }
3524
3525        String hostingNameStr = hostingName != null
3526                ? hostingName.flattenToShortString() : null;
3527
3528        if (app == null) {
3529            checkTime(startTime, "startProcess: creating new process record");
3530            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3531            if (app == null) {
3532                Slog.w(TAG, "Failed making new process record for "
3533                        + processName + "/" + info.uid + " isolated=" + isolated);
3534                return null;
3535            }
3536            app.crashHandler = crashHandler;
3537            checkTime(startTime, "startProcess: done creating new process record");
3538        } else {
3539            // If this is a new package in the process, add the package to the list
3540            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3541            checkTime(startTime, "startProcess: added package to existing proc");
3542        }
3543
3544        // If the system is not ready yet, then hold off on starting this
3545        // process until it is.
3546        if (!mProcessesReady
3547                && !isAllowedWhileBooting(info)
3548                && !allowWhileBooting) {
3549            if (!mProcessesOnHold.contains(app)) {
3550                mProcessesOnHold.add(app);
3551            }
3552            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3553                    "System not ready, putting on hold: " + app);
3554            checkTime(startTime, "startProcess: returning with proc on hold");
3555            return app;
3556        }
3557
3558        checkTime(startTime, "startProcess: stepping in to startProcess");
3559        startProcessLocked(
3560                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3561        checkTime(startTime, "startProcess: done starting proc!");
3562        return (app.pid != 0) ? app : null;
3563    }
3564
3565    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3566        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3567    }
3568
3569    private final void startProcessLocked(ProcessRecord app,
3570            String hostingType, String hostingNameStr) {
3571        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3572                null /* entryPoint */, null /* entryPointArgs */);
3573    }
3574
3575    private final void startProcessLocked(ProcessRecord app, String hostingType,
3576            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3577        long startTime = SystemClock.elapsedRealtime();
3578        if (app.pid > 0 && app.pid != MY_PID) {
3579            checkTime(startTime, "startProcess: removing from pids map");
3580            synchronized (mPidsSelfLocked) {
3581                mPidsSelfLocked.remove(app.pid);
3582                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3583            }
3584            checkTime(startTime, "startProcess: done removing from pids map");
3585            app.setPid(0);
3586        }
3587
3588        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3589                "startProcessLocked removing on hold: " + app);
3590        mProcessesOnHold.remove(app);
3591
3592        checkTime(startTime, "startProcess: starting to update cpu stats");
3593        updateCpuStats();
3594        checkTime(startTime, "startProcess: done updating cpu stats");
3595
3596        try {
3597            try {
3598                final int userId = UserHandle.getUserId(app.uid);
3599                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3600            } catch (RemoteException e) {
3601                throw e.rethrowAsRuntimeException();
3602            }
3603
3604            int uid = app.uid;
3605            int[] gids = null;
3606            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3607            if (!app.isolated) {
3608                int[] permGids = null;
3609                try {
3610                    checkTime(startTime, "startProcess: getting gids from package manager");
3611                    final IPackageManager pm = AppGlobals.getPackageManager();
3612                    permGids = pm.getPackageGids(app.info.packageName,
3613                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3614                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3615                            MountServiceInternal.class);
3616                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3617                            app.info.packageName);
3618                } catch (RemoteException e) {
3619                    throw e.rethrowAsRuntimeException();
3620                }
3621
3622                /*
3623                 * Add shared application and profile GIDs so applications can share some
3624                 * resources like shared libraries and access user-wide resources
3625                 */
3626                if (ArrayUtils.isEmpty(permGids)) {
3627                    gids = new int[2];
3628                } else {
3629                    gids = new int[permGids.length + 2];
3630                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3631                }
3632                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3633                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3634            }
3635            checkTime(startTime, "startProcess: building args");
3636            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3637                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3638                        && mTopComponent != null
3639                        && app.processName.equals(mTopComponent.getPackageName())) {
3640                    uid = 0;
3641                }
3642                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3643                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3644                    uid = 0;
3645                }
3646            }
3647            int debugFlags = 0;
3648            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3649                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3650                // Also turn on CheckJNI for debuggable apps. It's quite
3651                // awkward to turn on otherwise.
3652                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3653            }
3654            // Run the app in safe mode if its manifest requests so or the
3655            // system is booted in safe mode.
3656            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3657                mSafeMode == true) {
3658                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3659            }
3660            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3661                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3662            }
3663            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3664            if ("true".equals(genDebugInfoProperty)) {
3665                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3666            }
3667            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3668                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3669            }
3670            if ("1".equals(SystemProperties.get("debug.assert"))) {
3671                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3672            }
3673            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3674                // Enable all debug flags required by the native debugger.
3675                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3676                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3677                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3678                mNativeDebuggingApp = null;
3679            }
3680
3681            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3682            if (requiredAbi == null) {
3683                requiredAbi = Build.SUPPORTED_ABIS[0];
3684            }
3685
3686            String instructionSet = null;
3687            if (app.info.primaryCpuAbi != null) {
3688                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3689            }
3690
3691            app.gids = gids;
3692            app.requiredAbi = requiredAbi;
3693            app.instructionSet = instructionSet;
3694
3695            // Start the process.  It will either succeed and return a result containing
3696            // the PID of the new process, or else throw a RuntimeException.
3697            boolean isActivityProcess = (entryPoint == null);
3698            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3699            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3700                    app.processName);
3701            checkTime(startTime, "startProcess: asking zygote to start proc");
3702            Process.ProcessStartResult startResult = Process.start(entryPoint,
3703                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3704                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3705                    app.info.dataDir, entryPointArgs);
3706            checkTime(startTime, "startProcess: returned from zygote!");
3707            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3708
3709            if (app.isolated) {
3710                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3711            }
3712            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3713            checkTime(startTime, "startProcess: done updating battery stats");
3714
3715            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3716                    UserHandle.getUserId(uid), startResult.pid, uid,
3717                    app.processName, hostingType,
3718                    hostingNameStr != null ? hostingNameStr : "");
3719
3720            try {
3721                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3722                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3723            } catch (RemoteException ex) {
3724                // Ignore
3725            }
3726
3727            if (app.persistent) {
3728                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3729            }
3730
3731            checkTime(startTime, "startProcess: building log message");
3732            StringBuilder buf = mStringBuilder;
3733            buf.setLength(0);
3734            buf.append("Start proc ");
3735            buf.append(startResult.pid);
3736            buf.append(':');
3737            buf.append(app.processName);
3738            buf.append('/');
3739            UserHandle.formatUid(buf, uid);
3740            if (!isActivityProcess) {
3741                buf.append(" [");
3742                buf.append(entryPoint);
3743                buf.append("]");
3744            }
3745            buf.append(" for ");
3746            buf.append(hostingType);
3747            if (hostingNameStr != null) {
3748                buf.append(" ");
3749                buf.append(hostingNameStr);
3750            }
3751            Slog.i(TAG, buf.toString());
3752            app.setPid(startResult.pid);
3753            app.usingWrapper = startResult.usingWrapper;
3754            app.removed = false;
3755            app.killed = false;
3756            app.killedByAm = false;
3757            checkTime(startTime, "startProcess: starting to update pids map");
3758            synchronized (mPidsSelfLocked) {
3759                this.mPidsSelfLocked.put(startResult.pid, app);
3760                if (isActivityProcess) {
3761                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3762                    msg.obj = app;
3763                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3764                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3765                }
3766            }
3767            checkTime(startTime, "startProcess: done updating pids map");
3768        } catch (RuntimeException e) {
3769            Slog.e(TAG, "Failure starting process " + app.processName, e);
3770
3771            // Something went very wrong while trying to start this process; one
3772            // common case is when the package is frozen due to an active
3773            // upgrade. To recover, clean up any active bookkeeping related to
3774            // starting this process. (We already invoked this method once when
3775            // the package was initially frozen through KILL_APPLICATION_MSG, so
3776            // it doesn't hurt to use it again.)
3777            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3778                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3779        }
3780    }
3781
3782    void updateUsageStats(ActivityRecord component, boolean resumed) {
3783        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3784                "updateUsageStats: comp=" + component + "res=" + resumed);
3785        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3786        if (resumed) {
3787            if (mUsageStatsService != null) {
3788                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3789                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3790            }
3791            synchronized (stats) {
3792                stats.noteActivityResumedLocked(component.app.uid);
3793            }
3794        } else {
3795            if (mUsageStatsService != null) {
3796                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3798            }
3799            synchronized (stats) {
3800                stats.noteActivityPausedLocked(component.app.uid);
3801            }
3802        }
3803    }
3804
3805    Intent getHomeIntent() {
3806        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3807        intent.setComponent(mTopComponent);
3808        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3809        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3810            intent.addCategory(Intent.CATEGORY_HOME);
3811        }
3812        return intent;
3813    }
3814
3815    boolean startHomeActivityLocked(int userId, String reason) {
3816        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3817                && mTopAction == null) {
3818            // We are running in factory test mode, but unable to find
3819            // the factory test app, so just sit around displaying the
3820            // error message and don't try to start anything.
3821            return false;
3822        }
3823        Intent intent = getHomeIntent();
3824        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3825        if (aInfo != null) {
3826            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3827            // Don't do this if the home app is currently being
3828            // instrumented.
3829            aInfo = new ActivityInfo(aInfo);
3830            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3831            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3832                    aInfo.applicationInfo.uid, true);
3833            if (app == null || app.instrumentationClass == null) {
3834                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3835                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3836            }
3837        } else {
3838            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3839        }
3840
3841        return true;
3842    }
3843
3844    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3845        ActivityInfo ai = null;
3846        ComponentName comp = intent.getComponent();
3847        try {
3848            if (comp != null) {
3849                // Factory test.
3850                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3851            } else {
3852                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3853                        intent,
3854                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3855                        flags, userId);
3856
3857                if (info != null) {
3858                    ai = info.activityInfo;
3859                }
3860            }
3861        } catch (RemoteException e) {
3862            // ignore
3863        }
3864
3865        return ai;
3866    }
3867
3868    /**
3869     * Starts the "new version setup screen" if appropriate.
3870     */
3871    void startSetupActivityLocked() {
3872        // Only do this once per boot.
3873        if (mCheckedForSetup) {
3874            return;
3875        }
3876
3877        // We will show this screen if the current one is a different
3878        // version than the last one shown, and we are not running in
3879        // low-level factory test mode.
3880        final ContentResolver resolver = mContext.getContentResolver();
3881        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3882                Settings.Global.getInt(resolver,
3883                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3884            mCheckedForSetup = true;
3885
3886            // See if we should be showing the platform update setup UI.
3887            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3888            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3889                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3890            if (!ris.isEmpty()) {
3891                final ResolveInfo ri = ris.get(0);
3892                String vers = ri.activityInfo.metaData != null
3893                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3894                        : null;
3895                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3896                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3897                            Intent.METADATA_SETUP_VERSION);
3898                }
3899                String lastVers = Settings.Secure.getString(
3900                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3901                if (vers != null && !vers.equals(lastVers)) {
3902                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3903                    intent.setComponent(new ComponentName(
3904                            ri.activityInfo.packageName, ri.activityInfo.name));
3905                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3906                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3907                            null, 0, 0, 0, null, false, false, null, null, null);
3908                }
3909            }
3910        }
3911    }
3912
3913    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3914        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3915    }
3916
3917    void enforceNotIsolatedCaller(String caller) {
3918        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3919            throw new SecurityException("Isolated process not allowed to call " + caller);
3920        }
3921    }
3922
3923    void enforceShellRestriction(String restriction, int userHandle) {
3924        if (Binder.getCallingUid() == Process.SHELL_UID) {
3925            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3926                throw new SecurityException("Shell does not have permission to access user "
3927                        + userHandle);
3928            }
3929        }
3930    }
3931
3932    @Override
3933    public int getFrontActivityScreenCompatMode() {
3934        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3935        synchronized (this) {
3936            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3937        }
3938    }
3939
3940    @Override
3941    public void setFrontActivityScreenCompatMode(int mode) {
3942        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3943                "setFrontActivityScreenCompatMode");
3944        synchronized (this) {
3945            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3946        }
3947    }
3948
3949    @Override
3950    public int getPackageScreenCompatMode(String packageName) {
3951        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3952        synchronized (this) {
3953            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3954        }
3955    }
3956
3957    @Override
3958    public void setPackageScreenCompatMode(String packageName, int mode) {
3959        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3960                "setPackageScreenCompatMode");
3961        synchronized (this) {
3962            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3963        }
3964    }
3965
3966    @Override
3967    public boolean getPackageAskScreenCompat(String packageName) {
3968        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3969        synchronized (this) {
3970            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3971        }
3972    }
3973
3974    @Override
3975    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3976        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977                "setPackageAskScreenCompat");
3978        synchronized (this) {
3979            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3980        }
3981    }
3982
3983    private boolean hasUsageStatsPermission(String callingPackage) {
3984        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3985                Binder.getCallingUid(), callingPackage);
3986        if (mode == AppOpsManager.MODE_DEFAULT) {
3987            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3988                    == PackageManager.PERMISSION_GRANTED;
3989        }
3990        return mode == AppOpsManager.MODE_ALLOWED;
3991    }
3992
3993    @Override
3994    public int getPackageProcessState(String packageName, String callingPackage) {
3995        if (!hasUsageStatsPermission(callingPackage)) {
3996            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3997                    "getPackageProcessState");
3998        }
3999
4000        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4001        synchronized (this) {
4002            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003                final ProcessRecord proc = mLruProcesses.get(i);
4004                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4005                        || procState > proc.setProcState) {
4006                    boolean found = false;
4007                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4008                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4009                            procState = proc.setProcState;
4010                            found = true;
4011                        }
4012                    }
4013                    if (proc.pkgDeps != null && !found) {
4014                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4015                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4016                                procState = proc.setProcState;
4017                                break;
4018                            }
4019                        }
4020                    }
4021                }
4022            }
4023        }
4024        return procState;
4025    }
4026
4027    @Override
4028    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4029        synchronized (this) {
4030            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4031            if (app == null) {
4032                return false;
4033            }
4034            if (app.trimMemoryLevel < level && app.thread != null &&
4035                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4036                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4037                try {
4038                    app.thread.scheduleTrimMemory(level);
4039                    app.trimMemoryLevel = level;
4040                    return true;
4041                } catch (RemoteException e) {
4042                    // Fallthrough to failure case.
4043                }
4044            }
4045        }
4046        return false;
4047    }
4048
4049    private void dispatchProcessesChanged() {
4050        int N;
4051        synchronized (this) {
4052            N = mPendingProcessChanges.size();
4053            if (mActiveProcessChanges.length < N) {
4054                mActiveProcessChanges = new ProcessChangeItem[N];
4055            }
4056            mPendingProcessChanges.toArray(mActiveProcessChanges);
4057            mPendingProcessChanges.clear();
4058            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059                    "*** Delivering " + N + " process changes");
4060        }
4061
4062        int i = mProcessObservers.beginBroadcast();
4063        while (i > 0) {
4064            i--;
4065            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066            if (observer != null) {
4067                try {
4068                    for (int j=0; j<N; j++) {
4069                        ProcessChangeItem item = mActiveProcessChanges[j];
4070                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073                                    + item.uid + ": " + item.foregroundActivities);
4074                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075                                    item.foregroundActivities);
4076                        }
4077                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080                                    + ": " + item.processState);
4081                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4082                        }
4083                    }
4084                } catch (RemoteException e) {
4085                }
4086            }
4087        }
4088        mProcessObservers.finishBroadcast();
4089
4090        synchronized (this) {
4091            for (int j=0; j<N; j++) {
4092                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4093            }
4094        }
4095    }
4096
4097    private void dispatchProcessDied(int pid, int uid) {
4098        int i = mProcessObservers.beginBroadcast();
4099        while (i > 0) {
4100            i--;
4101            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102            if (observer != null) {
4103                try {
4104                    observer.onProcessDied(pid, uid);
4105                } catch (RemoteException e) {
4106                }
4107            }
4108        }
4109        mProcessObservers.finishBroadcast();
4110    }
4111
4112    private void dispatchUidsChanged() {
4113        int N;
4114        synchronized (this) {
4115            N = mPendingUidChanges.size();
4116            if (mActiveUidChanges.length < N) {
4117                mActiveUidChanges = new UidRecord.ChangeItem[N];
4118            }
4119            for (int i=0; i<N; i++) {
4120                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121                mActiveUidChanges[i] = change;
4122                if (change.uidRecord != null) {
4123                    change.uidRecord.pendingChange = null;
4124                    change.uidRecord = null;
4125                }
4126            }
4127            mPendingUidChanges.clear();
4128            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                    "*** Delivering " + N + " uid changes");
4130        }
4131
4132        if (mLocalPowerManager != null) {
4133            for (int j=0; j<N; j++) {
4134                UidRecord.ChangeItem item = mActiveUidChanges[j];
4135                if (item.change == UidRecord.CHANGE_GONE
4136                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4137                    mLocalPowerManager.uidGone(item.uid);
4138                } else {
4139                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4140                }
4141            }
4142        }
4143
4144        int i = mUidObservers.beginBroadcast();
4145        while (i > 0) {
4146            i--;
4147            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4148            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4149            if (observer != null) {
4150                try {
4151                    for (int j=0; j<N; j++) {
4152                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4153                        final int change = item.change;
4154                        UidRecord validateUid = null;
4155                        if (VALIDATE_UID_STATES && i == 0) {
4156                            validateUid = mValidateUids.get(item.uid);
4157                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4158                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4159                                validateUid = new UidRecord(item.uid);
4160                                mValidateUids.put(item.uid, validateUid);
4161                            }
4162                        }
4163                        if (change == UidRecord.CHANGE_IDLE
4164                                || change == UidRecord.CHANGE_GONE_IDLE) {
4165                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4166                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167                                        "UID idle uid=" + item.uid);
4168                                observer.onUidIdle(item.uid);
4169                            }
4170                            if (VALIDATE_UID_STATES && i == 0) {
4171                                if (validateUid != null) {
4172                                    validateUid.idle = true;
4173                                }
4174                            }
4175                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4176                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4177                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178                                        "UID active uid=" + item.uid);
4179                                observer.onUidActive(item.uid);
4180                            }
4181                            if (VALIDATE_UID_STATES && i == 0) {
4182                                validateUid.idle = false;
4183                            }
4184                        }
4185                        if (change == UidRecord.CHANGE_GONE
4186                                || change == UidRecord.CHANGE_GONE_IDLE) {
4187                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4188                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4189                                        "UID gone uid=" + item.uid);
4190                                observer.onUidGone(item.uid);
4191                            }
4192                            if (VALIDATE_UID_STATES && i == 0) {
4193                                if (validateUid != null) {
4194                                    mValidateUids.remove(item.uid);
4195                                }
4196                            }
4197                        } else {
4198                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4199                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200                                        "UID CHANGED uid=" + item.uid
4201                                                + ": " + item.processState);
4202                                observer.onUidStateChanged(item.uid, item.processState);
4203                            }
4204                            if (VALIDATE_UID_STATES && i == 0) {
4205                                validateUid.curProcState = validateUid.setProcState
4206                                        = item.processState;
4207                            }
4208                        }
4209                    }
4210                } catch (RemoteException e) {
4211                }
4212            }
4213        }
4214        mUidObservers.finishBroadcast();
4215
4216        synchronized (this) {
4217            for (int j=0; j<N; j++) {
4218                mAvailUidChanges.add(mActiveUidChanges[j]);
4219            }
4220        }
4221    }
4222
4223    @Override
4224    public final int startActivity(IApplicationThread caller, String callingPackage,
4225            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4226            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4227        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4228                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4229                UserHandle.getCallingUserId());
4230    }
4231
4232    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4233        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4234        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4235                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4236                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4237
4238        // TODO: Switch to user app stacks here.
4239        String mimeType = intent.getType();
4240        final Uri data = intent.getData();
4241        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4242            mimeType = getProviderMimeType(data, userId);
4243        }
4244        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4245
4246        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4247        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4248                null, 0, 0, null, null, null, null, false, userId, container, null);
4249    }
4250
4251    @Override
4252    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4253            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4254            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4255        enforceNotIsolatedCaller("startActivity");
4256        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4257                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4258        // TODO: Switch to user app stacks here.
4259        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4260                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4261                profilerInfo, null, null, bOptions, false, userId, null, null);
4262    }
4263
4264    @Override
4265    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4268            int userId) {
4269
4270        // This is very dangerous -- it allows you to perform a start activity (including
4271        // permission grants) as any app that may launch one of your own activities.  So
4272        // we will only allow this to be done from activities that are part of the core framework,
4273        // and then only when they are running as the system.
4274        final ActivityRecord sourceRecord;
4275        final int targetUid;
4276        final String targetPackage;
4277        synchronized (this) {
4278            if (resultTo == null) {
4279                throw new SecurityException("Must be called from an activity");
4280            }
4281            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4282            if (sourceRecord == null) {
4283                throw new SecurityException("Called with bad activity token: " + resultTo);
4284            }
4285            if (!sourceRecord.info.packageName.equals("android")) {
4286                throw new SecurityException(
4287                        "Must be called from an activity that is declared in the android package");
4288            }
4289            if (sourceRecord.app == null) {
4290                throw new SecurityException("Called without a process attached to activity");
4291            }
4292            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4293                // This is still okay, as long as this activity is running under the
4294                // uid of the original calling activity.
4295                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4296                    throw new SecurityException(
4297                            "Calling activity in uid " + sourceRecord.app.uid
4298                                    + " must be system uid or original calling uid "
4299                                    + sourceRecord.launchedFromUid);
4300                }
4301            }
4302            if (ignoreTargetSecurity) {
4303                if (intent.getComponent() == null) {
4304                    throw new SecurityException(
4305                            "Component must be specified with ignoreTargetSecurity");
4306                }
4307                if (intent.getSelector() != null) {
4308                    throw new SecurityException(
4309                            "Selector not allowed with ignoreTargetSecurity");
4310                }
4311            }
4312            targetUid = sourceRecord.launchedFromUid;
4313            targetPackage = sourceRecord.launchedFromPackage;
4314        }
4315
4316        if (userId == UserHandle.USER_NULL) {
4317            userId = UserHandle.getUserId(sourceRecord.app.uid);
4318        }
4319
4320        // TODO: Switch to user app stacks here.
4321        try {
4322            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4323                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4324                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4325            return ret;
4326        } catch (SecurityException e) {
4327            // XXX need to figure out how to propagate to original app.
4328            // A SecurityException here is generally actually a fault of the original
4329            // calling activity (such as a fairly granting permissions), so propagate it
4330            // back to them.
4331            /*
4332            StringBuilder msg = new StringBuilder();
4333            msg.append("While launching");
4334            msg.append(intent.toString());
4335            msg.append(": ");
4336            msg.append(e.getMessage());
4337            */
4338            throw e;
4339        }
4340    }
4341
4342    @Override
4343    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4344            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4345            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4346        enforceNotIsolatedCaller("startActivityAndWait");
4347        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4349        WaitResult res = new WaitResult();
4350        // TODO: Switch to user app stacks here.
4351        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4352                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4353                bOptions, false, userId, null, null);
4354        return res;
4355    }
4356
4357    @Override
4358    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360            int startFlags, Configuration config, Bundle bOptions, int userId) {
4361        enforceNotIsolatedCaller("startActivityWithConfig");
4362        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4364        // TODO: Switch to user app stacks here.
4365        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4366                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4367                null, null, config, bOptions, false, userId, null, null);
4368        return ret;
4369    }
4370
4371    @Override
4372    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4373            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4374            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4375            throws TransactionTooLargeException {
4376        enforceNotIsolatedCaller("startActivityIntentSender");
4377        // Refuse possible leaked file descriptors
4378        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4379            throw new IllegalArgumentException("File descriptors passed in Intent");
4380        }
4381
4382        IIntentSender sender = intent.getTarget();
4383        if (!(sender instanceof PendingIntentRecord)) {
4384            throw new IllegalArgumentException("Bad PendingIntent object");
4385        }
4386
4387        PendingIntentRecord pir = (PendingIntentRecord)sender;
4388
4389        synchronized (this) {
4390            // If this is coming from the currently resumed activity, it is
4391            // effectively saying that app switches are allowed at this point.
4392            final ActivityStack stack = getFocusedStack();
4393            if (stack.mResumedActivity != null &&
4394                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4395                mAppSwitchesAllowedTime = 0;
4396            }
4397        }
4398        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4399                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4400        return ret;
4401    }
4402
4403    @Override
4404    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4405            Intent intent, String resolvedType, IVoiceInteractionSession session,
4406            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4407            Bundle bOptions, int userId) {
4408        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4409                != PackageManager.PERMISSION_GRANTED) {
4410            String msg = "Permission Denial: startVoiceActivity() from pid="
4411                    + Binder.getCallingPid()
4412                    + ", uid=" + Binder.getCallingUid()
4413                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4414            Slog.w(TAG, msg);
4415            throw new SecurityException(msg);
4416        }
4417        if (session == null || interactor == null) {
4418            throw new NullPointerException("null session or interactor");
4419        }
4420        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4421                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4422        // TODO: Switch to user app stacks here.
4423        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4424                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4425                null, bOptions, false, userId, null, null);
4426    }
4427
4428    @Override
4429    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4430            throws RemoteException {
4431        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4432        synchronized (this) {
4433            ActivityRecord activity = getFocusedStack().topActivity();
4434            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4435                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4436            }
4437            if (mRunningVoice != null || activity.task.voiceSession != null
4438                    || activity.voiceSession != null) {
4439                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4440                return;
4441            }
4442            if (activity.pendingVoiceInteractionStart) {
4443                Slog.w(TAG, "Pending start of voice interaction already.");
4444                return;
4445            }
4446            activity.pendingVoiceInteractionStart = true;
4447        }
4448        LocalServices.getService(VoiceInteractionManagerInternal.class)
4449                .startLocalVoiceInteraction(callingActivity, options);
4450    }
4451
4452    @Override
4453    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4454        LocalServices.getService(VoiceInteractionManagerInternal.class)
4455                .stopLocalVoiceInteraction(callingActivity);
4456    }
4457
4458    @Override
4459    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4460        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4461                .supportsLocalVoiceInteraction();
4462    }
4463
4464    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4465            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4466        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4467        if (activityToCallback == null) return;
4468        activityToCallback.setVoiceSessionLocked(voiceSession);
4469
4470        // Inform the activity
4471        try {
4472            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4473                    voiceInteractor);
4474            long token = Binder.clearCallingIdentity();
4475            try {
4476                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4477            } finally {
4478                Binder.restoreCallingIdentity(token);
4479            }
4480            // TODO: VI Should we cache the activity so that it's easier to find later
4481            // rather than scan through all the stacks and activities?
4482        } catch (RemoteException re) {
4483            activityToCallback.clearVoiceSessionLocked();
4484            // TODO: VI Should this terminate the voice session?
4485        }
4486    }
4487
4488    @Override
4489    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4490        synchronized (this) {
4491            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4492                if (keepAwake) {
4493                    mVoiceWakeLock.acquire();
4494                } else {
4495                    mVoiceWakeLock.release();
4496                }
4497            }
4498        }
4499    }
4500
4501    @Override
4502    public boolean startNextMatchingActivity(IBinder callingActivity,
4503            Intent intent, Bundle bOptions) {
4504        // Refuse possible leaked file descriptors
4505        if (intent != null && intent.hasFileDescriptors() == true) {
4506            throw new IllegalArgumentException("File descriptors passed in Intent");
4507        }
4508        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4509
4510        synchronized (this) {
4511            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4512            if (r == null) {
4513                ActivityOptions.abort(options);
4514                return false;
4515            }
4516            if (r.app == null || r.app.thread == null) {
4517                // The caller is not running...  d'oh!
4518                ActivityOptions.abort(options);
4519                return false;
4520            }
4521            intent = new Intent(intent);
4522            // The caller is not allowed to change the data.
4523            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4524            // And we are resetting to find the next component...
4525            intent.setComponent(null);
4526
4527            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4528
4529            ActivityInfo aInfo = null;
4530            try {
4531                List<ResolveInfo> resolves =
4532                    AppGlobals.getPackageManager().queryIntentActivities(
4533                            intent, r.resolvedType,
4534                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4535                            UserHandle.getCallingUserId()).getList();
4536
4537                // Look for the original activity in the list...
4538                final int N = resolves != null ? resolves.size() : 0;
4539                for (int i=0; i<N; i++) {
4540                    ResolveInfo rInfo = resolves.get(i);
4541                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4542                            && rInfo.activityInfo.name.equals(r.info.name)) {
4543                        // We found the current one...  the next matching is
4544                        // after it.
4545                        i++;
4546                        if (i<N) {
4547                            aInfo = resolves.get(i).activityInfo;
4548                        }
4549                        if (debug) {
4550                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4551                                    + "/" + r.info.name);
4552                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4553                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4554                        }
4555                        break;
4556                    }
4557                }
4558            } catch (RemoteException e) {
4559            }
4560
4561            if (aInfo == null) {
4562                // Nobody who is next!
4563                ActivityOptions.abort(options);
4564                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4565                return false;
4566            }
4567
4568            intent.setComponent(new ComponentName(
4569                    aInfo.applicationInfo.packageName, aInfo.name));
4570            intent.setFlags(intent.getFlags()&~(
4571                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4572                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4573                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4574                    Intent.FLAG_ACTIVITY_NEW_TASK));
4575
4576            // Okay now we need to start the new activity, replacing the
4577            // currently running activity.  This is a little tricky because
4578            // we want to start the new one as if the current one is finished,
4579            // but not finish the current one first so that there is no flicker.
4580            // And thus...
4581            final boolean wasFinishing = r.finishing;
4582            r.finishing = true;
4583
4584            // Propagate reply information over to the new activity.
4585            final ActivityRecord resultTo = r.resultTo;
4586            final String resultWho = r.resultWho;
4587            final int requestCode = r.requestCode;
4588            r.resultTo = null;
4589            if (resultTo != null) {
4590                resultTo.removeResultsLocked(r, resultWho, requestCode);
4591            }
4592
4593            final long origId = Binder.clearCallingIdentity();
4594            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4595                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4596                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4597                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4598                    false, false, null, null, null);
4599            Binder.restoreCallingIdentity(origId);
4600
4601            r.finishing = wasFinishing;
4602            if (res != ActivityManager.START_SUCCESS) {
4603                return false;
4604            }
4605            return true;
4606        }
4607    }
4608
4609    @Override
4610    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4611        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4612            String msg = "Permission Denial: startActivityFromRecents called without " +
4613                    START_TASKS_FROM_RECENTS;
4614            Slog.w(TAG, msg);
4615            throw new SecurityException(msg);
4616        }
4617        final long origId = Binder.clearCallingIdentity();
4618        try {
4619            synchronized (this) {
4620                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4621            }
4622        } finally {
4623            Binder.restoreCallingIdentity(origId);
4624        }
4625    }
4626
4627    final int startActivityInPackage(int uid, String callingPackage,
4628            Intent intent, String resolvedType, IBinder resultTo,
4629            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4630            IActivityContainer container, TaskRecord inTask) {
4631
4632        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4633                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4634
4635        // TODO: Switch to user app stacks here.
4636        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4637                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4638                null, null, null, bOptions, false, userId, container, inTask);
4639        return ret;
4640    }
4641
4642    @Override
4643    public final int startActivities(IApplicationThread caller, String callingPackage,
4644            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4645            int userId) {
4646        enforceNotIsolatedCaller("startActivities");
4647        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4648                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4649        // TODO: Switch to user app stacks here.
4650        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4651                resolvedTypes, resultTo, bOptions, userId);
4652        return ret;
4653    }
4654
4655    final int startActivitiesInPackage(int uid, String callingPackage,
4656            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4657            Bundle bOptions, int userId) {
4658
4659        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4660                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4661        // TODO: Switch to user app stacks here.
4662        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4663                resultTo, bOptions, userId);
4664        return ret;
4665    }
4666
4667    @Override
4668    public void reportActivityFullyDrawn(IBinder token) {
4669        synchronized (this) {
4670            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671            if (r == null) {
4672                return;
4673            }
4674            r.reportFullyDrawnLocked();
4675        }
4676    }
4677
4678    @Override
4679    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4680        synchronized (this) {
4681            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682            if (r == null) {
4683                return;
4684            }
4685            TaskRecord task = r.task;
4686            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4687                // Fixed screen orientation isn't supported when activities aren't in full screen
4688                // mode.
4689                return;
4690            }
4691            final long origId = Binder.clearCallingIdentity();
4692            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4693            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4694                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4695            if (config != null) {
4696                r.frozenBeforeDestroy = true;
4697                if (!updateConfigurationLocked(config, r, false)) {
4698                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4699                }
4700            }
4701            Binder.restoreCallingIdentity(origId);
4702        }
4703    }
4704
4705    @Override
4706    public int getRequestedOrientation(IBinder token) {
4707        synchronized (this) {
4708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4709            if (r == null) {
4710                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4711            }
4712            return mWindowManager.getAppOrientation(r.appToken);
4713        }
4714    }
4715
4716    /**
4717     * This is the internal entry point for handling Activity.finish().
4718     *
4719     * @param token The Binder token referencing the Activity we want to finish.
4720     * @param resultCode Result code, if any, from this Activity.
4721     * @param resultData Result data (Intent), if any, from this Activity.
4722     * @param finishTask Whether to finish the task associated with this Activity.
4723     *
4724     * @return Returns true if the activity successfully finished, or false if it is still running.
4725     */
4726    @Override
4727    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4728            int finishTask) {
4729        // Refuse possible leaked file descriptors
4730        if (resultData != null && resultData.hasFileDescriptors() == true) {
4731            throw new IllegalArgumentException("File descriptors passed in Intent");
4732        }
4733
4734        synchronized(this) {
4735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736            if (r == null) {
4737                return true;
4738            }
4739            // Keep track of the root activity of the task before we finish it
4740            TaskRecord tr = r.task;
4741            ActivityRecord rootR = tr.getRootActivity();
4742            if (rootR == null) {
4743                Slog.w(TAG, "Finishing task with all activities already finished");
4744            }
4745            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4746            // finish.
4747            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4748                    mStackSupervisor.isLastLockedTask(tr)) {
4749                Slog.i(TAG, "Not finishing task in lock task mode");
4750                mStackSupervisor.showLockTaskToast();
4751                return false;
4752            }
4753            if (mController != null) {
4754                // Find the first activity that is not finishing.
4755                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4756                if (next != null) {
4757                    // ask watcher if this is allowed
4758                    boolean resumeOK = true;
4759                    try {
4760                        resumeOK = mController.activityResuming(next.packageName);
4761                    } catch (RemoteException e) {
4762                        mController = null;
4763                        Watchdog.getInstance().setActivityController(null);
4764                    }
4765
4766                    if (!resumeOK) {
4767                        Slog.i(TAG, "Not finishing activity because controller resumed");
4768                        return false;
4769                    }
4770                }
4771            }
4772            final long origId = Binder.clearCallingIdentity();
4773            try {
4774                boolean res;
4775                final boolean finishWithRootActivity =
4776                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4777                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4778                        || (finishWithRootActivity && r == rootR)) {
4779                    // If requested, remove the task that is associated to this activity only if it
4780                    // was the root activity in the task. The result code and data is ignored
4781                    // because we don't support returning them across task boundaries. Also, to
4782                    // keep backwards compatibility we remove the task from recents when finishing
4783                    // task with root activity.
4784                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4785                    if (!res) {
4786                        Slog.i(TAG, "Removing task failed to finish activity");
4787                    }
4788                } else {
4789                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4790                            resultData, "app-request", true);
4791                    if (!res) {
4792                        Slog.i(TAG, "Failed to finish by app-request");
4793                    }
4794                }
4795                return res;
4796            } finally {
4797                Binder.restoreCallingIdentity(origId);
4798            }
4799        }
4800    }
4801
4802    @Override
4803    public final void finishHeavyWeightApp() {
4804        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805                != PackageManager.PERMISSION_GRANTED) {
4806            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4807                    + Binder.getCallingPid()
4808                    + ", uid=" + Binder.getCallingUid()
4809                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4810            Slog.w(TAG, msg);
4811            throw new SecurityException(msg);
4812        }
4813
4814        synchronized(this) {
4815            if (mHeavyWeightProcess == null) {
4816                return;
4817            }
4818
4819            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4820            for (int i = 0; i < activities.size(); i++) {
4821                ActivityRecord r = activities.get(i);
4822                if (!r.finishing && r.isInStackLocked()) {
4823                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4824                            null, "finish-heavy", true);
4825                }
4826            }
4827
4828            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4829                    mHeavyWeightProcess.userId, 0));
4830            mHeavyWeightProcess = null;
4831        }
4832    }
4833
4834    @Override
4835    public void crashApplication(int uid, int initialPid, String packageName,
4836            String message) {
4837        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4838                != PackageManager.PERMISSION_GRANTED) {
4839            String msg = "Permission Denial: crashApplication() from pid="
4840                    + Binder.getCallingPid()
4841                    + ", uid=" + Binder.getCallingUid()
4842                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4843            Slog.w(TAG, msg);
4844            throw new SecurityException(msg);
4845        }
4846
4847        synchronized(this) {
4848            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4849        }
4850    }
4851
4852    @Override
4853    public final void finishSubActivity(IBinder token, String resultWho,
4854            int requestCode) {
4855        synchronized(this) {
4856            final long origId = Binder.clearCallingIdentity();
4857            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4858            if (r != null) {
4859                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4860            }
4861            Binder.restoreCallingIdentity(origId);
4862        }
4863    }
4864
4865    @Override
4866    public boolean finishActivityAffinity(IBinder token) {
4867        synchronized(this) {
4868            final long origId = Binder.clearCallingIdentity();
4869            try {
4870                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4871                if (r == null) {
4872                    return false;
4873                }
4874
4875                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4876                // can finish.
4877                final TaskRecord task = r.task;
4878                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4879                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4880                    mStackSupervisor.showLockTaskToast();
4881                    return false;
4882                }
4883                return task.stack.finishActivityAffinityLocked(r);
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void finishVoiceTask(IVoiceInteractionSession session) {
4892        synchronized (this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                // TODO: VI Consider treating local voice interactions and voice tasks
4896                // differently here
4897                mStackSupervisor.finishVoiceTask(session);
4898            } finally {
4899                Binder.restoreCallingIdentity(origId);
4900            }
4901        }
4902
4903    }
4904
4905    @Override
4906    public boolean releaseActivityInstance(IBinder token) {
4907        synchronized(this) {
4908            final long origId = Binder.clearCallingIdentity();
4909            try {
4910                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911                if (r == null) {
4912                    return false;
4913                }
4914                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4915            } finally {
4916                Binder.restoreCallingIdentity(origId);
4917            }
4918        }
4919    }
4920
4921    @Override
4922    public void releaseSomeActivities(IApplicationThread appInt) {
4923        synchronized(this) {
4924            final long origId = Binder.clearCallingIdentity();
4925            try {
4926                ProcessRecord app = getRecordForAppLocked(appInt);
4927                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4928            } finally {
4929                Binder.restoreCallingIdentity(origId);
4930            }
4931        }
4932    }
4933
4934    @Override
4935    public boolean willActivityBeVisible(IBinder token) {
4936        synchronized(this) {
4937            ActivityStack stack = ActivityRecord.getStackLocked(token);
4938            if (stack != null) {
4939                return stack.willActivityBeVisibleLocked(token);
4940            }
4941            return false;
4942        }
4943    }
4944
4945    @Override
4946    public void overridePendingTransition(IBinder token, String packageName,
4947            int enterAnim, int exitAnim) {
4948        synchronized(this) {
4949            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4950            if (self == null) {
4951                return;
4952            }
4953
4954            final long origId = Binder.clearCallingIdentity();
4955
4956            if (self.state == ActivityState.RESUMED
4957                    || self.state == ActivityState.PAUSING) {
4958                mWindowManager.overridePendingAppTransition(packageName,
4959                        enterAnim, exitAnim, null);
4960            }
4961
4962            Binder.restoreCallingIdentity(origId);
4963        }
4964    }
4965
4966    /**
4967     * Main function for removing an existing process from the activity manager
4968     * as a result of that process going away.  Clears out all connections
4969     * to the process.
4970     */
4971    private final void handleAppDiedLocked(ProcessRecord app,
4972            boolean restarting, boolean allowRestart) {
4973        int pid = app.pid;
4974        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4975        if (!kept && !restarting) {
4976            removeLruProcessLocked(app);
4977            if (pid > 0) {
4978                ProcessList.remove(pid);
4979            }
4980        }
4981
4982        if (mProfileProc == app) {
4983            clearProfilerLocked();
4984        }
4985
4986        // Remove this application's activities from active lists.
4987        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4988
4989        app.activities.clear();
4990
4991        if (app.instrumentationClass != null) {
4992            Slog.w(TAG, "Crash of app " + app.processName
4993                  + " running instrumentation " + app.instrumentationClass);
4994            Bundle info = new Bundle();
4995            info.putString("shortMsg", "Process crashed.");
4996            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4997        }
4998
4999        if (!restarting && hasVisibleActivities
5000                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5001            // If there was nothing to resume, and we are not already restarting this process, but
5002            // there is a visible activity that is hosted by the process...  then make sure all
5003            // visible activities are running, taking care of restarting this process.
5004            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5005        }
5006    }
5007
5008    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5009        IBinder threadBinder = thread.asBinder();
5010        // Find the application record.
5011        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012            ProcessRecord rec = mLruProcesses.get(i);
5013            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5014                return i;
5015            }
5016        }
5017        return -1;
5018    }
5019
5020    final ProcessRecord getRecordForAppLocked(
5021            IApplicationThread thread) {
5022        if (thread == null) {
5023            return null;
5024        }
5025
5026        int appIndex = getLRURecordIndexForAppLocked(thread);
5027        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5028    }
5029
5030    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5031        // If there are no longer any background processes running,
5032        // and the app that died was not running instrumentation,
5033        // then tell everyone we are now low on memory.
5034        boolean haveBg = false;
5035        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036            ProcessRecord rec = mLruProcesses.get(i);
5037            if (rec.thread != null
5038                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5039                haveBg = true;
5040                break;
5041            }
5042        }
5043
5044        if (!haveBg) {
5045            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5046            if (doReport) {
5047                long now = SystemClock.uptimeMillis();
5048                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5049                    doReport = false;
5050                } else {
5051                    mLastMemUsageReportTime = now;
5052                }
5053            }
5054            final ArrayList<ProcessMemInfo> memInfos
5055                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5056            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5057            long now = SystemClock.uptimeMillis();
5058            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059                ProcessRecord rec = mLruProcesses.get(i);
5060                if (rec == dyingProc || rec.thread == null) {
5061                    continue;
5062                }
5063                if (doReport) {
5064                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5065                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5066                }
5067                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5068                    // The low memory report is overriding any current
5069                    // state for a GC request.  Make sure to do
5070                    // heavy/important/visible/foreground processes first.
5071                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5072                        rec.lastRequestedGc = 0;
5073                    } else {
5074                        rec.lastRequestedGc = rec.lastLowMemory;
5075                    }
5076                    rec.reportLowMemory = true;
5077                    rec.lastLowMemory = now;
5078                    mProcessesToGc.remove(rec);
5079                    addProcessToGcListLocked(rec);
5080                }
5081            }
5082            if (doReport) {
5083                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5084                mHandler.sendMessage(msg);
5085            }
5086            scheduleAppGcsLocked();
5087        }
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app) {
5091       appDiedLocked(app, app.pid, app.thread, false);
5092    }
5093
5094    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5095            boolean fromBinderDied) {
5096        // First check if this ProcessRecord is actually active for the pid.
5097        synchronized (mPidsSelfLocked) {
5098            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5099            if (curProc != app) {
5100                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5101                return;
5102            }
5103        }
5104
5105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5106        synchronized (stats) {
5107            stats.noteProcessDiedLocked(app.info.uid, pid);
5108        }
5109
5110        if (!app.killed) {
5111            if (!fromBinderDied) {
5112                Process.killProcessQuiet(pid);
5113            }
5114            killProcessGroup(app.uid, pid);
5115            app.killed = true;
5116        }
5117
5118        // Clean up already done if the process has been re-started.
5119        if (app.pid == pid && app.thread != null &&
5120                app.thread.asBinder() == thread.asBinder()) {
5121            boolean doLowMem = app.instrumentationClass == null;
5122            boolean doOomAdj = doLowMem;
5123            if (!app.killedByAm) {
5124                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5125                        + ") has died");
5126                mAllowLowerMemLevel = true;
5127            } else {
5128                // Note that we always want to do oom adj to update our state with the
5129                // new number of procs.
5130                mAllowLowerMemLevel = false;
5131                doLowMem = false;
5132            }
5133            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5134            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5135                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5136            handleAppDiedLocked(app, false, true);
5137
5138            if (doOomAdj) {
5139                updateOomAdjLocked();
5140            }
5141            if (doLowMem) {
5142                doLowMemReportIfNeededLocked(app);
5143            }
5144        } else if (app.pid != pid) {
5145            // A new process has already been started.
5146            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5147                    + ") has died and restarted (pid " + app.pid + ").");
5148            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5149        } else if (DEBUG_PROCESSES) {
5150            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5151                    + thread.asBinder());
5152        }
5153    }
5154
5155    /**
5156     * If a stack trace dump file is configured, dump process stack traces.
5157     * @param clearTraces causes the dump file to be erased prior to the new
5158     *    traces being written, if true; when false, the new traces will be
5159     *    appended to any existing file content.
5160     * @param firstPids of dalvik VM processes to dump stack traces for first
5161     * @param lastPids of dalvik VM processes to dump stack traces for last
5162     * @param nativeProcs optional list of native process names to dump stack crawls
5163     * @return file containing stack traces, or null if no dump file is configured
5164     */
5165    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5166            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5167        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5168        if (tracesPath == null || tracesPath.length() == 0) {
5169            return null;
5170        }
5171
5172        File tracesFile = new File(tracesPath);
5173        try {
5174            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5175            tracesFile.createNewFile();
5176            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5177        } catch (IOException e) {
5178            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5179            return null;
5180        }
5181
5182        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5183        return tracesFile;
5184    }
5185
5186    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5188        // Use a FileObserver to detect when traces finish writing.
5189        // The order of traces is considered important to maintain for legibility.
5190        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5191            @Override
5192            public synchronized void onEvent(int event, String path) { notify(); }
5193        };
5194
5195        try {
5196            observer.startWatching();
5197
5198            // First collect all of the stacks of the most important pids.
5199            if (firstPids != null) {
5200                try {
5201                    int num = firstPids.size();
5202                    for (int i = 0; i < num; i++) {
5203                        synchronized (observer) {
5204                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5205                                    + firstPids.get(i));
5206                            final long sime = SystemClock.elapsedRealtime();
5207                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5208                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5209                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5210                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5211                        }
5212                    }
5213                } catch (InterruptedException e) {
5214                    Slog.wtf(TAG, e);
5215                }
5216            }
5217
5218            // Next collect the stacks of the native pids
5219            if (nativeProcs != null) {
5220                int[] pids = Process.getPidsForCommands(nativeProcs);
5221                if (pids != null) {
5222                    for (int pid : pids) {
5223                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5224                        final long sime = SystemClock.elapsedRealtime();
5225                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5226                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5227                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5228                    }
5229                }
5230            }
5231
5232            // Lastly, measure CPU usage.
5233            if (processCpuTracker != null) {
5234                processCpuTracker.init();
5235                System.gc();
5236                processCpuTracker.update();
5237                try {
5238                    synchronized (processCpuTracker) {
5239                        processCpuTracker.wait(500); // measure over 1/2 second.
5240                    }
5241                } catch (InterruptedException e) {
5242                }
5243                processCpuTracker.update();
5244
5245                // We'll take the stack crawls of just the top apps using CPU.
5246                final int N = processCpuTracker.countWorkingStats();
5247                int numProcs = 0;
5248                for (int i=0; i<N && numProcs<5; i++) {
5249                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5250                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5251                        numProcs++;
5252                        try {
5253                            synchronized (observer) {
5254                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5255                                        + stats.pid);
5256                                final long stime = SystemClock.elapsedRealtime();
5257                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5258                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5259                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5260                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5261                            }
5262                        } catch (InterruptedException e) {
5263                            Slog.wtf(TAG, e);
5264                        }
5265                    } else if (DEBUG_ANR) {
5266                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5267                                + stats.pid);
5268                    }
5269                }
5270            }
5271        } finally {
5272            observer.stopWatching();
5273        }
5274    }
5275
5276    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5277        if (true || IS_USER_BUILD) {
5278            return;
5279        }
5280        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5281        if (tracesPath == null || tracesPath.length() == 0) {
5282            return;
5283        }
5284
5285        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5286        StrictMode.allowThreadDiskWrites();
5287        try {
5288            final File tracesFile = new File(tracesPath);
5289            final File tracesDir = tracesFile.getParentFile();
5290            final File tracesTmp = new File(tracesDir, "__tmp__");
5291            try {
5292                if (tracesFile.exists()) {
5293                    tracesTmp.delete();
5294                    tracesFile.renameTo(tracesTmp);
5295                }
5296                StringBuilder sb = new StringBuilder();
5297                Time tobj = new Time();
5298                tobj.set(System.currentTimeMillis());
5299                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5300                sb.append(": ");
5301                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5302                sb.append(" since ");
5303                sb.append(msg);
5304                FileOutputStream fos = new FileOutputStream(tracesFile);
5305                fos.write(sb.toString().getBytes());
5306                if (app == null) {
5307                    fos.write("\n*** No application process!".getBytes());
5308                }
5309                fos.close();
5310                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311            } catch (IOException e) {
5312                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5313                return;
5314            }
5315
5316            if (app != null) {
5317                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5318                firstPids.add(app.pid);
5319                dumpStackTraces(tracesPath, firstPids, null, null, null);
5320            }
5321
5322            File lastTracesFile = null;
5323            File curTracesFile = null;
5324            for (int i=9; i>=0; i--) {
5325                String name = String.format(Locale.US, "slow%02d.txt", i);
5326                curTracesFile = new File(tracesDir, name);
5327                if (curTracesFile.exists()) {
5328                    if (lastTracesFile != null) {
5329                        curTracesFile.renameTo(lastTracesFile);
5330                    } else {
5331                        curTracesFile.delete();
5332                    }
5333                }
5334                lastTracesFile = curTracesFile;
5335            }
5336            tracesFile.renameTo(curTracesFile);
5337            if (tracesTmp.exists()) {
5338                tracesTmp.renameTo(tracesFile);
5339            }
5340        } finally {
5341            StrictMode.setThreadPolicy(oldPolicy);
5342        }
5343    }
5344
5345    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5346        if (!mLaunchWarningShown) {
5347            mLaunchWarningShown = true;
5348            mUiHandler.post(new Runnable() {
5349                @Override
5350                public void run() {
5351                    synchronized (ActivityManagerService.this) {
5352                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5353                        d.show();
5354                        mUiHandler.postDelayed(new Runnable() {
5355                            @Override
5356                            public void run() {
5357                                synchronized (ActivityManagerService.this) {
5358                                    d.dismiss();
5359                                    mLaunchWarningShown = false;
5360                                }
5361                            }
5362                        }, 4000);
5363                    }
5364                }
5365            });
5366        }
5367    }
5368
5369    @Override
5370    public boolean clearApplicationUserData(final String packageName,
5371            final IPackageDataObserver observer, int userId) {
5372        enforceNotIsolatedCaller("clearApplicationUserData");
5373        int uid = Binder.getCallingUid();
5374        int pid = Binder.getCallingPid();
5375        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5376                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5377
5378        final DevicePolicyManagerInternal dpmi = LocalServices
5379                .getService(DevicePolicyManagerInternal.class);
5380        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5381            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5382        }
5383
5384        long callingId = Binder.clearCallingIdentity();
5385        try {
5386            IPackageManager pm = AppGlobals.getPackageManager();
5387            int pkgUid = -1;
5388            synchronized(this) {
5389                try {
5390                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5391                } catch (RemoteException e) {
5392                }
5393                if (pkgUid == -1) {
5394                    Slog.w(TAG, "Invalid packageName: " + packageName);
5395                    if (observer != null) {
5396                        try {
5397                            observer.onRemoveCompleted(packageName, false);
5398                        } catch (RemoteException e) {
5399                            Slog.i(TAG, "Observer no longer exists.");
5400                        }
5401                    }
5402                    return false;
5403                }
5404                if (uid == pkgUid || checkComponentPermission(
5405                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5406                        pid, uid, -1, true)
5407                        == PackageManager.PERMISSION_GRANTED) {
5408                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5409                } else {
5410                    throw new SecurityException("PID " + pid + " does not have permission "
5411                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5412                                    + " of package " + packageName);
5413                }
5414
5415                // Remove all tasks match the cleared application package and user
5416                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5417                    final TaskRecord tr = mRecentTasks.get(i);
5418                    final String taskPackageName =
5419                            tr.getBaseIntent().getComponent().getPackageName();
5420                    if (tr.userId != userId) continue;
5421                    if (!taskPackageName.equals(packageName)) continue;
5422                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5423                }
5424            }
5425
5426            final int pkgUidF = pkgUid;
5427            final int userIdF = userId;
5428            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5429                @Override
5430                public void onRemoveCompleted(String packageName, boolean succeeded)
5431                        throws RemoteException {
5432                    synchronized (ActivityManagerService.this) {
5433                        finishForceStopPackageLocked(packageName, pkgUidF);
5434                    }
5435
5436                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437                            Uri.fromParts("package", packageName, null));
5438                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5439                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5440                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441                            null, null, 0, null, null, null, null, false, false, userIdF);
5442
5443                    if (observer != null) {
5444                        observer.onRemoveCompleted(packageName, succeeded);
5445                    }
5446                }
5447            };
5448
5449            try {
5450                // Clear application user data
5451                pm.clearApplicationUserData(packageName, localObserver, userId);
5452
5453                synchronized(this) {
5454                    // Remove all permissions granted from/to this package
5455                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5456                }
5457
5458                // Remove all zen rules created by this package; revoke it's zen access.
5459                INotificationManager inm = NotificationManager.getService();
5460                inm.removeAutomaticZenRules(packageName);
5461                inm.setNotificationPolicyAccessGranted(packageName, false);
5462
5463            } catch (RemoteException e) {
5464            }
5465        } finally {
5466            Binder.restoreCallingIdentity(callingId);
5467        }
5468        return true;
5469    }
5470
5471    @Override
5472    public void killBackgroundProcesses(final String packageName, int userId) {
5473        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5474                != PackageManager.PERMISSION_GRANTED &&
5475                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5476                        != PackageManager.PERMISSION_GRANTED) {
5477            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5478                    + Binder.getCallingPid()
5479                    + ", uid=" + Binder.getCallingUid()
5480                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5481            Slog.w(TAG, msg);
5482            throw new SecurityException(msg);
5483        }
5484
5485        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5486                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5487        long callingId = Binder.clearCallingIdentity();
5488        try {
5489            IPackageManager pm = AppGlobals.getPackageManager();
5490            synchronized(this) {
5491                int appId = -1;
5492                try {
5493                    appId = UserHandle.getAppId(
5494                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5495                } catch (RemoteException e) {
5496                }
5497                if (appId == -1) {
5498                    Slog.w(TAG, "Invalid packageName: " + packageName);
5499                    return;
5500                }
5501                killPackageProcessesLocked(packageName, appId, userId,
5502                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507    }
5508
5509    @Override
5510    public void killAllBackgroundProcesses() {
5511        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5512                != PackageManager.PERMISSION_GRANTED) {
5513            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5514                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5515                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5516            Slog.w(TAG, msg);
5517            throw new SecurityException(msg);
5518        }
5519
5520        final long callingId = Binder.clearCallingIdentity();
5521        try {
5522            synchronized (this) {
5523                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5524                final int NP = mProcessNames.getMap().size();
5525                for (int ip = 0; ip < NP; ip++) {
5526                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5527                    final int NA = apps.size();
5528                    for (int ia = 0; ia < NA; ia++) {
5529                        final ProcessRecord app = apps.valueAt(ia);
5530                        if (app.persistent) {
5531                            // We don't kill persistent processes.
5532                            continue;
5533                        }
5534                        if (app.removed) {
5535                            procs.add(app);
5536                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5537                            app.removed = true;
5538                            procs.add(app);
5539                        }
5540                    }
5541                }
5542
5543                final int N = procs.size();
5544                for (int i = 0; i < N; i++) {
5545                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5546                }
5547
5548                mAllowLowerMemLevel = true;
5549
5550                updateOomAdjLocked();
5551                doLowMemReportIfNeededLocked(null);
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(callingId);
5555        }
5556    }
5557
5558    /**
5559     * Kills all background processes, except those matching any of the
5560     * specified properties.
5561     *
5562     * @param minTargetSdk the target SDK version at or above which to preserve
5563     *                     processes, or {@code -1} to ignore the target SDK
5564     * @param maxProcState the process state at or below which to preserve
5565     *                     processes, or {@code -1} to ignore the process state
5566     */
5567    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5568        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5569                != PackageManager.PERMISSION_GRANTED) {
5570            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5571                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5572                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5573            Slog.w(TAG, msg);
5574            throw new SecurityException(msg);
5575        }
5576
5577        final long callingId = Binder.clearCallingIdentity();
5578        try {
5579            synchronized (this) {
5580                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5581                final int NP = mProcessNames.getMap().size();
5582                for (int ip = 0; ip < NP; ip++) {
5583                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584                    final int NA = apps.size();
5585                    for (int ia = 0; ia < NA; ia++) {
5586                        final ProcessRecord app = apps.valueAt(ia);
5587                        if (app.removed) {
5588                            procs.add(app);
5589                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5590                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5591                            app.removed = true;
5592                            procs.add(app);
5593                        }
5594                    }
5595                }
5596
5597                final int N = procs.size();
5598                for (int i = 0; i < N; i++) {
5599                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5600                }
5601            }
5602        } finally {
5603            Binder.restoreCallingIdentity(callingId);
5604        }
5605    }
5606
5607    @Override
5608    public void forceStopPackage(final String packageName, int userId) {
5609        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5610                != PackageManager.PERMISSION_GRANTED) {
5611            String msg = "Permission Denial: forceStopPackage() from pid="
5612                    + Binder.getCallingPid()
5613                    + ", uid=" + Binder.getCallingUid()
5614                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5615            Slog.w(TAG, msg);
5616            throw new SecurityException(msg);
5617        }
5618        final int callingPid = Binder.getCallingPid();
5619        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5620                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5621        long callingId = Binder.clearCallingIdentity();
5622        try {
5623            IPackageManager pm = AppGlobals.getPackageManager();
5624            synchronized(this) {
5625                int[] users = userId == UserHandle.USER_ALL
5626                        ? mUserController.getUsers() : new int[] { userId };
5627                for (int user : users) {
5628                    int pkgUid = -1;
5629                    try {
5630                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5631                                user);
5632                    } catch (RemoteException e) {
5633                    }
5634                    if (pkgUid == -1) {
5635                        Slog.w(TAG, "Invalid packageName: " + packageName);
5636                        continue;
5637                    }
5638                    try {
5639                        pm.setPackageStoppedState(packageName, true, user);
5640                    } catch (RemoteException e) {
5641                    } catch (IllegalArgumentException e) {
5642                        Slog.w(TAG, "Failed trying to unstop package "
5643                                + packageName + ": " + e);
5644                    }
5645                    if (mUserController.isUserRunningLocked(user, 0)) {
5646                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5647                        finishForceStopPackageLocked(packageName, pkgUid);
5648                    }
5649                }
5650            }
5651        } finally {
5652            Binder.restoreCallingIdentity(callingId);
5653        }
5654    }
5655
5656    @Override
5657    public void addPackageDependency(String packageName) {
5658        synchronized (this) {
5659            int callingPid = Binder.getCallingPid();
5660            if (callingPid == Process.myPid()) {
5661                //  Yeah, um, no.
5662                return;
5663            }
5664            ProcessRecord proc;
5665            synchronized (mPidsSelfLocked) {
5666                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5667            }
5668            if (proc != null) {
5669                if (proc.pkgDeps == null) {
5670                    proc.pkgDeps = new ArraySet<String>(1);
5671                }
5672                proc.pkgDeps.add(packageName);
5673            }
5674        }
5675    }
5676
5677    /*
5678     * The pkg name and app id have to be specified.
5679     */
5680    @Override
5681    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5682        if (pkg == null) {
5683            return;
5684        }
5685        // Make sure the uid is valid.
5686        if (appid < 0) {
5687            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5688            return;
5689        }
5690        int callerUid = Binder.getCallingUid();
5691        // Only the system server can kill an application
5692        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5693            // Post an aysnc message to kill the application
5694            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5695            msg.arg1 = appid;
5696            msg.arg2 = 0;
5697            Bundle bundle = new Bundle();
5698            bundle.putString("pkg", pkg);
5699            bundle.putString("reason", reason);
5700            msg.obj = bundle;
5701            mHandler.sendMessage(msg);
5702        } else {
5703            throw new SecurityException(callerUid + " cannot kill pkg: " +
5704                    pkg);
5705        }
5706    }
5707
5708    @Override
5709    public void closeSystemDialogs(String reason) {
5710        enforceNotIsolatedCaller("closeSystemDialogs");
5711
5712        final int pid = Binder.getCallingPid();
5713        final int uid = Binder.getCallingUid();
5714        final long origId = Binder.clearCallingIdentity();
5715        try {
5716            synchronized (this) {
5717                // Only allow this from foreground processes, so that background
5718                // applications can't abuse it to prevent system UI from being shown.
5719                if (uid >= Process.FIRST_APPLICATION_UID) {
5720                    ProcessRecord proc;
5721                    synchronized (mPidsSelfLocked) {
5722                        proc = mPidsSelfLocked.get(pid);
5723                    }
5724                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5725                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5726                                + " from background process " + proc);
5727                        return;
5728                    }
5729                }
5730                closeSystemDialogsLocked(reason);
5731            }
5732        } finally {
5733            Binder.restoreCallingIdentity(origId);
5734        }
5735    }
5736
5737    void closeSystemDialogsLocked(String reason) {
5738        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5740                | Intent.FLAG_RECEIVER_FOREGROUND);
5741        if (reason != null) {
5742            intent.putExtra("reason", reason);
5743        }
5744        mWindowManager.closeSystemDialogs(reason);
5745
5746        mStackSupervisor.closeSystemDialogsLocked();
5747
5748        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5749                AppOpsManager.OP_NONE, null, false, false,
5750                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5751    }
5752
5753    @Override
5754    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5755        enforceNotIsolatedCaller("getProcessMemoryInfo");
5756        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5757        for (int i=pids.length-1; i>=0; i--) {
5758            ProcessRecord proc;
5759            int oomAdj;
5760            synchronized (this) {
5761                synchronized (mPidsSelfLocked) {
5762                    proc = mPidsSelfLocked.get(pids[i]);
5763                    oomAdj = proc != null ? proc.setAdj : 0;
5764                }
5765            }
5766            infos[i] = new Debug.MemoryInfo();
5767            Debug.getMemoryInfo(pids[i], infos[i]);
5768            if (proc != null) {
5769                synchronized (this) {
5770                    if (proc.thread != null && proc.setAdj == oomAdj) {
5771                        // Record this for posterity if the process has been stable.
5772                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5773                                infos[i].getTotalUss(), false, proc.pkgList);
5774                    }
5775                }
5776            }
5777        }
5778        return infos;
5779    }
5780
5781    @Override
5782    public long[] getProcessPss(int[] pids) {
5783        enforceNotIsolatedCaller("getProcessPss");
5784        long[] pss = new long[pids.length];
5785        for (int i=pids.length-1; i>=0; i--) {
5786            ProcessRecord proc;
5787            int oomAdj;
5788            synchronized (this) {
5789                synchronized (mPidsSelfLocked) {
5790                    proc = mPidsSelfLocked.get(pids[i]);
5791                    oomAdj = proc != null ? proc.setAdj : 0;
5792                }
5793            }
5794            long[] tmpUss = new long[1];
5795            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5796            if (proc != null) {
5797                synchronized (this) {
5798                    if (proc.thread != null && proc.setAdj == oomAdj) {
5799                        // Record this for posterity if the process has been stable.
5800                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5801                    }
5802                }
5803            }
5804        }
5805        return pss;
5806    }
5807
5808    @Override
5809    public void killApplicationProcess(String processName, int uid) {
5810        if (processName == null) {
5811            return;
5812        }
5813
5814        int callerUid = Binder.getCallingUid();
5815        // Only the system server can kill an application
5816        if (callerUid == Process.SYSTEM_UID) {
5817            synchronized (this) {
5818                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5819                if (app != null && app.thread != null) {
5820                    try {
5821                        app.thread.scheduleSuicide();
5822                    } catch (RemoteException e) {
5823                        // If the other end already died, then our work here is done.
5824                    }
5825                } else {
5826                    Slog.w(TAG, "Process/uid not found attempting kill of "
5827                            + processName + " / " + uid);
5828                }
5829            }
5830        } else {
5831            throw new SecurityException(callerUid + " cannot kill app process: " +
5832                    processName);
5833        }
5834    }
5835
5836    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5837        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5838                false, true, false, false, UserHandle.getUserId(uid), reason);
5839    }
5840
5841    private void finishForceStopPackageLocked(final String packageName, int uid) {
5842        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5843                Uri.fromParts("package", packageName, null));
5844        if (!mProcessesReady) {
5845            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5846                    | Intent.FLAG_RECEIVER_FOREGROUND);
5847        }
5848        intent.putExtra(Intent.EXTRA_UID, uid);
5849        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5850        broadcastIntentLocked(null, null, intent,
5851                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5852                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5853    }
5854
5855
5856    private final boolean killPackageProcessesLocked(String packageName, int appId,
5857            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5858            boolean doit, boolean evenPersistent, String reason) {
5859        ArrayList<ProcessRecord> procs = new ArrayList<>();
5860
5861        // Remove all processes this package may have touched: all with the
5862        // same UID (except for the system or root user), and all whose name
5863        // matches the package name.
5864        final int NP = mProcessNames.getMap().size();
5865        for (int ip=0; ip<NP; ip++) {
5866            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5867            final int NA = apps.size();
5868            for (int ia=0; ia<NA; ia++) {
5869                ProcessRecord app = apps.valueAt(ia);
5870                if (app.persistent && !evenPersistent) {
5871                    // we don't kill persistent processes
5872                    continue;
5873                }
5874                if (app.removed) {
5875                    if (doit) {
5876                        procs.add(app);
5877                    }
5878                    continue;
5879                }
5880
5881                // Skip process if it doesn't meet our oom adj requirement.
5882                if (app.setAdj < minOomAdj) {
5883                    continue;
5884                }
5885
5886                // If no package is specified, we call all processes under the
5887                // give user id.
5888                if (packageName == null) {
5889                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5890                        continue;
5891                    }
5892                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5893                        continue;
5894                    }
5895                // Package has been specified, we want to hit all processes
5896                // that match it.  We need to qualify this by the processes
5897                // that are running under the specified app and user ID.
5898                } else {
5899                    final boolean isDep = app.pkgDeps != null
5900                            && app.pkgDeps.contains(packageName);
5901                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5902                        continue;
5903                    }
5904                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5905                        continue;
5906                    }
5907                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5908                        continue;
5909                    }
5910                }
5911
5912                // Process has passed all conditions, kill it!
5913                if (!doit) {
5914                    return true;
5915                }
5916                app.removed = true;
5917                procs.add(app);
5918            }
5919        }
5920
5921        int N = procs.size();
5922        for (int i=0; i<N; i++) {
5923            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5924        }
5925        updateOomAdjLocked();
5926        return N > 0;
5927    }
5928
5929    private void cleanupDisabledPackageComponentsLocked(
5930            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5931
5932        Set<String> disabledClasses = null;
5933        boolean packageDisabled = false;
5934        IPackageManager pm = AppGlobals.getPackageManager();
5935
5936        if (changedClasses == null) {
5937            // Nothing changed...
5938            return;
5939        }
5940
5941        // Determine enable/disable state of the package and its components.
5942        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5943        for (int i = changedClasses.length - 1; i >= 0; i--) {
5944            final String changedClass = changedClasses[i];
5945
5946            if (changedClass.equals(packageName)) {
5947                try {
5948                    // Entire package setting changed
5949                    enabled = pm.getApplicationEnabledSetting(packageName,
5950                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5951                } catch (Exception e) {
5952                    // No such package/component; probably racing with uninstall.  In any
5953                    // event it means we have nothing further to do here.
5954                    return;
5955                }
5956                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5957                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5958                if (packageDisabled) {
5959                    // Entire package is disabled.
5960                    // No need to continue to check component states.
5961                    disabledClasses = null;
5962                    break;
5963                }
5964            } else {
5965                try {
5966                    enabled = pm.getComponentEnabledSetting(
5967                            new ComponentName(packageName, changedClass),
5968                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5969                } catch (Exception e) {
5970                    // As above, probably racing with uninstall.
5971                    return;
5972                }
5973                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5974                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5975                    if (disabledClasses == null) {
5976                        disabledClasses = new ArraySet<>(changedClasses.length);
5977                    }
5978                    disabledClasses.add(changedClass);
5979                }
5980            }
5981        }
5982
5983        if (!packageDisabled && disabledClasses == null) {
5984            // Nothing to do here...
5985            return;
5986        }
5987
5988        // Clean-up disabled activities.
5989        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5990                packageName, disabledClasses, true, false, userId) && mBooted) {
5991            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5992            mStackSupervisor.scheduleIdleLocked();
5993        }
5994
5995        // Clean-up disabled tasks
5996        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5997
5998        // Clean-up disabled services.
5999        mServices.bringDownDisabledPackageServicesLocked(
6000                packageName, disabledClasses, userId, false, killProcess, true);
6001
6002        // Clean-up disabled providers.
6003        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6004        mProviderMap.collectPackageProvidersLocked(
6005                packageName, disabledClasses, true, false, userId, providers);
6006        for (int i = providers.size() - 1; i >= 0; i--) {
6007            removeDyingProviderLocked(null, providers.get(i), true);
6008        }
6009
6010        // Clean-up disabled broadcast receivers.
6011        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6012            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6013                    packageName, disabledClasses, userId, true);
6014        }
6015
6016    }
6017
6018    final boolean clearBroadcastQueueForUserLocked(int userId) {
6019        boolean didSomething = false;
6020        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022                    null, null, userId, true);
6023        }
6024        return didSomething;
6025    }
6026
6027    final boolean forceStopPackageLocked(String packageName, int appId,
6028            boolean callerWillRestart, boolean purgeCache, boolean doit,
6029            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6030        int i;
6031
6032        if (userId == UserHandle.USER_ALL && packageName == null) {
6033            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6034        }
6035
6036        if (appId < 0 && packageName != null) {
6037            try {
6038                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6039                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6040            } catch (RemoteException e) {
6041            }
6042        }
6043
6044        if (doit) {
6045            if (packageName != null) {
6046                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6047                        + " user=" + userId + ": " + reason);
6048            } else {
6049                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6050            }
6051
6052            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6053        }
6054
6055        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6056                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6057                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6058
6059        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6060                packageName, null, doit, evenPersistent, userId)) {
6061            if (!doit) {
6062                return true;
6063            }
6064            didSomething = true;
6065        }
6066
6067        if (mServices.bringDownDisabledPackageServicesLocked(
6068                packageName, null, userId, evenPersistent, true, doit)) {
6069            if (!doit) {
6070                return true;
6071            }
6072            didSomething = true;
6073        }
6074
6075        if (packageName == null) {
6076            // Remove all sticky broadcasts from this user.
6077            mStickyBroadcasts.remove(userId);
6078        }
6079
6080        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6081        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6082                userId, providers)) {
6083            if (!doit) {
6084                return true;
6085            }
6086            didSomething = true;
6087        }
6088        for (i = providers.size() - 1; i >= 0; i--) {
6089            removeDyingProviderLocked(null, providers.get(i), true);
6090        }
6091
6092        // Remove transient permissions granted from/to this package/user
6093        removeUriPermissionsForPackageLocked(packageName, userId, false);
6094
6095        if (doit) {
6096            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6097                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6098                        packageName, null, userId, doit);
6099            }
6100        }
6101
6102        if (packageName == null || uninstalling) {
6103            // Remove pending intents.  For now we only do this when force
6104            // stopping users, because we have some problems when doing this
6105            // for packages -- app widgets are not currently cleaned up for
6106            // such packages, so they can be left with bad pending intents.
6107            if (mIntentSenderRecords.size() > 0) {
6108                Iterator<WeakReference<PendingIntentRecord>> it
6109                        = mIntentSenderRecords.values().iterator();
6110                while (it.hasNext()) {
6111                    WeakReference<PendingIntentRecord> wpir = it.next();
6112                    if (wpir == null) {
6113                        it.remove();
6114                        continue;
6115                    }
6116                    PendingIntentRecord pir = wpir.get();
6117                    if (pir == null) {
6118                        it.remove();
6119                        continue;
6120                    }
6121                    if (packageName == null) {
6122                        // Stopping user, remove all objects for the user.
6123                        if (pir.key.userId != userId) {
6124                            // Not the same user, skip it.
6125                            continue;
6126                        }
6127                    } else {
6128                        if (UserHandle.getAppId(pir.uid) != appId) {
6129                            // Different app id, skip it.
6130                            continue;
6131                        }
6132                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6133                            // Different user, skip it.
6134                            continue;
6135                        }
6136                        if (!pir.key.packageName.equals(packageName)) {
6137                            // Different package, skip it.
6138                            continue;
6139                        }
6140                    }
6141                    if (!doit) {
6142                        return true;
6143                    }
6144                    didSomething = true;
6145                    it.remove();
6146                    pir.canceled = true;
6147                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6148                        pir.key.activity.pendingResults.remove(pir.ref);
6149                    }
6150                }
6151            }
6152        }
6153
6154        if (doit) {
6155            if (purgeCache && packageName != null) {
6156                AttributeCache ac = AttributeCache.instance();
6157                if (ac != null) {
6158                    ac.removePackage(packageName);
6159                }
6160            }
6161            if (mBooted) {
6162                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6163                mStackSupervisor.scheduleIdleLocked();
6164            }
6165        }
6166
6167        return didSomething;
6168    }
6169
6170    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6171        ProcessRecord old = mProcessNames.remove(name, uid);
6172        if (old != null) {
6173            old.uidRecord.numProcs--;
6174            if (old.uidRecord.numProcs == 0) {
6175                // No more processes using this uid, tell clients it is gone.
6176                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6177                        "No more processes in " + old.uidRecord);
6178                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6179                mActiveUids.remove(uid);
6180                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6181            }
6182            old.uidRecord = null;
6183        }
6184        mIsolatedProcesses.remove(uid);
6185        return old;
6186    }
6187
6188    private final void addProcessNameLocked(ProcessRecord proc) {
6189        // We shouldn't already have a process under this name, but just in case we
6190        // need to clean up whatever may be there now.
6191        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6192        if (old == proc && proc.persistent) {
6193            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6194            Slog.w(TAG, "Re-adding persistent process " + proc);
6195        } else if (old != null) {
6196            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6197        }
6198        UidRecord uidRec = mActiveUids.get(proc.uid);
6199        if (uidRec == null) {
6200            uidRec = new UidRecord(proc.uid);
6201            // This is the first appearance of the uid, report it now!
6202            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6203                    "Creating new process uid: " + uidRec);
6204            mActiveUids.put(proc.uid, uidRec);
6205            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6206            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6207        }
6208        proc.uidRecord = uidRec;
6209        uidRec.numProcs++;
6210        mProcessNames.put(proc.processName, proc.uid, proc);
6211        if (proc.isolated) {
6212            mIsolatedProcesses.put(proc.uid, proc);
6213        }
6214    }
6215
6216    boolean removeProcessLocked(ProcessRecord app,
6217            boolean callerWillRestart, boolean allowRestart, String reason) {
6218        final String name = app.processName;
6219        final int uid = app.uid;
6220        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6221            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6222
6223        ProcessRecord old = mProcessNames.get(name, uid);
6224        if (old != app) {
6225            // This process is no longer active, so nothing to do.
6226            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6227            return false;
6228        }
6229        removeProcessNameLocked(name, uid);
6230        if (mHeavyWeightProcess == app) {
6231            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6232                    mHeavyWeightProcess.userId, 0));
6233            mHeavyWeightProcess = null;
6234        }
6235        boolean needRestart = false;
6236        if (app.pid > 0 && app.pid != MY_PID) {
6237            int pid = app.pid;
6238            synchronized (mPidsSelfLocked) {
6239                mPidsSelfLocked.remove(pid);
6240                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6241            }
6242            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6243            if (app.isolated) {
6244                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6245            }
6246            boolean willRestart = false;
6247            if (app.persistent && !app.isolated) {
6248                if (!callerWillRestart) {
6249                    willRestart = true;
6250                } else {
6251                    needRestart = true;
6252                }
6253            }
6254            app.kill(reason, true);
6255            handleAppDiedLocked(app, willRestart, allowRestart);
6256            if (willRestart) {
6257                removeLruProcessLocked(app);
6258                addAppLocked(app.info, false, null /* ABI override */);
6259            }
6260        } else {
6261            mRemovedProcesses.add(app);
6262        }
6263
6264        return needRestart;
6265    }
6266
6267    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6268        cleanupAppInLaunchingProvidersLocked(app, true);
6269        removeProcessLocked(app, false, true, "timeout publishing content providers");
6270    }
6271
6272    private final void processStartTimedOutLocked(ProcessRecord app) {
6273        final int pid = app.pid;
6274        boolean gone = false;
6275        synchronized (mPidsSelfLocked) {
6276            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6277            if (knownApp != null && knownApp.thread == null) {
6278                mPidsSelfLocked.remove(pid);
6279                gone = true;
6280            }
6281        }
6282
6283        if (gone) {
6284            Slog.w(TAG, "Process " + app + " failed to attach");
6285            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6286                    pid, app.uid, app.processName);
6287            removeProcessNameLocked(app.processName, app.uid);
6288            if (mHeavyWeightProcess == app) {
6289                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6290                        mHeavyWeightProcess.userId, 0));
6291                mHeavyWeightProcess = null;
6292            }
6293            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6294            if (app.isolated) {
6295                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6296            }
6297            // Take care of any launching providers waiting for this process.
6298            cleanupAppInLaunchingProvidersLocked(app, true);
6299            // Take care of any services that are waiting for the process.
6300            mServices.processStartTimedOutLocked(app);
6301            app.kill("start timeout", true);
6302            removeLruProcessLocked(app);
6303            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6304                Slog.w(TAG, "Unattached app died before backup, skipping");
6305                try {
6306                    IBackupManager bm = IBackupManager.Stub.asInterface(
6307                            ServiceManager.getService(Context.BACKUP_SERVICE));
6308                    bm.agentDisconnected(app.info.packageName);
6309                } catch (RemoteException e) {
6310                    // Can't happen; the backup manager is local
6311                }
6312            }
6313            if (isPendingBroadcastProcessLocked(pid)) {
6314                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6315                skipPendingBroadcastLocked(pid);
6316            }
6317        } else {
6318            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6319        }
6320    }
6321
6322    private final boolean attachApplicationLocked(IApplicationThread thread,
6323            int pid) {
6324
6325        // Find the application record that is being attached...  either via
6326        // the pid if we are running in multiple processes, or just pull the
6327        // next app record if we are emulating process with anonymous threads.
6328        ProcessRecord app;
6329        if (pid != MY_PID && pid >= 0) {
6330            synchronized (mPidsSelfLocked) {
6331                app = mPidsSelfLocked.get(pid);
6332            }
6333        } else {
6334            app = null;
6335        }
6336
6337        if (app == null) {
6338            Slog.w(TAG, "No pending application record for pid " + pid
6339                    + " (IApplicationThread " + thread + "); dropping process");
6340            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6341            if (pid > 0 && pid != MY_PID) {
6342                Process.killProcessQuiet(pid);
6343                //TODO: killProcessGroup(app.info.uid, pid);
6344            } else {
6345                try {
6346                    thread.scheduleExit();
6347                } catch (Exception e) {
6348                    // Ignore exceptions.
6349                }
6350            }
6351            return false;
6352        }
6353
6354        // If this application record is still attached to a previous
6355        // process, clean it up now.
6356        if (app.thread != null) {
6357            handleAppDiedLocked(app, true, true);
6358        }
6359
6360        // Tell the process all about itself.
6361
6362        if (DEBUG_ALL) Slog.v(
6363                TAG, "Binding process pid " + pid + " to record " + app);
6364
6365        final String processName = app.processName;
6366        try {
6367            AppDeathRecipient adr = new AppDeathRecipient(
6368                    app, pid, thread);
6369            thread.asBinder().linkToDeath(adr, 0);
6370            app.deathRecipient = adr;
6371        } catch (RemoteException e) {
6372            app.resetPackageList(mProcessStats);
6373            startProcessLocked(app, "link fail", processName);
6374            return false;
6375        }
6376
6377        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6378
6379        app.makeActive(thread, mProcessStats);
6380        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6381        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6382        app.forcingToForeground = null;
6383        updateProcessForegroundLocked(app, false, false);
6384        app.hasShownUi = false;
6385        app.debugging = false;
6386        app.cached = false;
6387        app.killedByAm = false;
6388
6389        // We carefully use the same state that PackageManager uses for
6390        // filtering, since we use this flag to decide if we need to install
6391        // providers when user is unlocked later
6392        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6393
6394        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6395
6396        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6397        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6398
6399        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6400            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6401            msg.obj = app;
6402            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6403        }
6404
6405        if (!normalMode) {
6406            Slog.i(TAG, "Launching preboot mode app: " + app);
6407        }
6408
6409        if (DEBUG_ALL) Slog.v(
6410            TAG, "New app record " + app
6411            + " thread=" + thread.asBinder() + " pid=" + pid);
6412        try {
6413            int testMode = IApplicationThread.DEBUG_OFF;
6414            if (mDebugApp != null && mDebugApp.equals(processName)) {
6415                testMode = mWaitForDebugger
6416                    ? IApplicationThread.DEBUG_WAIT
6417                    : IApplicationThread.DEBUG_ON;
6418                app.debugging = true;
6419                if (mDebugTransient) {
6420                    mDebugApp = mOrigDebugApp;
6421                    mWaitForDebugger = mOrigWaitForDebugger;
6422                }
6423            }
6424            String profileFile = app.instrumentationProfileFile;
6425            ParcelFileDescriptor profileFd = null;
6426            int samplingInterval = 0;
6427            boolean profileAutoStop = false;
6428            if (mProfileApp != null && mProfileApp.equals(processName)) {
6429                mProfileProc = app;
6430                profileFile = mProfileFile;
6431                profileFd = mProfileFd;
6432                samplingInterval = mSamplingInterval;
6433                profileAutoStop = mAutoStopProfiler;
6434            }
6435            boolean enableTrackAllocation = false;
6436            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6437                enableTrackAllocation = true;
6438                mTrackAllocationApp = null;
6439            }
6440
6441            // If the app is being launched for restore or full backup, set it up specially
6442            boolean isRestrictedBackupMode = false;
6443            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6444                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6445                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6446                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6447                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6448            }
6449
6450            if (app.instrumentationClass != null) {
6451                notifyPackageUse(app.instrumentationClass.getPackageName(),
6452                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6453            }
6454            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6455                    + processName + " with config " + mConfiguration);
6456            ApplicationInfo appInfo = app.instrumentationInfo != null
6457                    ? app.instrumentationInfo : app.info;
6458            app.compat = compatibilityInfoForPackageLocked(appInfo);
6459            if (profileFd != null) {
6460                profileFd = profileFd.dup();
6461            }
6462            ProfilerInfo profilerInfo = profileFile == null ? null
6463                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6464            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6465                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6466                    app.instrumentationUiAutomationConnection, testMode,
6467                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6468                    isRestrictedBackupMode || !normalMode, app.persistent,
6469                    new Configuration(mConfiguration), app.compat,
6470                    getCommonServicesLocked(app.isolated),
6471                    mCoreSettingsObserver.getCoreSettingsLocked());
6472            updateLruProcessLocked(app, false, null);
6473            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6474        } catch (Exception e) {
6475            // todo: Yikes!  What should we do?  For now we will try to
6476            // start another process, but that could easily get us in
6477            // an infinite loop of restarting processes...
6478            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6479
6480            app.resetPackageList(mProcessStats);
6481            app.unlinkDeathRecipient();
6482            startProcessLocked(app, "bind fail", processName);
6483            return false;
6484        }
6485
6486        // Remove this record from the list of starting applications.
6487        mPersistentStartingProcesses.remove(app);
6488        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6489                "Attach application locked removing on hold: " + app);
6490        mProcessesOnHold.remove(app);
6491
6492        boolean badApp = false;
6493        boolean didSomething = false;
6494
6495        // See if the top visible activity is waiting to run in this process...
6496        if (normalMode) {
6497            try {
6498                if (mStackSupervisor.attachApplicationLocked(app)) {
6499                    didSomething = true;
6500                }
6501            } catch (Exception e) {
6502                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6503                badApp = true;
6504            }
6505        }
6506
6507        // Find any services that should be running in this process...
6508        if (!badApp) {
6509            try {
6510                didSomething |= mServices.attachApplicationLocked(app, processName);
6511            } catch (Exception e) {
6512                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6513                badApp = true;
6514            }
6515        }
6516
6517        // Check if a next-broadcast receiver is in this process...
6518        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6519            try {
6520                didSomething |= sendPendingBroadcastsLocked(app);
6521            } catch (Exception e) {
6522                // If the app died trying to launch the receiver we declare it 'bad'
6523                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6524                badApp = true;
6525            }
6526        }
6527
6528        // Check whether the next backup agent is in this process...
6529        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6530            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6531                    "New app is backup target, launching agent for " + app);
6532            notifyPackageUse(mBackupTarget.appInfo.packageName,
6533                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6534            try {
6535                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6536                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6537                        mBackupTarget.backupMode);
6538            } catch (Exception e) {
6539                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6540                badApp = true;
6541            }
6542        }
6543
6544        if (badApp) {
6545            app.kill("error during init", true);
6546            handleAppDiedLocked(app, false, true);
6547            return false;
6548        }
6549
6550        if (!didSomething) {
6551            updateOomAdjLocked();
6552        }
6553
6554        return true;
6555    }
6556
6557    @Override
6558    public final void attachApplication(IApplicationThread thread) {
6559        synchronized (this) {
6560            int callingPid = Binder.getCallingPid();
6561            final long origId = Binder.clearCallingIdentity();
6562            attachApplicationLocked(thread, callingPid);
6563            Binder.restoreCallingIdentity(origId);
6564        }
6565    }
6566
6567    @Override
6568    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6569        final long origId = Binder.clearCallingIdentity();
6570        synchronized (this) {
6571            ActivityStack stack = ActivityRecord.getStackLocked(token);
6572            if (stack != null) {
6573                ActivityRecord r =
6574                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6575                if (stopProfiling) {
6576                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6577                        try {
6578                            mProfileFd.close();
6579                        } catch (IOException e) {
6580                        }
6581                        clearProfilerLocked();
6582                    }
6583                }
6584            }
6585        }
6586        Binder.restoreCallingIdentity(origId);
6587    }
6588
6589    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6590        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6591                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6592    }
6593
6594    void enableScreenAfterBoot() {
6595        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6596                SystemClock.uptimeMillis());
6597        mWindowManager.enableScreenAfterBoot();
6598
6599        synchronized (this) {
6600            updateEventDispatchingLocked();
6601        }
6602    }
6603
6604    @Override
6605    public void showBootMessage(final CharSequence msg, final boolean always) {
6606        if (Binder.getCallingUid() != Process.myUid()) {
6607            // These days only the core system can call this, so apps can't get in
6608            // the way of what we show about running them.
6609        }
6610        mWindowManager.showBootMessage(msg, always);
6611    }
6612
6613    @Override
6614    public void keyguardWaitingForActivityDrawn() {
6615        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6616        final long token = Binder.clearCallingIdentity();
6617        try {
6618            synchronized (this) {
6619                if (DEBUG_LOCKSCREEN) logLockScreen("");
6620                mWindowManager.keyguardWaitingForActivityDrawn();
6621                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6622                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6623                    updateSleepIfNeededLocked();
6624                }
6625            }
6626        } finally {
6627            Binder.restoreCallingIdentity(token);
6628        }
6629    }
6630
6631    @Override
6632    public void keyguardGoingAway(int flags) {
6633        enforceNotIsolatedCaller("keyguardGoingAway");
6634        final long token = Binder.clearCallingIdentity();
6635        try {
6636            synchronized (this) {
6637                if (DEBUG_LOCKSCREEN) logLockScreen("");
6638                mWindowManager.keyguardGoingAway(flags);
6639                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6640                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6641                    updateSleepIfNeededLocked();
6642
6643                    // Some stack visibility might change (e.g. docked stack)
6644                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6645                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6646                }
6647            }
6648        } finally {
6649            Binder.restoreCallingIdentity(token);
6650        }
6651    }
6652
6653    final void finishBooting() {
6654        synchronized (this) {
6655            if (!mBootAnimationComplete) {
6656                mCallFinishBooting = true;
6657                return;
6658            }
6659            mCallFinishBooting = false;
6660        }
6661
6662        ArraySet<String> completedIsas = new ArraySet<String>();
6663        for (String abi : Build.SUPPORTED_ABIS) {
6664            Process.establishZygoteConnectionForAbi(abi);
6665            final String instructionSet = VMRuntime.getInstructionSet(abi);
6666            if (!completedIsas.contains(instructionSet)) {
6667                try {
6668                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6669                } catch (InstallerException e) {
6670                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6671                            e.getMessage() +")");
6672                }
6673                completedIsas.add(instructionSet);
6674            }
6675        }
6676
6677        IntentFilter pkgFilter = new IntentFilter();
6678        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6679        pkgFilter.addDataScheme("package");
6680        mContext.registerReceiver(new BroadcastReceiver() {
6681            @Override
6682            public void onReceive(Context context, Intent intent) {
6683                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6684                if (pkgs != null) {
6685                    for (String pkg : pkgs) {
6686                        synchronized (ActivityManagerService.this) {
6687                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6688                                    0, "query restart")) {
6689                                setResultCode(Activity.RESULT_OK);
6690                                return;
6691                            }
6692                        }
6693                    }
6694                }
6695            }
6696        }, pkgFilter);
6697
6698        IntentFilter dumpheapFilter = new IntentFilter();
6699        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6700        mContext.registerReceiver(new BroadcastReceiver() {
6701            @Override
6702            public void onReceive(Context context, Intent intent) {
6703                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6704                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6705                } else {
6706                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6707                }
6708            }
6709        }, dumpheapFilter);
6710
6711        // Let system services know.
6712        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6713
6714        synchronized (this) {
6715            // Ensure that any processes we had put on hold are now started
6716            // up.
6717            final int NP = mProcessesOnHold.size();
6718            if (NP > 0) {
6719                ArrayList<ProcessRecord> procs =
6720                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6721                for (int ip=0; ip<NP; ip++) {
6722                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6723                            + procs.get(ip));
6724                    startProcessLocked(procs.get(ip), "on-hold", null);
6725                }
6726            }
6727
6728            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6729                // Start looking for apps that are abusing wake locks.
6730                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6731                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6732                // Tell anyone interested that we are done booting!
6733                SystemProperties.set("sys.boot_completed", "1");
6734
6735                // And trigger dev.bootcomplete if we are not showing encryption progress
6736                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6737                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6738                    SystemProperties.set("dev.bootcomplete", "1");
6739                }
6740                mUserController.sendBootCompletedLocked(
6741                        new IIntentReceiver.Stub() {
6742                            @Override
6743                            public void performReceive(Intent intent, int resultCode,
6744                                    String data, Bundle extras, boolean ordered,
6745                                    boolean sticky, int sendingUser) {
6746                                synchronized (ActivityManagerService.this) {
6747                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6748                                            true, false);
6749                                }
6750                            }
6751                        });
6752                scheduleStartProfilesLocked();
6753            }
6754        }
6755    }
6756
6757    @Override
6758    public void bootAnimationComplete() {
6759        final boolean callFinishBooting;
6760        synchronized (this) {
6761            callFinishBooting = mCallFinishBooting;
6762            mBootAnimationComplete = true;
6763        }
6764        if (callFinishBooting) {
6765            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6766            finishBooting();
6767            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6768        }
6769    }
6770
6771    final void ensureBootCompleted() {
6772        boolean booting;
6773        boolean enableScreen;
6774        synchronized (this) {
6775            booting = mBooting;
6776            mBooting = false;
6777            enableScreen = !mBooted;
6778            mBooted = true;
6779        }
6780
6781        if (booting) {
6782            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6783            finishBooting();
6784            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6785        }
6786
6787        if (enableScreen) {
6788            enableScreenAfterBoot();
6789        }
6790    }
6791
6792    @Override
6793    public final void activityResumed(IBinder token) {
6794        final long origId = Binder.clearCallingIdentity();
6795        synchronized(this) {
6796            ActivityStack stack = ActivityRecord.getStackLocked(token);
6797            if (stack != null) {
6798                stack.activityResumedLocked(token);
6799            }
6800        }
6801        Binder.restoreCallingIdentity(origId);
6802    }
6803
6804    @Override
6805    public final void activityPaused(IBinder token) {
6806        final long origId = Binder.clearCallingIdentity();
6807        synchronized(this) {
6808            ActivityStack stack = ActivityRecord.getStackLocked(token);
6809            if (stack != null) {
6810                stack.activityPausedLocked(token, false);
6811            }
6812        }
6813        Binder.restoreCallingIdentity(origId);
6814    }
6815
6816    @Override
6817    public final void activityStopped(IBinder token, Bundle icicle,
6818            PersistableBundle persistentState, CharSequence description) {
6819        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6820
6821        // Refuse possible leaked file descriptors
6822        if (icicle != null && icicle.hasFileDescriptors()) {
6823            throw new IllegalArgumentException("File descriptors passed in Bundle");
6824        }
6825
6826        final long origId = Binder.clearCallingIdentity();
6827
6828        synchronized (this) {
6829            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830            if (r != null) {
6831                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6832            }
6833        }
6834
6835        trimApplications();
6836
6837        Binder.restoreCallingIdentity(origId);
6838    }
6839
6840    @Override
6841    public final void activityDestroyed(IBinder token) {
6842        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6843        synchronized (this) {
6844            ActivityStack stack = ActivityRecord.getStackLocked(token);
6845            if (stack != null) {
6846                stack.activityDestroyedLocked(token, "activityDestroyed");
6847            }
6848        }
6849    }
6850
6851    @Override
6852    public final void activityRelaunched(IBinder token) {
6853        final long origId = Binder.clearCallingIdentity();
6854        synchronized (this) {
6855            mStackSupervisor.activityRelaunchedLocked(token);
6856        }
6857        Binder.restoreCallingIdentity(origId);
6858    }
6859
6860    @Override
6861    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6862            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6863        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6864                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6865        synchronized (this) {
6866            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6867            if (record == null) {
6868                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6869                        + "found for: " + token);
6870            }
6871            record.setSizeConfigurations(horizontalSizeConfiguration,
6872                    verticalSizeConfigurations, smallestSizeConfigurations);
6873        }
6874    }
6875
6876    @Override
6877    public final void backgroundResourcesReleased(IBinder token) {
6878        final long origId = Binder.clearCallingIdentity();
6879        try {
6880            synchronized (this) {
6881                ActivityStack stack = ActivityRecord.getStackLocked(token);
6882                if (stack != null) {
6883                    stack.backgroundResourcesReleased();
6884                }
6885            }
6886        } finally {
6887            Binder.restoreCallingIdentity(origId);
6888        }
6889    }
6890
6891    @Override
6892    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6893        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6894    }
6895
6896    @Override
6897    public final void notifyEnterAnimationComplete(IBinder token) {
6898        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6899    }
6900
6901    @Override
6902    public String getCallingPackage(IBinder token) {
6903        synchronized (this) {
6904            ActivityRecord r = getCallingRecordLocked(token);
6905            return r != null ? r.info.packageName : null;
6906        }
6907    }
6908
6909    @Override
6910    public ComponentName getCallingActivity(IBinder token) {
6911        synchronized (this) {
6912            ActivityRecord r = getCallingRecordLocked(token);
6913            return r != null ? r.intent.getComponent() : null;
6914        }
6915    }
6916
6917    private ActivityRecord getCallingRecordLocked(IBinder token) {
6918        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6919        if (r == null) {
6920            return null;
6921        }
6922        return r.resultTo;
6923    }
6924
6925    @Override
6926    public ComponentName getActivityClassForToken(IBinder token) {
6927        synchronized(this) {
6928            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6929            if (r == null) {
6930                return null;
6931            }
6932            return r.intent.getComponent();
6933        }
6934    }
6935
6936    @Override
6937    public String getPackageForToken(IBinder token) {
6938        synchronized(this) {
6939            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6940            if (r == null) {
6941                return null;
6942            }
6943            return r.packageName;
6944        }
6945    }
6946
6947    @Override
6948    public boolean isRootVoiceInteraction(IBinder token) {
6949        synchronized(this) {
6950            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6951            if (r == null) {
6952                return false;
6953            }
6954            return r.rootVoiceInteraction;
6955        }
6956    }
6957
6958    @Override
6959    public IIntentSender getIntentSender(int type,
6960            String packageName, IBinder token, String resultWho,
6961            int requestCode, Intent[] intents, String[] resolvedTypes,
6962            int flags, Bundle bOptions, int userId) {
6963        enforceNotIsolatedCaller("getIntentSender");
6964        // Refuse possible leaked file descriptors
6965        if (intents != null) {
6966            if (intents.length < 1) {
6967                throw new IllegalArgumentException("Intents array length must be >= 1");
6968            }
6969            for (int i=0; i<intents.length; i++) {
6970                Intent intent = intents[i];
6971                if (intent != null) {
6972                    if (intent.hasFileDescriptors()) {
6973                        throw new IllegalArgumentException("File descriptors passed in Intent");
6974                    }
6975                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6976                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6977                        throw new IllegalArgumentException(
6978                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6979                    }
6980                    intents[i] = new Intent(intent);
6981                }
6982            }
6983            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6984                throw new IllegalArgumentException(
6985                        "Intent array length does not match resolvedTypes length");
6986            }
6987        }
6988        if (bOptions != null) {
6989            if (bOptions.hasFileDescriptors()) {
6990                throw new IllegalArgumentException("File descriptors passed in options");
6991            }
6992        }
6993
6994        synchronized(this) {
6995            int callingUid = Binder.getCallingUid();
6996            int origUserId = userId;
6997            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6998                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6999                    ALLOW_NON_FULL, "getIntentSender", null);
7000            if (origUserId == UserHandle.USER_CURRENT) {
7001                // We don't want to evaluate this until the pending intent is
7002                // actually executed.  However, we do want to always do the
7003                // security checking for it above.
7004                userId = UserHandle.USER_CURRENT;
7005            }
7006            try {
7007                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7008                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7009                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7010                    if (!UserHandle.isSameApp(callingUid, uid)) {
7011                        String msg = "Permission Denial: getIntentSender() from pid="
7012                            + Binder.getCallingPid()
7013                            + ", uid=" + Binder.getCallingUid()
7014                            + ", (need uid=" + uid + ")"
7015                            + " is not allowed to send as package " + packageName;
7016                        Slog.w(TAG, msg);
7017                        throw new SecurityException(msg);
7018                    }
7019                }
7020
7021                return getIntentSenderLocked(type, packageName, callingUid, userId,
7022                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7023
7024            } catch (RemoteException e) {
7025                throw new SecurityException(e);
7026            }
7027        }
7028    }
7029
7030    IIntentSender getIntentSenderLocked(int type, String packageName,
7031            int callingUid, int userId, IBinder token, String resultWho,
7032            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7033            Bundle bOptions) {
7034        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7035        ActivityRecord activity = null;
7036        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7037            activity = ActivityRecord.isInStackLocked(token);
7038            if (activity == null) {
7039                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7040                return null;
7041            }
7042            if (activity.finishing) {
7043                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7044                return null;
7045            }
7046        }
7047
7048        // We're going to be splicing together extras before sending, so we're
7049        // okay poking into any contained extras.
7050        if (intents != null) {
7051            for (int i = 0; i < intents.length; i++) {
7052                intents[i].setDefusable(true);
7053            }
7054        }
7055        Bundle.setDefusable(bOptions, true);
7056
7057        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7058        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7059        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7060        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7061                |PendingIntent.FLAG_UPDATE_CURRENT);
7062
7063        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7064                type, packageName, activity, resultWho,
7065                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7066        WeakReference<PendingIntentRecord> ref;
7067        ref = mIntentSenderRecords.get(key);
7068        PendingIntentRecord rec = ref != null ? ref.get() : null;
7069        if (rec != null) {
7070            if (!cancelCurrent) {
7071                if (updateCurrent) {
7072                    if (rec.key.requestIntent != null) {
7073                        rec.key.requestIntent.replaceExtras(intents != null ?
7074                                intents[intents.length - 1] : null);
7075                    }
7076                    if (intents != null) {
7077                        intents[intents.length-1] = rec.key.requestIntent;
7078                        rec.key.allIntents = intents;
7079                        rec.key.allResolvedTypes = resolvedTypes;
7080                    } else {
7081                        rec.key.allIntents = null;
7082                        rec.key.allResolvedTypes = null;
7083                    }
7084                }
7085                return rec;
7086            }
7087            rec.canceled = true;
7088            mIntentSenderRecords.remove(key);
7089        }
7090        if (noCreate) {
7091            return rec;
7092        }
7093        rec = new PendingIntentRecord(this, key, callingUid);
7094        mIntentSenderRecords.put(key, rec.ref);
7095        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7096            if (activity.pendingResults == null) {
7097                activity.pendingResults
7098                        = new HashSet<WeakReference<PendingIntentRecord>>();
7099            }
7100            activity.pendingResults.add(rec.ref);
7101        }
7102        return rec;
7103    }
7104
7105    @Override
7106    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7107            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7108        if (target instanceof PendingIntentRecord) {
7109            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7110                    finishedReceiver, requiredPermission, options);
7111        } else {
7112            if (intent == null) {
7113                // Weird case: someone has given us their own custom IIntentSender, and now
7114                // they have someone else trying to send to it but of course this isn't
7115                // really a PendingIntent, so there is no base Intent, and the caller isn't
7116                // supplying an Intent... but we never want to dispatch a null Intent to
7117                // a receiver, so um...  let's make something up.
7118                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7119                intent = new Intent(Intent.ACTION_MAIN);
7120            }
7121            try {
7122                target.send(code, intent, resolvedType, null, requiredPermission, options);
7123            } catch (RemoteException e) {
7124            }
7125            // Platform code can rely on getting a result back when the send is done, but if
7126            // this intent sender is from outside of the system we can't rely on it doing that.
7127            // So instead we don't give it the result receiver, and instead just directly
7128            // report the finish immediately.
7129            if (finishedReceiver != null) {
7130                try {
7131                    finishedReceiver.performReceive(intent, 0,
7132                            null, null, false, false, UserHandle.getCallingUserId());
7133                } catch (RemoteException e) {
7134                }
7135            }
7136            return 0;
7137        }
7138    }
7139
7140    /**
7141     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7142     *
7143     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7144     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7145     */
7146    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7147        if (DEBUG_WHITELISTS) {
7148            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7149                    + targetUid + ", " + duration + ")");
7150        }
7151        synchronized (mPidsSelfLocked) {
7152            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7153            if (pr == null) {
7154                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7155                return;
7156            }
7157            if (!pr.whitelistManager) {
7158                if (DEBUG_WHITELISTS) {
7159                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7160                            + callerPid + " is not allowed");
7161                }
7162                return;
7163            }
7164        }
7165
7166        final long token = Binder.clearCallingIdentity();
7167        try {
7168            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7169                    true, "pe from uid:" + callerUid);
7170        } finally {
7171            Binder.restoreCallingIdentity(token);
7172        }
7173    }
7174
7175    @Override
7176    public void cancelIntentSender(IIntentSender sender) {
7177        if (!(sender instanceof PendingIntentRecord)) {
7178            return;
7179        }
7180        synchronized(this) {
7181            PendingIntentRecord rec = (PendingIntentRecord)sender;
7182            try {
7183                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7184                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7185                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7186                    String msg = "Permission Denial: cancelIntentSender() from pid="
7187                        + Binder.getCallingPid()
7188                        + ", uid=" + Binder.getCallingUid()
7189                        + " is not allowed to cancel packges "
7190                        + rec.key.packageName;
7191                    Slog.w(TAG, msg);
7192                    throw new SecurityException(msg);
7193                }
7194            } catch (RemoteException e) {
7195                throw new SecurityException(e);
7196            }
7197            cancelIntentSenderLocked(rec, true);
7198        }
7199    }
7200
7201    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7202        rec.canceled = true;
7203        mIntentSenderRecords.remove(rec.key);
7204        if (cleanActivity && rec.key.activity != null) {
7205            rec.key.activity.pendingResults.remove(rec.ref);
7206        }
7207    }
7208
7209    @Override
7210    public String getPackageForIntentSender(IIntentSender pendingResult) {
7211        if (!(pendingResult instanceof PendingIntentRecord)) {
7212            return null;
7213        }
7214        try {
7215            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7216            return res.key.packageName;
7217        } catch (ClassCastException e) {
7218        }
7219        return null;
7220    }
7221
7222    @Override
7223    public int getUidForIntentSender(IIntentSender sender) {
7224        if (sender instanceof PendingIntentRecord) {
7225            try {
7226                PendingIntentRecord res = (PendingIntentRecord)sender;
7227                return res.uid;
7228            } catch (ClassCastException e) {
7229            }
7230        }
7231        return -1;
7232    }
7233
7234    @Override
7235    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7236        if (!(pendingResult instanceof PendingIntentRecord)) {
7237            return false;
7238        }
7239        try {
7240            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7241            if (res.key.allIntents == null) {
7242                return false;
7243            }
7244            for (int i=0; i<res.key.allIntents.length; i++) {
7245                Intent intent = res.key.allIntents[i];
7246                if (intent.getPackage() != null && intent.getComponent() != null) {
7247                    return false;
7248                }
7249            }
7250            return true;
7251        } catch (ClassCastException e) {
7252        }
7253        return false;
7254    }
7255
7256    @Override
7257    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7258        if (!(pendingResult instanceof PendingIntentRecord)) {
7259            return false;
7260        }
7261        try {
7262            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7263            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7264                return true;
7265            }
7266            return false;
7267        } catch (ClassCastException e) {
7268        }
7269        return false;
7270    }
7271
7272    @Override
7273    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7274        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7275                "getIntentForIntentSender()");
7276        if (!(pendingResult instanceof PendingIntentRecord)) {
7277            return null;
7278        }
7279        try {
7280            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7281            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7282        } catch (ClassCastException e) {
7283        }
7284        return null;
7285    }
7286
7287    @Override
7288    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7289        if (!(pendingResult instanceof PendingIntentRecord)) {
7290            return null;
7291        }
7292        try {
7293            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7294            synchronized (this) {
7295                return getTagForIntentSenderLocked(res, prefix);
7296            }
7297        } catch (ClassCastException e) {
7298        }
7299        return null;
7300    }
7301
7302    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7303        final Intent intent = res.key.requestIntent;
7304        if (intent != null) {
7305            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7306                    || res.lastTagPrefix.equals(prefix))) {
7307                return res.lastTag;
7308            }
7309            res.lastTagPrefix = prefix;
7310            final StringBuilder sb = new StringBuilder(128);
7311            if (prefix != null) {
7312                sb.append(prefix);
7313            }
7314            if (intent.getAction() != null) {
7315                sb.append(intent.getAction());
7316            } else if (intent.getComponent() != null) {
7317                intent.getComponent().appendShortString(sb);
7318            } else {
7319                sb.append("?");
7320            }
7321            return res.lastTag = sb.toString();
7322        }
7323        return null;
7324    }
7325
7326    @Override
7327    public void setProcessLimit(int max) {
7328        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329                "setProcessLimit()");
7330        synchronized (this) {
7331            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7332            mProcessLimitOverride = max;
7333        }
7334        trimApplications();
7335    }
7336
7337    @Override
7338    public int getProcessLimit() {
7339        synchronized (this) {
7340            return mProcessLimitOverride;
7341        }
7342    }
7343
7344    void foregroundTokenDied(ForegroundToken token) {
7345        synchronized (ActivityManagerService.this) {
7346            synchronized (mPidsSelfLocked) {
7347                ForegroundToken cur
7348                    = mForegroundProcesses.get(token.pid);
7349                if (cur != token) {
7350                    return;
7351                }
7352                mForegroundProcesses.remove(token.pid);
7353                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7354                if (pr == null) {
7355                    return;
7356                }
7357                pr.forcingToForeground = null;
7358                updateProcessForegroundLocked(pr, false, false);
7359            }
7360            updateOomAdjLocked();
7361        }
7362    }
7363
7364    @Override
7365    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7366        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7367                "setProcessForeground()");
7368        synchronized(this) {
7369            boolean changed = false;
7370
7371            synchronized (mPidsSelfLocked) {
7372                ProcessRecord pr = mPidsSelfLocked.get(pid);
7373                if (pr == null && isForeground) {
7374                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7375                    return;
7376                }
7377                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7378                if (oldToken != null) {
7379                    oldToken.token.unlinkToDeath(oldToken, 0);
7380                    mForegroundProcesses.remove(pid);
7381                    if (pr != null) {
7382                        pr.forcingToForeground = null;
7383                    }
7384                    changed = true;
7385                }
7386                if (isForeground && token != null) {
7387                    ForegroundToken newToken = new ForegroundToken() {
7388                        @Override
7389                        public void binderDied() {
7390                            foregroundTokenDied(this);
7391                        }
7392                    };
7393                    newToken.pid = pid;
7394                    newToken.token = token;
7395                    try {
7396                        token.linkToDeath(newToken, 0);
7397                        mForegroundProcesses.put(pid, newToken);
7398                        pr.forcingToForeground = token;
7399                        changed = true;
7400                    } catch (RemoteException e) {
7401                        // If the process died while doing this, we will later
7402                        // do the cleanup with the process death link.
7403                    }
7404                }
7405            }
7406
7407            if (changed) {
7408                updateOomAdjLocked();
7409            }
7410        }
7411    }
7412
7413    @Override
7414    public boolean isAppForeground(int uid) throws RemoteException {
7415        synchronized (this) {
7416            UidRecord uidRec = mActiveUids.get(uid);
7417            if (uidRec == null || uidRec.idle) {
7418                return false;
7419            }
7420            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7421        }
7422    }
7423
7424    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7425    // be guarded by permission checking.
7426    int getUidState(int uid) {
7427        synchronized (this) {
7428            UidRecord uidRec = mActiveUids.get(uid);
7429            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7430        }
7431    }
7432
7433    @Override
7434    public boolean isInMultiWindowMode(IBinder token) {
7435        final long origId = Binder.clearCallingIdentity();
7436        try {
7437            synchronized(this) {
7438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7439                if (r == null) {
7440                    return false;
7441                }
7442                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7443                return !r.task.mFullscreen;
7444            }
7445        } finally {
7446            Binder.restoreCallingIdentity(origId);
7447        }
7448    }
7449
7450    @Override
7451    public boolean isInPictureInPictureMode(IBinder token) {
7452        final long origId = Binder.clearCallingIdentity();
7453        try {
7454            synchronized(this) {
7455                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7456                if (stack == null) {
7457                    return false;
7458                }
7459                return stack.mStackId == PINNED_STACK_ID;
7460            }
7461        } finally {
7462            Binder.restoreCallingIdentity(origId);
7463        }
7464    }
7465
7466    @Override
7467    public void enterPictureInPictureMode(IBinder token) {
7468        final long origId = Binder.clearCallingIdentity();
7469        try {
7470            synchronized(this) {
7471                if (!mSupportsPictureInPicture) {
7472                    throw new IllegalStateException("enterPictureInPictureMode: "
7473                            + "Device doesn't support picture-in-picture mode.");
7474                }
7475
7476                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7477
7478                if (r == null) {
7479                    throw new IllegalStateException("enterPictureInPictureMode: "
7480                            + "Can't find activity for token=" + token);
7481                }
7482
7483                if (!r.supportsPictureInPicture()) {
7484                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7485                            + "Picture-In-Picture not supported for r=" + r);
7486                }
7487
7488                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7489                // current bounds.
7490                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7491                final Rect bounds = (pinnedStack != null)
7492                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7493
7494                mStackSupervisor.moveActivityToPinnedStackLocked(
7495                        r, "enterPictureInPictureMode", bounds);
7496            }
7497        } finally {
7498            Binder.restoreCallingIdentity(origId);
7499        }
7500    }
7501
7502    // =========================================================
7503    // PROCESS INFO
7504    // =========================================================
7505
7506    static class ProcessInfoService extends IProcessInfoService.Stub {
7507        final ActivityManagerService mActivityManagerService;
7508        ProcessInfoService(ActivityManagerService activityManagerService) {
7509            mActivityManagerService = activityManagerService;
7510        }
7511
7512        @Override
7513        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7514            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7515                    /*in*/ pids, /*out*/ states, null);
7516        }
7517
7518        @Override
7519        public void getProcessStatesAndOomScoresFromPids(
7520                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7521            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7522                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7523        }
7524    }
7525
7526    /**
7527     * For each PID in the given input array, write the current process state
7528     * for that process into the states array, or -1 to indicate that no
7529     * process with the given PID exists. If scores array is provided, write
7530     * the oom score for the process into the scores array, with INVALID_ADJ
7531     * indicating the PID doesn't exist.
7532     */
7533    public void getProcessStatesAndOomScoresForPIDs(
7534            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7535        if (scores != null) {
7536            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7537                    "getProcessStatesAndOomScoresForPIDs()");
7538        }
7539
7540        if (pids == null) {
7541            throw new NullPointerException("pids");
7542        } else if (states == null) {
7543            throw new NullPointerException("states");
7544        } else if (pids.length != states.length) {
7545            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7546        } else if (scores != null && pids.length != scores.length) {
7547            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7548        }
7549
7550        synchronized (mPidsSelfLocked) {
7551            for (int i = 0; i < pids.length; i++) {
7552                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7553                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7554                        pr.curProcState;
7555                if (scores != null) {
7556                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7557                }
7558            }
7559        }
7560    }
7561
7562    // =========================================================
7563    // PERMISSIONS
7564    // =========================================================
7565
7566    static class PermissionController extends IPermissionController.Stub {
7567        ActivityManagerService mActivityManagerService;
7568        PermissionController(ActivityManagerService activityManagerService) {
7569            mActivityManagerService = activityManagerService;
7570        }
7571
7572        @Override
7573        public boolean checkPermission(String permission, int pid, int uid) {
7574            return mActivityManagerService.checkPermission(permission, pid,
7575                    uid) == PackageManager.PERMISSION_GRANTED;
7576        }
7577
7578        @Override
7579        public String[] getPackagesForUid(int uid) {
7580            return mActivityManagerService.mContext.getPackageManager()
7581                    .getPackagesForUid(uid);
7582        }
7583
7584        @Override
7585        public boolean isRuntimePermission(String permission) {
7586            try {
7587                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7588                        .getPermissionInfo(permission, 0);
7589                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7590            } catch (NameNotFoundException nnfe) {
7591                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7592            }
7593            return false;
7594        }
7595    }
7596
7597    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7598        @Override
7599        public int checkComponentPermission(String permission, int pid, int uid,
7600                int owningUid, boolean exported) {
7601            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7602                    owningUid, exported);
7603        }
7604
7605        @Override
7606        public Object getAMSLock() {
7607            return ActivityManagerService.this;
7608        }
7609    }
7610
7611    /**
7612     * This can be called with or without the global lock held.
7613     */
7614    int checkComponentPermission(String permission, int pid, int uid,
7615            int owningUid, boolean exported) {
7616        if (pid == MY_PID) {
7617            return PackageManager.PERMISSION_GRANTED;
7618        }
7619        return ActivityManager.checkComponentPermission(permission, uid,
7620                owningUid, exported);
7621    }
7622
7623    /**
7624     * As the only public entry point for permissions checking, this method
7625     * can enforce the semantic that requesting a check on a null global
7626     * permission is automatically denied.  (Internally a null permission
7627     * string is used when calling {@link #checkComponentPermission} in cases
7628     * when only uid-based security is needed.)
7629     *
7630     * This can be called with or without the global lock held.
7631     */
7632    @Override
7633    public int checkPermission(String permission, int pid, int uid) {
7634        if (permission == null) {
7635            return PackageManager.PERMISSION_DENIED;
7636        }
7637        return checkComponentPermission(permission, pid, uid, -1, true);
7638    }
7639
7640    @Override
7641    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7642        if (permission == null) {
7643            return PackageManager.PERMISSION_DENIED;
7644        }
7645
7646        // We might be performing an operation on behalf of an indirect binder
7647        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7648        // client identity accordingly before proceeding.
7649        Identity tlsIdentity = sCallerIdentity.get();
7650        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7651            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7652                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7653            uid = tlsIdentity.uid;
7654            pid = tlsIdentity.pid;
7655        }
7656
7657        return checkComponentPermission(permission, pid, uid, -1, true);
7658    }
7659
7660    /**
7661     * Binder IPC calls go through the public entry point.
7662     * This can be called with or without the global lock held.
7663     */
7664    int checkCallingPermission(String permission) {
7665        return checkPermission(permission,
7666                Binder.getCallingPid(),
7667                UserHandle.getAppId(Binder.getCallingUid()));
7668    }
7669
7670    /**
7671     * This can be called with or without the global lock held.
7672     */
7673    void enforceCallingPermission(String permission, String func) {
7674        if (checkCallingPermission(permission)
7675                == PackageManager.PERMISSION_GRANTED) {
7676            return;
7677        }
7678
7679        String msg = "Permission Denial: " + func + " from pid="
7680                + Binder.getCallingPid()
7681                + ", uid=" + Binder.getCallingUid()
7682                + " requires " + permission;
7683        Slog.w(TAG, msg);
7684        throw new SecurityException(msg);
7685    }
7686
7687    /**
7688     * Determine if UID is holding permissions required to access {@link Uri} in
7689     * the given {@link ProviderInfo}. Final permission checking is always done
7690     * in {@link ContentProvider}.
7691     */
7692    private final boolean checkHoldingPermissionsLocked(
7693            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7694        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7695                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7696        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7697            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7698                    != PERMISSION_GRANTED) {
7699                return false;
7700            }
7701        }
7702        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7703    }
7704
7705    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7706            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7707        if (pi.applicationInfo.uid == uid) {
7708            return true;
7709        } else if (!pi.exported) {
7710            return false;
7711        }
7712
7713        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7714        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7715        try {
7716            // check if target holds top-level <provider> permissions
7717            if (!readMet && pi.readPermission != null && considerUidPermissions
7718                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7719                readMet = true;
7720            }
7721            if (!writeMet && pi.writePermission != null && considerUidPermissions
7722                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7723                writeMet = true;
7724            }
7725
7726            // track if unprotected read/write is allowed; any denied
7727            // <path-permission> below removes this ability
7728            boolean allowDefaultRead = pi.readPermission == null;
7729            boolean allowDefaultWrite = pi.writePermission == null;
7730
7731            // check if target holds any <path-permission> that match uri
7732            final PathPermission[] pps = pi.pathPermissions;
7733            if (pps != null) {
7734                final String path = grantUri.uri.getPath();
7735                int i = pps.length;
7736                while (i > 0 && (!readMet || !writeMet)) {
7737                    i--;
7738                    PathPermission pp = pps[i];
7739                    if (pp.match(path)) {
7740                        if (!readMet) {
7741                            final String pprperm = pp.getReadPermission();
7742                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7743                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7744                                    + ": match=" + pp.match(path)
7745                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7746                            if (pprperm != null) {
7747                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7748                                        == PERMISSION_GRANTED) {
7749                                    readMet = true;
7750                                } else {
7751                                    allowDefaultRead = false;
7752                                }
7753                            }
7754                        }
7755                        if (!writeMet) {
7756                            final String ppwperm = pp.getWritePermission();
7757                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7759                                    + ": match=" + pp.match(path)
7760                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7761                            if (ppwperm != null) {
7762                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7763                                        == PERMISSION_GRANTED) {
7764                                    writeMet = true;
7765                                } else {
7766                                    allowDefaultWrite = false;
7767                                }
7768                            }
7769                        }
7770                    }
7771                }
7772            }
7773
7774            // grant unprotected <provider> read/write, if not blocked by
7775            // <path-permission> above
7776            if (allowDefaultRead) readMet = true;
7777            if (allowDefaultWrite) writeMet = true;
7778
7779        } catch (RemoteException e) {
7780            return false;
7781        }
7782
7783        return readMet && writeMet;
7784    }
7785
7786    public int getAppStartMode(int uid, String packageName) {
7787        synchronized (this) {
7788            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7789        }
7790    }
7791
7792    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7793            boolean allowWhenForeground) {
7794        UidRecord uidRec = mActiveUids.get(uid);
7795        if (!mLenientBackgroundCheck) {
7796            if (!allowWhenForeground || uidRec == null
7797                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7798                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7799                        packageName) != AppOpsManager.MODE_ALLOWED) {
7800                    return ActivityManager.APP_START_MODE_DELAYED;
7801                }
7802            }
7803
7804        } else if (uidRec == null || uidRec.idle) {
7805            if (callingPid >= 0) {
7806                ProcessRecord proc;
7807                synchronized (mPidsSelfLocked) {
7808                    proc = mPidsSelfLocked.get(callingPid);
7809                }
7810                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7811                    // Whoever is instigating this is in the foreground, so we will allow it
7812                    // to go through.
7813                    return ActivityManager.APP_START_MODE_NORMAL;
7814                }
7815            }
7816            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7817                    != AppOpsManager.MODE_ALLOWED) {
7818                return ActivityManager.APP_START_MODE_DELAYED;
7819            }
7820        }
7821        return ActivityManager.APP_START_MODE_NORMAL;
7822    }
7823
7824    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7825        ProviderInfo pi = null;
7826        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7827        if (cpr != null) {
7828            pi = cpr.info;
7829        } else {
7830            try {
7831                pi = AppGlobals.getPackageManager().resolveContentProvider(
7832                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7833            } catch (RemoteException ex) {
7834            }
7835        }
7836        return pi;
7837    }
7838
7839    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7840        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7841        if (targetUris != null) {
7842            return targetUris.get(grantUri);
7843        }
7844        return null;
7845    }
7846
7847    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7848            String targetPkg, int targetUid, GrantUri grantUri) {
7849        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7850        if (targetUris == null) {
7851            targetUris = Maps.newArrayMap();
7852            mGrantedUriPermissions.put(targetUid, targetUris);
7853        }
7854
7855        UriPermission perm = targetUris.get(grantUri);
7856        if (perm == null) {
7857            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7858            targetUris.put(grantUri, perm);
7859        }
7860
7861        return perm;
7862    }
7863
7864    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7865            final int modeFlags) {
7866        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7867        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7868                : UriPermission.STRENGTH_OWNED;
7869
7870        // Root gets to do everything.
7871        if (uid == 0) {
7872            return true;
7873        }
7874
7875        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7876        if (perms == null) return false;
7877
7878        // First look for exact match
7879        final UriPermission exactPerm = perms.get(grantUri);
7880        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7881            return true;
7882        }
7883
7884        // No exact match, look for prefixes
7885        final int N = perms.size();
7886        for (int i = 0; i < N; i++) {
7887            final UriPermission perm = perms.valueAt(i);
7888            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7889                    && perm.getStrength(modeFlags) >= minStrength) {
7890                return true;
7891            }
7892        }
7893
7894        return false;
7895    }
7896
7897    /**
7898     * @param uri This uri must NOT contain an embedded userId.
7899     * @param userId The userId in which the uri is to be resolved.
7900     */
7901    @Override
7902    public int checkUriPermission(Uri uri, int pid, int uid,
7903            final int modeFlags, int userId, IBinder callerToken) {
7904        enforceNotIsolatedCaller("checkUriPermission");
7905
7906        // Another redirected-binder-call permissions check as in
7907        // {@link checkPermissionWithToken}.
7908        Identity tlsIdentity = sCallerIdentity.get();
7909        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7910            uid = tlsIdentity.uid;
7911            pid = tlsIdentity.pid;
7912        }
7913
7914        // Our own process gets to do everything.
7915        if (pid == MY_PID) {
7916            return PackageManager.PERMISSION_GRANTED;
7917        }
7918        synchronized (this) {
7919            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7920                    ? PackageManager.PERMISSION_GRANTED
7921                    : PackageManager.PERMISSION_DENIED;
7922        }
7923    }
7924
7925    /**
7926     * Check if the targetPkg can be granted permission to access uri by
7927     * the callingUid using the given modeFlags.  Throws a security exception
7928     * if callingUid is not allowed to do this.  Returns the uid of the target
7929     * if the URI permission grant should be performed; returns -1 if it is not
7930     * needed (for example targetPkg already has permission to access the URI).
7931     * If you already know the uid of the target, you can supply it in
7932     * lastTargetUid else set that to -1.
7933     */
7934    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7935            final int modeFlags, int lastTargetUid) {
7936        if (!Intent.isAccessUriMode(modeFlags)) {
7937            return -1;
7938        }
7939
7940        if (targetPkg != null) {
7941            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7942                    "Checking grant " + targetPkg + " permission to " + grantUri);
7943        }
7944
7945        final IPackageManager pm = AppGlobals.getPackageManager();
7946
7947        // If this is not a content: uri, we can't do anything with it.
7948        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7949            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950                    "Can't grant URI permission for non-content URI: " + grantUri);
7951            return -1;
7952        }
7953
7954        final String authority = grantUri.uri.getAuthority();
7955        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7956        if (pi == null) {
7957            Slog.w(TAG, "No content provider found for permission check: " +
7958                    grantUri.uri.toSafeString());
7959            return -1;
7960        }
7961
7962        int targetUid = lastTargetUid;
7963        if (targetUid < 0 && targetPkg != null) {
7964            try {
7965                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7966                        UserHandle.getUserId(callingUid));
7967                if (targetUid < 0) {
7968                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7969                            "Can't grant URI permission no uid for: " + targetPkg);
7970                    return -1;
7971                }
7972            } catch (RemoteException ex) {
7973                return -1;
7974            }
7975        }
7976
7977        if (targetUid >= 0) {
7978            // First...  does the target actually need this permission?
7979            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7980                // No need to grant the target this permission.
7981                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982                        "Target " + targetPkg + " already has full permission to " + grantUri);
7983                return -1;
7984            }
7985        } else {
7986            // First...  there is no target package, so can anyone access it?
7987            boolean allowed = pi.exported;
7988            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7989                if (pi.readPermission != null) {
7990                    allowed = false;
7991                }
7992            }
7993            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7994                if (pi.writePermission != null) {
7995                    allowed = false;
7996                }
7997            }
7998            if (allowed) {
7999                return -1;
8000            }
8001        }
8002
8003        /* There is a special cross user grant if:
8004         * - The target is on another user.
8005         * - Apps on the current user can access the uri without any uid permissions.
8006         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8007         * grant uri permissions.
8008         */
8009        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8010                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8011                modeFlags, false /*without considering the uid permissions*/);
8012
8013        // Second...  is the provider allowing granting of URI permissions?
8014        if (!specialCrossUserGrant) {
8015            if (!pi.grantUriPermissions) {
8016                throw new SecurityException("Provider " + pi.packageName
8017                        + "/" + pi.name
8018                        + " does not allow granting of Uri permissions (uri "
8019                        + grantUri + ")");
8020            }
8021            if (pi.uriPermissionPatterns != null) {
8022                final int N = pi.uriPermissionPatterns.length;
8023                boolean allowed = false;
8024                for (int i=0; i<N; i++) {
8025                    if (pi.uriPermissionPatterns[i] != null
8026                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8027                        allowed = true;
8028                        break;
8029                    }
8030                }
8031                if (!allowed) {
8032                    throw new SecurityException("Provider " + pi.packageName
8033                            + "/" + pi.name
8034                            + " does not allow granting of permission to path of Uri "
8035                            + grantUri);
8036                }
8037            }
8038        }
8039
8040        // Third...  does the caller itself have permission to access
8041        // this uri?
8042        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8043            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8044                // Require they hold a strong enough Uri permission
8045                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8046                    throw new SecurityException("Uid " + callingUid
8047                            + " does not have permission to uri " + grantUri);
8048                }
8049            }
8050        }
8051        return targetUid;
8052    }
8053
8054    /**
8055     * @param uri This uri must NOT contain an embedded userId.
8056     * @param userId The userId in which the uri is to be resolved.
8057     */
8058    @Override
8059    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8060            final int modeFlags, int userId) {
8061        enforceNotIsolatedCaller("checkGrantUriPermission");
8062        synchronized(this) {
8063            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8064                    new GrantUri(userId, uri, false), modeFlags, -1);
8065        }
8066    }
8067
8068    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8069            final int modeFlags, UriPermissionOwner owner) {
8070        if (!Intent.isAccessUriMode(modeFlags)) {
8071            return;
8072        }
8073
8074        // So here we are: the caller has the assumed permission
8075        // to the uri, and the target doesn't.  Let's now give this to
8076        // the target.
8077
8078        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8080
8081        final String authority = grantUri.uri.getAuthority();
8082        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8083        if (pi == null) {
8084            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8085            return;
8086        }
8087
8088        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8089            grantUri.prefix = true;
8090        }
8091        final UriPermission perm = findOrCreateUriPermissionLocked(
8092                pi.packageName, targetPkg, targetUid, grantUri);
8093        perm.grantModes(modeFlags, owner);
8094    }
8095
8096    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8097            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8098        if (targetPkg == null) {
8099            throw new NullPointerException("targetPkg");
8100        }
8101        int targetUid;
8102        final IPackageManager pm = AppGlobals.getPackageManager();
8103        try {
8104            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8105        } catch (RemoteException ex) {
8106            return;
8107        }
8108
8109        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8110                targetUid);
8111        if (targetUid < 0) {
8112            return;
8113        }
8114
8115        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8116                owner);
8117    }
8118
8119    static class NeededUriGrants extends ArrayList<GrantUri> {
8120        final String targetPkg;
8121        final int targetUid;
8122        final int flags;
8123
8124        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8125            this.targetPkg = targetPkg;
8126            this.targetUid = targetUid;
8127            this.flags = flags;
8128        }
8129    }
8130
8131    /**
8132     * Like checkGrantUriPermissionLocked, but takes an Intent.
8133     */
8134    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8135            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8136        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8138                + " clip=" + (intent != null ? intent.getClipData() : null)
8139                + " from " + intent + "; flags=0x"
8140                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8141
8142        if (targetPkg == null) {
8143            throw new NullPointerException("targetPkg");
8144        }
8145
8146        if (intent == null) {
8147            return null;
8148        }
8149        Uri data = intent.getData();
8150        ClipData clip = intent.getClipData();
8151        if (data == null && clip == null) {
8152            return null;
8153        }
8154        // Default userId for uris in the intent (if they don't specify it themselves)
8155        int contentUserHint = intent.getContentUserHint();
8156        if (contentUserHint == UserHandle.USER_CURRENT) {
8157            contentUserHint = UserHandle.getUserId(callingUid);
8158        }
8159        final IPackageManager pm = AppGlobals.getPackageManager();
8160        int targetUid;
8161        if (needed != null) {
8162            targetUid = needed.targetUid;
8163        } else {
8164            try {
8165                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8166                        targetUserId);
8167            } catch (RemoteException ex) {
8168                return null;
8169            }
8170            if (targetUid < 0) {
8171                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                        "Can't grant URI permission no uid for: " + targetPkg
8173                        + " on user " + targetUserId);
8174                return null;
8175            }
8176        }
8177        if (data != null) {
8178            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8179            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8180                    targetUid);
8181            if (targetUid > 0) {
8182                if (needed == null) {
8183                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8184                }
8185                needed.add(grantUri);
8186            }
8187        }
8188        if (clip != null) {
8189            for (int i=0; i<clip.getItemCount(); i++) {
8190                Uri uri = clip.getItemAt(i).getUri();
8191                if (uri != null) {
8192                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8193                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8194                            targetUid);
8195                    if (targetUid > 0) {
8196                        if (needed == null) {
8197                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8198                        }
8199                        needed.add(grantUri);
8200                    }
8201                } else {
8202                    Intent clipIntent = clip.getItemAt(i).getIntent();
8203                    if (clipIntent != null) {
8204                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8205                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8206                        if (newNeeded != null) {
8207                            needed = newNeeded;
8208                        }
8209                    }
8210                }
8211            }
8212        }
8213
8214        return needed;
8215    }
8216
8217    /**
8218     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8219     */
8220    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8221            UriPermissionOwner owner) {
8222        if (needed != null) {
8223            for (int i=0; i<needed.size(); i++) {
8224                GrantUri grantUri = needed.get(i);
8225                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8226                        grantUri, needed.flags, owner);
8227            }
8228        }
8229    }
8230
8231    void grantUriPermissionFromIntentLocked(int callingUid,
8232            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8233        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8234                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8235        if (needed == null) {
8236            return;
8237        }
8238
8239        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8240    }
8241
8242    /**
8243     * @param uri This uri must NOT contain an embedded userId.
8244     * @param userId The userId in which the uri is to be resolved.
8245     */
8246    @Override
8247    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8248            final int modeFlags, int userId) {
8249        enforceNotIsolatedCaller("grantUriPermission");
8250        GrantUri grantUri = new GrantUri(userId, uri, false);
8251        synchronized(this) {
8252            final ProcessRecord r = getRecordForAppLocked(caller);
8253            if (r == null) {
8254                throw new SecurityException("Unable to find app for caller "
8255                        + caller
8256                        + " when granting permission to uri " + grantUri);
8257            }
8258            if (targetPkg == null) {
8259                throw new IllegalArgumentException("null target");
8260            }
8261            if (grantUri == null) {
8262                throw new IllegalArgumentException("null uri");
8263            }
8264
8265            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8266                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8267                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8268                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8269
8270            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8271                    UserHandle.getUserId(r.uid));
8272        }
8273    }
8274
8275    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8276        if (perm.modeFlags == 0) {
8277            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8278                    perm.targetUid);
8279            if (perms != null) {
8280                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8282
8283                perms.remove(perm.uri);
8284                if (perms.isEmpty()) {
8285                    mGrantedUriPermissions.remove(perm.targetUid);
8286                }
8287            }
8288        }
8289    }
8290
8291    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8292        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293                "Revoking all granted permissions to " + grantUri);
8294
8295        final IPackageManager pm = AppGlobals.getPackageManager();
8296        final String authority = grantUri.uri.getAuthority();
8297        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8298        if (pi == null) {
8299            Slog.w(TAG, "No content provider found for permission revoke: "
8300                    + grantUri.toSafeString());
8301            return;
8302        }
8303
8304        // Does the caller have this permission on the URI?
8305        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8306            // If they don't have direct access to the URI, then revoke any
8307            // ownerless URI permissions that have been granted to them.
8308            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8309            if (perms != null) {
8310                boolean persistChanged = false;
8311                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8312                    final UriPermission perm = it.next();
8313                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8314                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8315                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316                                "Revoking non-owned " + perm.targetUid
8317                                + " permission to " + perm.uri);
8318                        persistChanged |= perm.revokeModes(
8319                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8320                        if (perm.modeFlags == 0) {
8321                            it.remove();
8322                        }
8323                    }
8324                }
8325                if (perms.isEmpty()) {
8326                    mGrantedUriPermissions.remove(callingUid);
8327                }
8328                if (persistChanged) {
8329                    schedulePersistUriGrants();
8330                }
8331            }
8332            return;
8333        }
8334
8335        boolean persistChanged = false;
8336
8337        // Go through all of the permissions and remove any that match.
8338        int N = mGrantedUriPermissions.size();
8339        for (int i = 0; i < N; i++) {
8340            final int targetUid = mGrantedUriPermissions.keyAt(i);
8341            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8342
8343            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8344                final UriPermission perm = it.next();
8345                if (perm.uri.sourceUserId == grantUri.sourceUserId
8346                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8347                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8349                    persistChanged |= perm.revokeModes(
8350                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8351                    if (perm.modeFlags == 0) {
8352                        it.remove();
8353                    }
8354                }
8355            }
8356
8357            if (perms.isEmpty()) {
8358                mGrantedUriPermissions.remove(targetUid);
8359                N--;
8360                i--;
8361            }
8362        }
8363
8364        if (persistChanged) {
8365            schedulePersistUriGrants();
8366        }
8367    }
8368
8369    /**
8370     * @param uri This uri must NOT contain an embedded userId.
8371     * @param userId The userId in which the uri is to be resolved.
8372     */
8373    @Override
8374    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8375            int userId) {
8376        enforceNotIsolatedCaller("revokeUriPermission");
8377        synchronized(this) {
8378            final ProcessRecord r = getRecordForAppLocked(caller);
8379            if (r == null) {
8380                throw new SecurityException("Unable to find app for caller "
8381                        + caller
8382                        + " when revoking permission to uri " + uri);
8383            }
8384            if (uri == null) {
8385                Slog.w(TAG, "revokeUriPermission: null uri");
8386                return;
8387            }
8388
8389            if (!Intent.isAccessUriMode(modeFlags)) {
8390                return;
8391            }
8392
8393            final String authority = uri.getAuthority();
8394            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8395            if (pi == null) {
8396                Slog.w(TAG, "No content provider found for permission revoke: "
8397                        + uri.toSafeString());
8398                return;
8399            }
8400
8401            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8402        }
8403    }
8404
8405    /**
8406     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8407     * given package.
8408     *
8409     * @param packageName Package name to match, or {@code null} to apply to all
8410     *            packages.
8411     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8412     *            to all users.
8413     * @param persistable If persistable grants should be removed.
8414     */
8415    private void removeUriPermissionsForPackageLocked(
8416            String packageName, int userHandle, boolean persistable) {
8417        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8418            throw new IllegalArgumentException("Must narrow by either package or user");
8419        }
8420
8421        boolean persistChanged = false;
8422
8423        int N = mGrantedUriPermissions.size();
8424        for (int i = 0; i < N; i++) {
8425            final int targetUid = mGrantedUriPermissions.keyAt(i);
8426            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8427
8428            // Only inspect grants matching user
8429            if (userHandle == UserHandle.USER_ALL
8430                    || userHandle == UserHandle.getUserId(targetUid)) {
8431                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8432                    final UriPermission perm = it.next();
8433
8434                    // Only inspect grants matching package
8435                    if (packageName == null || perm.sourcePkg.equals(packageName)
8436                            || perm.targetPkg.equals(packageName)) {
8437                        persistChanged |= perm.revokeModes(persistable
8438                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8439
8440                        // Only remove when no modes remain; any persisted grants
8441                        // will keep this alive.
8442                        if (perm.modeFlags == 0) {
8443                            it.remove();
8444                        }
8445                    }
8446                }
8447
8448                if (perms.isEmpty()) {
8449                    mGrantedUriPermissions.remove(targetUid);
8450                    N--;
8451                    i--;
8452                }
8453            }
8454        }
8455
8456        if (persistChanged) {
8457            schedulePersistUriGrants();
8458        }
8459    }
8460
8461    @Override
8462    public IBinder newUriPermissionOwner(String name) {
8463        enforceNotIsolatedCaller("newUriPermissionOwner");
8464        synchronized(this) {
8465            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8466            return owner.getExternalTokenLocked();
8467        }
8468    }
8469
8470    @Override
8471    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8472        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8473        synchronized(this) {
8474            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8475            if (r == null) {
8476                throw new IllegalArgumentException("Activity does not exist; token="
8477                        + activityToken);
8478            }
8479            return r.getUriPermissionsLocked().getExternalTokenLocked();
8480        }
8481    }
8482    /**
8483     * @param uri This uri must NOT contain an embedded userId.
8484     * @param sourceUserId The userId in which the uri is to be resolved.
8485     * @param targetUserId The userId of the app that receives the grant.
8486     */
8487    @Override
8488    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8489            final int modeFlags, int sourceUserId, int targetUserId) {
8490        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8491                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8492                "grantUriPermissionFromOwner", null);
8493        synchronized(this) {
8494            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8495            if (owner == null) {
8496                throw new IllegalArgumentException("Unknown owner: " + token);
8497            }
8498            if (fromUid != Binder.getCallingUid()) {
8499                if (Binder.getCallingUid() != Process.myUid()) {
8500                    // Only system code can grant URI permissions on behalf
8501                    // of other users.
8502                    throw new SecurityException("nice try");
8503                }
8504            }
8505            if (targetPkg == null) {
8506                throw new IllegalArgumentException("null target");
8507            }
8508            if (uri == null) {
8509                throw new IllegalArgumentException("null uri");
8510            }
8511
8512            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8513                    modeFlags, owner, targetUserId);
8514        }
8515    }
8516
8517    /**
8518     * @param uri This uri must NOT contain an embedded userId.
8519     * @param userId The userId in which the uri is to be resolved.
8520     */
8521    @Override
8522    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8523        synchronized(this) {
8524            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8525            if (owner == null) {
8526                throw new IllegalArgumentException("Unknown owner: " + token);
8527            }
8528
8529            if (uri == null) {
8530                owner.removeUriPermissionsLocked(mode);
8531            } else {
8532                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8533            }
8534        }
8535    }
8536
8537    private void schedulePersistUriGrants() {
8538        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8539            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8540                    10 * DateUtils.SECOND_IN_MILLIS);
8541        }
8542    }
8543
8544    private void writeGrantedUriPermissions() {
8545        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8546
8547        // Snapshot permissions so we can persist without lock
8548        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8549        synchronized (this) {
8550            final int size = mGrantedUriPermissions.size();
8551            for (int i = 0; i < size; i++) {
8552                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8553                for (UriPermission perm : perms.values()) {
8554                    if (perm.persistedModeFlags != 0) {
8555                        persist.add(perm.snapshot());
8556                    }
8557                }
8558            }
8559        }
8560
8561        FileOutputStream fos = null;
8562        try {
8563            fos = mGrantFile.startWrite();
8564
8565            XmlSerializer out = new FastXmlSerializer();
8566            out.setOutput(fos, StandardCharsets.UTF_8.name());
8567            out.startDocument(null, true);
8568            out.startTag(null, TAG_URI_GRANTS);
8569            for (UriPermission.Snapshot perm : persist) {
8570                out.startTag(null, TAG_URI_GRANT);
8571                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8572                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8573                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8574                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8575                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8576                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8577                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8578                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8579                out.endTag(null, TAG_URI_GRANT);
8580            }
8581            out.endTag(null, TAG_URI_GRANTS);
8582            out.endDocument();
8583
8584            mGrantFile.finishWrite(fos);
8585        } catch (IOException e) {
8586            if (fos != null) {
8587                mGrantFile.failWrite(fos);
8588            }
8589        }
8590    }
8591
8592    private void readGrantedUriPermissionsLocked() {
8593        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8594
8595        final long now = System.currentTimeMillis();
8596
8597        FileInputStream fis = null;
8598        try {
8599            fis = mGrantFile.openRead();
8600            final XmlPullParser in = Xml.newPullParser();
8601            in.setInput(fis, StandardCharsets.UTF_8.name());
8602
8603            int type;
8604            while ((type = in.next()) != END_DOCUMENT) {
8605                final String tag = in.getName();
8606                if (type == START_TAG) {
8607                    if (TAG_URI_GRANT.equals(tag)) {
8608                        final int sourceUserId;
8609                        final int targetUserId;
8610                        final int userHandle = readIntAttribute(in,
8611                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8612                        if (userHandle != UserHandle.USER_NULL) {
8613                            // For backwards compatibility.
8614                            sourceUserId = userHandle;
8615                            targetUserId = userHandle;
8616                        } else {
8617                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8618                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8619                        }
8620                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8621                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8622                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8623                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8624                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8625                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8626
8627                        // Sanity check that provider still belongs to source package
8628                        final ProviderInfo pi = getProviderInfoLocked(
8629                                uri.getAuthority(), sourceUserId);
8630                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8631                            int targetUid = -1;
8632                            try {
8633                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8634                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8635                            } catch (RemoteException e) {
8636                            }
8637                            if (targetUid != -1) {
8638                                final UriPermission perm = findOrCreateUriPermissionLocked(
8639                                        sourcePkg, targetPkg, targetUid,
8640                                        new GrantUri(sourceUserId, uri, prefix));
8641                                perm.initPersistedModes(modeFlags, createdTime);
8642                            }
8643                        } else {
8644                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8645                                    + " but instead found " + pi);
8646                        }
8647                    }
8648                }
8649            }
8650        } catch (FileNotFoundException e) {
8651            // Missing grants is okay
8652        } catch (IOException e) {
8653            Slog.wtf(TAG, "Failed reading Uri grants", e);
8654        } catch (XmlPullParserException e) {
8655            Slog.wtf(TAG, "Failed reading Uri grants", e);
8656        } finally {
8657            IoUtils.closeQuietly(fis);
8658        }
8659    }
8660
8661    /**
8662     * @param uri This uri must NOT contain an embedded userId.
8663     * @param userId The userId in which the uri is to be resolved.
8664     */
8665    @Override
8666    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8667        enforceNotIsolatedCaller("takePersistableUriPermission");
8668
8669        Preconditions.checkFlagsArgument(modeFlags,
8670                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8671
8672        synchronized (this) {
8673            final int callingUid = Binder.getCallingUid();
8674            boolean persistChanged = false;
8675            GrantUri grantUri = new GrantUri(userId, uri, false);
8676
8677            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8678                    new GrantUri(userId, uri, false));
8679            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8680                    new GrantUri(userId, uri, true));
8681
8682            final boolean exactValid = (exactPerm != null)
8683                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8684            final boolean prefixValid = (prefixPerm != null)
8685                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8686
8687            if (!(exactValid || prefixValid)) {
8688                throw new SecurityException("No persistable permission grants found for UID "
8689                        + callingUid + " and Uri " + grantUri.toSafeString());
8690            }
8691
8692            if (exactValid) {
8693                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8694            }
8695            if (prefixValid) {
8696                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8697            }
8698
8699            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8700
8701            if (persistChanged) {
8702                schedulePersistUriGrants();
8703            }
8704        }
8705    }
8706
8707    /**
8708     * @param uri This uri must NOT contain an embedded userId.
8709     * @param userId The userId in which the uri is to be resolved.
8710     */
8711    @Override
8712    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8713        enforceNotIsolatedCaller("releasePersistableUriPermission");
8714
8715        Preconditions.checkFlagsArgument(modeFlags,
8716                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8717
8718        synchronized (this) {
8719            final int callingUid = Binder.getCallingUid();
8720            boolean persistChanged = false;
8721
8722            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8723                    new GrantUri(userId, uri, false));
8724            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8725                    new GrantUri(userId, uri, true));
8726            if (exactPerm == null && prefixPerm == null) {
8727                throw new SecurityException("No permission grants found for UID " + callingUid
8728                        + " and Uri " + uri.toSafeString());
8729            }
8730
8731            if (exactPerm != null) {
8732                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8733                removeUriPermissionIfNeededLocked(exactPerm);
8734            }
8735            if (prefixPerm != null) {
8736                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8737                removeUriPermissionIfNeededLocked(prefixPerm);
8738            }
8739
8740            if (persistChanged) {
8741                schedulePersistUriGrants();
8742            }
8743        }
8744    }
8745
8746    /**
8747     * Prune any older {@link UriPermission} for the given UID until outstanding
8748     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8749     *
8750     * @return if any mutations occured that require persisting.
8751     */
8752    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8753        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8754        if (perms == null) return false;
8755        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8756
8757        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8758        for (UriPermission perm : perms.values()) {
8759            if (perm.persistedModeFlags != 0) {
8760                persisted.add(perm);
8761            }
8762        }
8763
8764        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8765        if (trimCount <= 0) return false;
8766
8767        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8768        for (int i = 0; i < trimCount; i++) {
8769            final UriPermission perm = persisted.get(i);
8770
8771            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8772                    "Trimming grant created at " + perm.persistedCreateTime);
8773
8774            perm.releasePersistableModes(~0);
8775            removeUriPermissionIfNeededLocked(perm);
8776        }
8777
8778        return true;
8779    }
8780
8781    @Override
8782    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8783            String packageName, boolean incoming) {
8784        enforceNotIsolatedCaller("getPersistedUriPermissions");
8785        Preconditions.checkNotNull(packageName, "packageName");
8786
8787        final int callingUid = Binder.getCallingUid();
8788        final IPackageManager pm = AppGlobals.getPackageManager();
8789        try {
8790            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8791                    UserHandle.getUserId(callingUid));
8792            if (packageUid != callingUid) {
8793                throw new SecurityException(
8794                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8795            }
8796        } catch (RemoteException e) {
8797            throw new SecurityException("Failed to verify package name ownership");
8798        }
8799
8800        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8801        synchronized (this) {
8802            if (incoming) {
8803                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8804                        callingUid);
8805                if (perms == null) {
8806                    Slog.w(TAG, "No permission grants found for " + packageName);
8807                } else {
8808                    for (UriPermission perm : perms.values()) {
8809                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8810                            result.add(perm.buildPersistedPublicApiObject());
8811                        }
8812                    }
8813                }
8814            } else {
8815                final int size = mGrantedUriPermissions.size();
8816                for (int i = 0; i < size; i++) {
8817                    final ArrayMap<GrantUri, UriPermission> perms =
8818                            mGrantedUriPermissions.valueAt(i);
8819                    for (UriPermission perm : perms.values()) {
8820                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8821                            result.add(perm.buildPersistedPublicApiObject());
8822                        }
8823                    }
8824                }
8825            }
8826        }
8827        return new ParceledListSlice<android.content.UriPermission>(result);
8828    }
8829
8830    @Override
8831    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8832            String packageName, int userId) {
8833        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8834                "getGrantedUriPermissions");
8835
8836        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8837        synchronized (this) {
8838            final int size = mGrantedUriPermissions.size();
8839            for (int i = 0; i < size; i++) {
8840                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8841                for (UriPermission perm : perms.values()) {
8842                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8843                            && perm.persistedModeFlags != 0) {
8844                        result.add(perm.buildPersistedPublicApiObject());
8845                    }
8846                }
8847            }
8848        }
8849        return new ParceledListSlice<android.content.UriPermission>(result);
8850    }
8851
8852    @Override
8853    public void clearGrantedUriPermissions(String packageName, int userId) {
8854        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8855                "clearGrantedUriPermissions");
8856        removeUriPermissionsForPackageLocked(packageName, userId, true);
8857    }
8858
8859    @Override
8860    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8861        synchronized (this) {
8862            ProcessRecord app =
8863                who != null ? getRecordForAppLocked(who) : null;
8864            if (app == null) return;
8865
8866            Message msg = Message.obtain();
8867            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8868            msg.obj = app;
8869            msg.arg1 = waiting ? 1 : 0;
8870            mUiHandler.sendMessage(msg);
8871        }
8872    }
8873
8874    @Override
8875    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8876        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8877        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8878        outInfo.availMem = Process.getFreeMemory();
8879        outInfo.totalMem = Process.getTotalMemory();
8880        outInfo.threshold = homeAppMem;
8881        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8882        outInfo.hiddenAppThreshold = cachedAppMem;
8883        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8884                ProcessList.SERVICE_ADJ);
8885        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8886                ProcessList.VISIBLE_APP_ADJ);
8887        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8888                ProcessList.FOREGROUND_APP_ADJ);
8889    }
8890
8891    // =========================================================
8892    // TASK MANAGEMENT
8893    // =========================================================
8894
8895    @Override
8896    public List<IAppTask> getAppTasks(String callingPackage) {
8897        int callingUid = Binder.getCallingUid();
8898        long ident = Binder.clearCallingIdentity();
8899
8900        synchronized(this) {
8901            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8902            try {
8903                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8904
8905                final int N = mRecentTasks.size();
8906                for (int i = 0; i < N; i++) {
8907                    TaskRecord tr = mRecentTasks.get(i);
8908                    // Skip tasks that do not match the caller.  We don't need to verify
8909                    // callingPackage, because we are also limiting to callingUid and know
8910                    // that will limit to the correct security sandbox.
8911                    if (tr.effectiveUid != callingUid) {
8912                        continue;
8913                    }
8914                    Intent intent = tr.getBaseIntent();
8915                    if (intent == null ||
8916                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8917                        continue;
8918                    }
8919                    ActivityManager.RecentTaskInfo taskInfo =
8920                            createRecentTaskInfoFromTaskRecord(tr);
8921                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8922                    list.add(taskImpl);
8923                }
8924            } finally {
8925                Binder.restoreCallingIdentity(ident);
8926            }
8927            return list;
8928        }
8929    }
8930
8931    @Override
8932    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8933        final int callingUid = Binder.getCallingUid();
8934        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8935
8936        synchronized(this) {
8937            if (DEBUG_ALL) Slog.v(
8938                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8939
8940            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8941                    callingUid);
8942
8943            // TODO: Improve with MRU list from all ActivityStacks.
8944            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8945        }
8946
8947        return list;
8948    }
8949
8950    /**
8951     * Creates a new RecentTaskInfo from a TaskRecord.
8952     */
8953    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8954        // Update the task description to reflect any changes in the task stack
8955        tr.updateTaskDescription();
8956
8957        // Compose the recent task info
8958        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8959        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8960        rti.persistentId = tr.taskId;
8961        rti.baseIntent = new Intent(tr.getBaseIntent());
8962        rti.origActivity = tr.origActivity;
8963        rti.realActivity = tr.realActivity;
8964        rti.description = tr.lastDescription;
8965        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8966        rti.userId = tr.userId;
8967        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8968        rti.firstActiveTime = tr.firstActiveTime;
8969        rti.lastActiveTime = tr.lastActiveTime;
8970        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8971        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8972        rti.numActivities = 0;
8973        if (tr.mBounds != null) {
8974            rti.bounds = new Rect(tr.mBounds);
8975        }
8976        rti.isDockable = tr.canGoInDockedStack();
8977        rti.resizeMode = tr.mResizeMode;
8978
8979        ActivityRecord base = null;
8980        ActivityRecord top = null;
8981        ActivityRecord tmp;
8982
8983        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8984            tmp = tr.mActivities.get(i);
8985            if (tmp.finishing) {
8986                continue;
8987            }
8988            base = tmp;
8989            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8990                top = base;
8991            }
8992            rti.numActivities++;
8993        }
8994
8995        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8996        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8997
8998        return rti;
8999    }
9000
9001    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9002        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9003                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9004        if (!allowed) {
9005            if (checkPermission(android.Manifest.permission.GET_TASKS,
9006                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9007                // Temporary compatibility: some existing apps on the system image may
9008                // still be requesting the old permission and not switched to the new
9009                // one; if so, we'll still allow them full access.  This means we need
9010                // to see if they are holding the old permission and are a system app.
9011                try {
9012                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9013                        allowed = true;
9014                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9015                                + " is using old GET_TASKS but privileged; allowing");
9016                    }
9017                } catch (RemoteException e) {
9018                }
9019            }
9020        }
9021        if (!allowed) {
9022            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9023                    + " does not hold REAL_GET_TASKS; limiting output");
9024        }
9025        return allowed;
9026    }
9027
9028    @Override
9029    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9030        final int callingUid = Binder.getCallingUid();
9031        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9032                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9033
9034        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9035        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9036        synchronized (this) {
9037            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9038                    callingUid);
9039            final boolean detailed = checkCallingPermission(
9040                    android.Manifest.permission.GET_DETAILED_TASKS)
9041                    == PackageManager.PERMISSION_GRANTED;
9042
9043            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9044                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9045                return Collections.emptyList();
9046            }
9047            mRecentTasks.loadUserRecentsLocked(userId);
9048
9049            final int recentsCount = mRecentTasks.size();
9050            ArrayList<ActivityManager.RecentTaskInfo> res =
9051                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9052
9053            final Set<Integer> includedUsers;
9054            if (includeProfiles) {
9055                includedUsers = mUserController.getProfileIds(userId);
9056            } else {
9057                includedUsers = new HashSet<>();
9058            }
9059            includedUsers.add(Integer.valueOf(userId));
9060
9061            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9062                TaskRecord tr = mRecentTasks.get(i);
9063                // Only add calling user or related users recent tasks
9064                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9065                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9066                    continue;
9067                }
9068
9069                if (tr.realActivitySuspended) {
9070                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9071                    continue;
9072                }
9073
9074                // Return the entry if desired by the caller.  We always return
9075                // the first entry, because callers always expect this to be the
9076                // foreground app.  We may filter others if the caller has
9077                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9078                // we should exclude the entry.
9079
9080                if (i == 0
9081                        || withExcluded
9082                        || (tr.intent == null)
9083                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9084                                == 0)) {
9085                    if (!allowed) {
9086                        // If the caller doesn't have the GET_TASKS permission, then only
9087                        // allow them to see a small subset of tasks -- their own and home.
9088                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9089                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9090                            continue;
9091                        }
9092                    }
9093                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9094                        if (tr.stack != null && tr.stack.isHomeStack()) {
9095                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9096                                    "Skipping, home stack task: " + tr);
9097                            continue;
9098                        }
9099                    }
9100                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9101                        final ActivityStack stack = tr.stack;
9102                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9103                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9104                                    "Skipping, top task in docked stack: " + tr);
9105                            continue;
9106                        }
9107                    }
9108                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9109                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9110                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9111                                    "Skipping, pinned stack task: " + tr);
9112                            continue;
9113                        }
9114                    }
9115                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9116                        // Don't include auto remove tasks that are finished or finishing.
9117                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9118                                "Skipping, auto-remove without activity: " + tr);
9119                        continue;
9120                    }
9121                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9122                            && !tr.isAvailable) {
9123                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9124                                "Skipping, unavail real act: " + tr);
9125                        continue;
9126                    }
9127
9128                    if (!tr.mUserSetupComplete) {
9129                        // Don't include task launched while user is not done setting-up.
9130                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9131                                "Skipping, user setup not complete: " + tr);
9132                        continue;
9133                    }
9134
9135                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9136                    if (!detailed) {
9137                        rti.baseIntent.replaceExtras((Bundle)null);
9138                    }
9139
9140                    res.add(rti);
9141                    maxNum--;
9142                }
9143            }
9144            return res;
9145        }
9146    }
9147
9148    @Override
9149    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9150        synchronized (this) {
9151            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9152                    "getTaskThumbnail()");
9153            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9154                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9155            if (tr != null) {
9156                return tr.getTaskThumbnailLocked();
9157            }
9158        }
9159        return null;
9160    }
9161
9162    @Override
9163    public int addAppTask(IBinder activityToken, Intent intent,
9164            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9165        final int callingUid = Binder.getCallingUid();
9166        final long callingIdent = Binder.clearCallingIdentity();
9167
9168        try {
9169            synchronized (this) {
9170                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9171                if (r == null) {
9172                    throw new IllegalArgumentException("Activity does not exist; token="
9173                            + activityToken);
9174                }
9175                ComponentName comp = intent.getComponent();
9176                if (comp == null) {
9177                    throw new IllegalArgumentException("Intent " + intent
9178                            + " must specify explicit component");
9179                }
9180                if (thumbnail.getWidth() != mThumbnailWidth
9181                        || thumbnail.getHeight() != mThumbnailHeight) {
9182                    throw new IllegalArgumentException("Bad thumbnail size: got "
9183                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9184                            + mThumbnailWidth + "x" + mThumbnailHeight);
9185                }
9186                if (intent.getSelector() != null) {
9187                    intent.setSelector(null);
9188                }
9189                if (intent.getSourceBounds() != null) {
9190                    intent.setSourceBounds(null);
9191                }
9192                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9193                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9194                        // The caller has added this as an auto-remove task...  that makes no
9195                        // sense, so turn off auto-remove.
9196                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9197                    }
9198                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9199                    // Must be a new task.
9200                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9201                }
9202                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9203                    mLastAddedTaskActivity = null;
9204                }
9205                ActivityInfo ainfo = mLastAddedTaskActivity;
9206                if (ainfo == null) {
9207                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9208                            comp, 0, UserHandle.getUserId(callingUid));
9209                    if (ainfo.applicationInfo.uid != callingUid) {
9210                        throw new SecurityException(
9211                                "Can't add task for another application: target uid="
9212                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9213                    }
9214                }
9215
9216                // Use the full screen as the context for the task thumbnail
9217                final Point displaySize = new Point();
9218                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9219                r.task.stack.getDisplaySize(displaySize);
9220                thumbnailInfo.taskWidth = displaySize.x;
9221                thumbnailInfo.taskHeight = displaySize.y;
9222                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9223
9224                TaskRecord task = new TaskRecord(this,
9225                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9226                        ainfo, intent, description, thumbnailInfo);
9227
9228                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9229                if (trimIdx >= 0) {
9230                    // If this would have caused a trim, then we'll abort because that
9231                    // means it would be added at the end of the list but then just removed.
9232                    return INVALID_TASK_ID;
9233                }
9234
9235                final int N = mRecentTasks.size();
9236                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9237                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9238                    tr.removedFromRecents();
9239                }
9240
9241                task.inRecents = true;
9242                mRecentTasks.add(task);
9243                r.task.stack.addTask(task, false, "addAppTask");
9244
9245                task.setLastThumbnailLocked(thumbnail);
9246                task.freeLastThumbnail();
9247
9248                return task.taskId;
9249            }
9250        } finally {
9251            Binder.restoreCallingIdentity(callingIdent);
9252        }
9253    }
9254
9255    @Override
9256    public Point getAppTaskThumbnailSize() {
9257        synchronized (this) {
9258            return new Point(mThumbnailWidth,  mThumbnailHeight);
9259        }
9260    }
9261
9262    @Override
9263    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9264        synchronized (this) {
9265            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9266            if (r != null) {
9267                r.setTaskDescription(td);
9268                r.task.updateTaskDescription();
9269            }
9270        }
9271    }
9272
9273    @Override
9274    public void setTaskResizeable(int taskId, int resizeableMode) {
9275        synchronized (this) {
9276            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9277                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9278            if (task == null) {
9279                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9280                return;
9281            }
9282            if (task.mResizeMode != resizeableMode) {
9283                task.mResizeMode = resizeableMode;
9284                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9285                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9286                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9287            }
9288        }
9289    }
9290
9291    @Override
9292    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9293        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9294        long ident = Binder.clearCallingIdentity();
9295        try {
9296            synchronized (this) {
9297                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9298                if (task == null) {
9299                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9300                    return;
9301                }
9302                int stackId = task.stack.mStackId;
9303                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9304                // in crop windows resize mode or if the task size is affected by the docked stack
9305                // changing size. No need to update configuration.
9306                if (bounds != null && task.inCropWindowsResizeMode()
9307                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9308                    mWindowManager.scrollTask(task.taskId, bounds);
9309                    return;
9310                }
9311
9312                // Place the task in the right stack if it isn't there already based on
9313                // the requested bounds.
9314                // The stack transition logic is:
9315                // - a null bounds on a freeform task moves that task to fullscreen
9316                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9317                //   that task to freeform
9318                // - otherwise the task is not moved
9319                if (!StackId.isTaskResizeAllowed(stackId)) {
9320                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9321                }
9322                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9323                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9324                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9325                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9326                }
9327                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9328                if (stackId != task.stack.mStackId) {
9329                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9330                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9331                    preserveWindow = false;
9332                }
9333
9334                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9335                        false /* deferResume */);
9336            }
9337        } finally {
9338            Binder.restoreCallingIdentity(ident);
9339        }
9340    }
9341
9342    @Override
9343    public Rect getTaskBounds(int taskId) {
9344        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9345        long ident = Binder.clearCallingIdentity();
9346        Rect rect = new Rect();
9347        try {
9348            synchronized (this) {
9349                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9351                if (task == null) {
9352                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9353                    return rect;
9354                }
9355                if (task.stack != null) {
9356                    // Return the bounds from window manager since it will be adjusted for various
9357                    // things like the presense of a docked stack for tasks that aren't resizeable.
9358                    mWindowManager.getTaskBounds(task.taskId, rect);
9359                } else {
9360                    // Task isn't in window manager yet since it isn't associated with a stack.
9361                    // Return the persist value from activity manager
9362                    if (task.mBounds != null) {
9363                        rect.set(task.mBounds);
9364                    } else if (task.mLastNonFullscreenBounds != null) {
9365                        rect.set(task.mLastNonFullscreenBounds);
9366                    }
9367                }
9368            }
9369        } finally {
9370            Binder.restoreCallingIdentity(ident);
9371        }
9372        return rect;
9373    }
9374
9375    @Override
9376    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9377        if (userId != UserHandle.getCallingUserId()) {
9378            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9379                    "getTaskDescriptionIcon");
9380        }
9381        final File passedIconFile = new File(filePath);
9382        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9383                passedIconFile.getName());
9384        if (!legitIconFile.getPath().equals(filePath)
9385                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9386            throw new IllegalArgumentException("Bad file path: " + filePath
9387                    + " passed for userId " + userId);
9388        }
9389        return mRecentTasks.getTaskDescriptionIcon(filePath);
9390    }
9391
9392    @Override
9393    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9394            throws RemoteException {
9395        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9396                opts.getCustomInPlaceResId() == 0) {
9397            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9398                    "with valid animation");
9399        }
9400        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9401        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9402                opts.getCustomInPlaceResId());
9403        mWindowManager.executeAppTransition();
9404    }
9405
9406    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9407            boolean removeFromRecents) {
9408        if (removeFromRecents) {
9409            mRecentTasks.remove(tr);
9410            tr.removedFromRecents();
9411        }
9412        ComponentName component = tr.getBaseIntent().getComponent();
9413        if (component == null) {
9414            Slog.w(TAG, "No component for base intent of task: " + tr);
9415            return;
9416        }
9417
9418        // Find any running services associated with this app and stop if needed.
9419        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9420
9421        if (!killProcess) {
9422            return;
9423        }
9424
9425        // Determine if the process(es) for this task should be killed.
9426        final String pkg = component.getPackageName();
9427        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9428        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9429        for (int i = 0; i < pmap.size(); i++) {
9430
9431            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9432            for (int j = 0; j < uids.size(); j++) {
9433                ProcessRecord proc = uids.valueAt(j);
9434                if (proc.userId != tr.userId) {
9435                    // Don't kill process for a different user.
9436                    continue;
9437                }
9438                if (proc == mHomeProcess) {
9439                    // Don't kill the home process along with tasks from the same package.
9440                    continue;
9441                }
9442                if (!proc.pkgList.containsKey(pkg)) {
9443                    // Don't kill process that is not associated with this task.
9444                    continue;
9445                }
9446
9447                for (int k = 0; k < proc.activities.size(); k++) {
9448                    TaskRecord otherTask = proc.activities.get(k).task;
9449                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9450                        // Don't kill process(es) that has an activity in a different task that is
9451                        // also in recents.
9452                        return;
9453                    }
9454                }
9455
9456                if (proc.foregroundServices) {
9457                    // Don't kill process(es) with foreground service.
9458                    return;
9459                }
9460
9461                // Add process to kill list.
9462                procsToKill.add(proc);
9463            }
9464        }
9465
9466        // Kill the running processes.
9467        for (int i = 0; i < procsToKill.size(); i++) {
9468            ProcessRecord pr = procsToKill.get(i);
9469            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9470                    && pr.curReceiver == null) {
9471                pr.kill("remove task", true);
9472            } else {
9473                // We delay killing processes that are not in the background or running a receiver.
9474                pr.waitingToKill = "remove task";
9475            }
9476        }
9477    }
9478
9479    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9480        // Remove all tasks with activities in the specified package from the list of recent tasks
9481        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9482            TaskRecord tr = mRecentTasks.get(i);
9483            if (tr.userId != userId) continue;
9484
9485            ComponentName cn = tr.intent.getComponent();
9486            if (cn != null && cn.getPackageName().equals(packageName)) {
9487                // If the package name matches, remove the task.
9488                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9489            }
9490        }
9491    }
9492
9493    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9494            int userId) {
9495
9496        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9497            TaskRecord tr = mRecentTasks.get(i);
9498            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9499                continue;
9500            }
9501
9502            ComponentName cn = tr.intent.getComponent();
9503            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9504                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9505            if (sameComponent) {
9506                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9507            }
9508        }
9509    }
9510
9511    /**
9512     * Removes the task with the specified task id.
9513     *
9514     * @param taskId Identifier of the task to be removed.
9515     * @param killProcess Kill any process associated with the task if possible.
9516     * @param removeFromRecents Whether to also remove the task from recents.
9517     * @return Returns true if the given task was found and removed.
9518     */
9519    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9520            boolean removeFromRecents) {
9521        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9522                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9523        if (tr != null) {
9524            tr.removeTaskActivitiesLocked();
9525            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9526            if (tr.isPersistable) {
9527                notifyTaskPersisterLocked(null, true);
9528            }
9529            return true;
9530        }
9531        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9532        return false;
9533    }
9534
9535    @Override
9536    public void removeStack(int stackId) {
9537        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9538        if (stackId == HOME_STACK_ID) {
9539            throw new IllegalArgumentException("Removing home stack is not allowed.");
9540        }
9541
9542        synchronized (this) {
9543            final long ident = Binder.clearCallingIdentity();
9544            try {
9545                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9546                if (stack == null) {
9547                    return;
9548                }
9549                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9550                for (int i = tasks.size() - 1; i >= 0; i--) {
9551                    removeTaskByIdLocked(
9552                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9553                }
9554            } finally {
9555                Binder.restoreCallingIdentity(ident);
9556            }
9557        }
9558    }
9559
9560    @Override
9561    public boolean removeTask(int taskId) {
9562        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9563        synchronized (this) {
9564            final long ident = Binder.clearCallingIdentity();
9565            try {
9566                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9567            } finally {
9568                Binder.restoreCallingIdentity(ident);
9569            }
9570        }
9571    }
9572
9573    /**
9574     * TODO: Add mController hook
9575     */
9576    @Override
9577    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9578        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9579
9580        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9581        synchronized(this) {
9582            moveTaskToFrontLocked(taskId, flags, bOptions);
9583        }
9584    }
9585
9586    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9587        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9588
9589        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9590                Binder.getCallingUid(), -1, -1, "Task to front")) {
9591            ActivityOptions.abort(options);
9592            return;
9593        }
9594        final long origId = Binder.clearCallingIdentity();
9595        try {
9596            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9597            if (task == null) {
9598                Slog.d(TAG, "Could not find task for id: "+ taskId);
9599                return;
9600            }
9601            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9602                mStackSupervisor.showLockTaskToast();
9603                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9604                return;
9605            }
9606            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9607            if (prev != null && prev.isRecentsActivity()) {
9608                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9609            }
9610            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9611                    false /* forceNonResizable */);
9612        } finally {
9613            Binder.restoreCallingIdentity(origId);
9614        }
9615        ActivityOptions.abort(options);
9616    }
9617
9618    /**
9619     * Moves an activity, and all of the other activities within the same task, to the bottom
9620     * of the history stack.  The activity's order within the task is unchanged.
9621     *
9622     * @param token A reference to the activity we wish to move
9623     * @param nonRoot If false then this only works if the activity is the root
9624     *                of a task; if true it will work for any activity in a task.
9625     * @return Returns true if the move completed, false if not.
9626     */
9627    @Override
9628    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9629        enforceNotIsolatedCaller("moveActivityTaskToBack");
9630        synchronized(this) {
9631            final long origId = Binder.clearCallingIdentity();
9632            try {
9633                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9634                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9635                if (task != null) {
9636                    if (mStackSupervisor.isLockedTask(task)) {
9637                        mStackSupervisor.showLockTaskToast();
9638                        return false;
9639                    }
9640                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9641                }
9642            } finally {
9643                Binder.restoreCallingIdentity(origId);
9644            }
9645        }
9646        return false;
9647    }
9648
9649    @Override
9650    public void moveTaskBackwards(int task) {
9651        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9652                "moveTaskBackwards()");
9653
9654        synchronized(this) {
9655            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9656                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9657                return;
9658            }
9659            final long origId = Binder.clearCallingIdentity();
9660            moveTaskBackwardsLocked(task);
9661            Binder.restoreCallingIdentity(origId);
9662        }
9663    }
9664
9665    private final void moveTaskBackwardsLocked(int task) {
9666        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9667    }
9668
9669    @Override
9670    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9671            IActivityContainerCallback callback) throws RemoteException {
9672        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9673        synchronized (this) {
9674            if (parentActivityToken == null) {
9675                throw new IllegalArgumentException("parent token must not be null");
9676            }
9677            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9678            if (r == null) {
9679                return null;
9680            }
9681            if (callback == null) {
9682                throw new IllegalArgumentException("callback must not be null");
9683            }
9684            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9685        }
9686    }
9687
9688    @Override
9689    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9690        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9691        synchronized (this) {
9692            mStackSupervisor.deleteActivityContainer(container);
9693        }
9694    }
9695
9696    @Override
9697    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9698        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9699        synchronized (this) {
9700            final int stackId = mStackSupervisor.getNextStackId();
9701            final ActivityStack stack =
9702                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9703            if (stack == null) {
9704                return null;
9705            }
9706            return stack.mActivityContainer;
9707        }
9708    }
9709
9710    @Override
9711    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9712        synchronized (this) {
9713            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9714            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9715                return stack.mActivityContainer.getDisplayId();
9716            }
9717            return Display.DEFAULT_DISPLAY;
9718        }
9719    }
9720
9721    @Override
9722    public int getActivityStackId(IBinder token) throws RemoteException {
9723        synchronized (this) {
9724            ActivityStack stack = ActivityRecord.getStackLocked(token);
9725            if (stack == null) {
9726                return INVALID_STACK_ID;
9727            }
9728            return stack.mStackId;
9729        }
9730    }
9731
9732    @Override
9733    public void exitFreeformMode(IBinder token) throws RemoteException {
9734        synchronized (this) {
9735            long ident = Binder.clearCallingIdentity();
9736            try {
9737                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9738                if (r == null) {
9739                    throw new IllegalArgumentException(
9740                            "exitFreeformMode: No activity record matching token=" + token);
9741                }
9742                final ActivityStack stack = r.getStackLocked(token);
9743                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9744                    throw new IllegalStateException(
9745                            "exitFreeformMode: You can only go fullscreen from freeform.");
9746                }
9747                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9748                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9749                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9750            } finally {
9751                Binder.restoreCallingIdentity(ident);
9752            }
9753        }
9754    }
9755
9756    @Override
9757    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9758        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9759        if (stackId == HOME_STACK_ID) {
9760            throw new IllegalArgumentException(
9761                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9762        }
9763        synchronized (this) {
9764            long ident = Binder.clearCallingIdentity();
9765            try {
9766                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9767                        + " to stackId=" + stackId + " toTop=" + toTop);
9768                if (stackId == DOCKED_STACK_ID) {
9769                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9770                            null /* initialBounds */);
9771                }
9772                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9773                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9774                if (result && stackId == DOCKED_STACK_ID) {
9775                    // If task moved to docked stack - show recents if needed.
9776                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9777                            "moveTaskToDockedStack");
9778                }
9779            } finally {
9780                Binder.restoreCallingIdentity(ident);
9781            }
9782        }
9783    }
9784
9785    @Override
9786    public void swapDockedAndFullscreenStack() throws RemoteException {
9787        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9788        synchronized (this) {
9789            long ident = Binder.clearCallingIdentity();
9790            try {
9791                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9792                        FULLSCREEN_WORKSPACE_STACK_ID);
9793                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9794                        : null;
9795                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9796                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9797                        : null;
9798                if (topTask == null || tasks == null || tasks.size() == 0) {
9799                    Slog.w(TAG,
9800                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9801                    return;
9802                }
9803
9804                // TODO: App transition
9805                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9806
9807                // Defer the resume so resume/pausing while moving stacks is dangerous.
9808                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9809                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9810                        ANIMATE, true /* deferResume */);
9811                final int size = tasks.size();
9812                for (int i = 0; i < size; i++) {
9813                    final int id = tasks.get(i).taskId;
9814                    if (id == topTask.taskId) {
9815                        continue;
9816                    }
9817                    mStackSupervisor.moveTaskToStackLocked(id,
9818                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9819                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9820                }
9821
9822                // Because we deferred the resume, to avoid conflicts with stack switches while
9823                // resuming, we need to do it after all the tasks are moved.
9824                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9825                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9826
9827                mWindowManager.executeAppTransition();
9828            } finally {
9829                Binder.restoreCallingIdentity(ident);
9830            }
9831        }
9832    }
9833
9834    /**
9835     * Moves the input task to the docked stack.
9836     *
9837     * @param taskId Id of task to move.
9838     * @param createMode The mode the docked stack should be created in if it doesn't exist
9839     *                   already. See
9840     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9841     *                   and
9842     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9843     * @param toTop If the task and stack should be moved to the top.
9844     * @param animate Whether we should play an animation for the moving the task
9845     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9846     *                      docked stack. Pass {@code null} to use default bounds.
9847     */
9848    @Override
9849    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9850            Rect initialBounds, boolean moveHomeStackFront) {
9851        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9852        synchronized (this) {
9853            long ident = Binder.clearCallingIdentity();
9854            try {
9855                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9856                        + " to createMode=" + createMode + " toTop=" + toTop);
9857                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9858                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9859                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9860                        animate, DEFER_RESUME);
9861                if (moved) {
9862                    if (moveHomeStackFront) {
9863                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9864                    }
9865                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9866                }
9867                return moved;
9868            } finally {
9869                Binder.restoreCallingIdentity(ident);
9870            }
9871        }
9872    }
9873
9874    /**
9875     * Moves the top activity in the input stackId to the pinned stack.
9876     *
9877     * @param stackId Id of stack to move the top activity to pinned stack.
9878     * @param bounds Bounds to use for pinned stack.
9879     *
9880     * @return True if the top activity of the input stack was successfully moved to the pinned
9881     *          stack.
9882     */
9883    @Override
9884    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9885        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9886        synchronized (this) {
9887            if (!mSupportsPictureInPicture) {
9888                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9889                        + "Device doesn't support picture-in-pciture mode");
9890            }
9891
9892            long ident = Binder.clearCallingIdentity();
9893            try {
9894                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899    }
9900
9901    @Override
9902    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9903            boolean preserveWindows, boolean animate, int animationDuration) {
9904        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9905        long ident = Binder.clearCallingIdentity();
9906        try {
9907            synchronized (this) {
9908                if (animate) {
9909                    if (stackId == PINNED_STACK_ID) {
9910                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9911                    } else {
9912                        throw new IllegalArgumentException("Stack: " + stackId
9913                                + " doesn't support animated resize.");
9914                    }
9915                } else {
9916                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9917                            null /* tempTaskInsetBounds */, preserveWindows,
9918                            allowResizeInDockedMode, !DEFER_RESUME);
9919                }
9920            }
9921        } finally {
9922            Binder.restoreCallingIdentity(ident);
9923        }
9924    }
9925
9926    @Override
9927    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9928            Rect tempDockedTaskInsetBounds,
9929            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9930        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9931                "resizeDockedStack()");
9932        long ident = Binder.clearCallingIdentity();
9933        try {
9934            synchronized (this) {
9935                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9936                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9937                        PRESERVE_WINDOWS);
9938            }
9939        } finally {
9940            Binder.restoreCallingIdentity(ident);
9941        }
9942    }
9943
9944    @Override
9945    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9946        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9947                "resizePinnedStack()");
9948        final long ident = Binder.clearCallingIdentity();
9949        try {
9950            synchronized (this) {
9951                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9952            }
9953        } finally {
9954            Binder.restoreCallingIdentity(ident);
9955        }
9956    }
9957
9958    @Override
9959    public void positionTaskInStack(int taskId, int stackId, int position) {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9961        if (stackId == HOME_STACK_ID) {
9962            throw new IllegalArgumentException(
9963                    "positionTaskInStack: Attempt to change the position of task "
9964                    + taskId + " in/to home stack");
9965        }
9966        synchronized (this) {
9967            long ident = Binder.clearCallingIdentity();
9968            try {
9969                if (DEBUG_STACK) Slog.d(TAG_STACK,
9970                        "positionTaskInStack: positioning task=" + taskId
9971                        + " in stackId=" + stackId + " at position=" + position);
9972                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9973            } finally {
9974                Binder.restoreCallingIdentity(ident);
9975            }
9976        }
9977    }
9978
9979    @Override
9980    public List<StackInfo> getAllStackInfos() {
9981        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9982        long ident = Binder.clearCallingIdentity();
9983        try {
9984            synchronized (this) {
9985                return mStackSupervisor.getAllStackInfosLocked();
9986            }
9987        } finally {
9988            Binder.restoreCallingIdentity(ident);
9989        }
9990    }
9991
9992    @Override
9993    public StackInfo getStackInfo(int stackId) {
9994        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9995        long ident = Binder.clearCallingIdentity();
9996        try {
9997            synchronized (this) {
9998                return mStackSupervisor.getStackInfoLocked(stackId);
9999            }
10000        } finally {
10001            Binder.restoreCallingIdentity(ident);
10002        }
10003    }
10004
10005    @Override
10006    public boolean isInHomeStack(int taskId) {
10007        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10008        long ident = Binder.clearCallingIdentity();
10009        try {
10010            synchronized (this) {
10011                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10012                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10013                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10014            }
10015        } finally {
10016            Binder.restoreCallingIdentity(ident);
10017        }
10018    }
10019
10020    @Override
10021    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10022        synchronized(this) {
10023            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10024        }
10025    }
10026
10027    @Override
10028    public void updateDeviceOwner(String packageName) {
10029        final int callingUid = Binder.getCallingUid();
10030        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10031            throw new SecurityException("updateDeviceOwner called from non-system process");
10032        }
10033        synchronized (this) {
10034            mDeviceOwnerName = packageName;
10035        }
10036    }
10037
10038    @Override
10039    public void updateLockTaskPackages(int userId, String[] packages) {
10040        final int callingUid = Binder.getCallingUid();
10041        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10042            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10043                    "updateLockTaskPackages()");
10044        }
10045        synchronized (this) {
10046            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10047                    Arrays.toString(packages));
10048            mLockTaskPackages.put(userId, packages);
10049            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10050        }
10051    }
10052
10053
10054    void startLockTaskModeLocked(TaskRecord task) {
10055        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10056        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10057            return;
10058        }
10059
10060        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10061        // is initiated by system after the pinning request was shown and locked mode is initiated
10062        // by an authorized app directly
10063        final int callingUid = Binder.getCallingUid();
10064        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10065        long ident = Binder.clearCallingIdentity();
10066        try {
10067            if (!isSystemInitiated) {
10068                task.mLockTaskUid = callingUid;
10069                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10070                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10071                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10072                    StatusBarManagerInternal statusBarManager =
10073                            LocalServices.getService(StatusBarManagerInternal.class);
10074                    if (statusBarManager != null) {
10075                        statusBarManager.showScreenPinningRequest(task.taskId);
10076                    }
10077                    return;
10078                }
10079
10080                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10081                if (stack == null || task != stack.topTask()) {
10082                    throw new IllegalArgumentException("Invalid task, not in foreground");
10083                }
10084            }
10085            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10086                    "Locking fully");
10087            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10088                    ActivityManager.LOCK_TASK_MODE_PINNED :
10089                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10090                    "startLockTask", true);
10091        } finally {
10092            Binder.restoreCallingIdentity(ident);
10093        }
10094    }
10095
10096    @Override
10097    public void startLockTaskMode(int taskId) {
10098        synchronized (this) {
10099            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10100            if (task != null) {
10101                startLockTaskModeLocked(task);
10102            }
10103        }
10104    }
10105
10106    @Override
10107    public void startLockTaskMode(IBinder token) {
10108        synchronized (this) {
10109            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10110            if (r == null) {
10111                return;
10112            }
10113            final TaskRecord task = r.task;
10114            if (task != null) {
10115                startLockTaskModeLocked(task);
10116            }
10117        }
10118    }
10119
10120    @Override
10121    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10122        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10123        // This makes inner call to look as if it was initiated by system.
10124        long ident = Binder.clearCallingIdentity();
10125        try {
10126            synchronized (this) {
10127                startLockTaskMode(taskId);
10128            }
10129        } finally {
10130            Binder.restoreCallingIdentity(ident);
10131        }
10132    }
10133
10134    @Override
10135    public void stopLockTaskMode() {
10136        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10137        if (lockTask == null) {
10138            // Our work here is done.
10139            return;
10140        }
10141
10142        final int callingUid = Binder.getCallingUid();
10143        final int lockTaskUid = lockTask.mLockTaskUid;
10144        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10145        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10146            // Done.
10147            return;
10148        } else {
10149            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10150            // It is possible lockTaskMode was started by the system process because
10151            // android:lockTaskMode is set to a locking value in the application manifest
10152            // instead of the app calling startLockTaskMode. In this case
10153            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10154            // {@link TaskRecord.effectiveUid} instead. Also caller with
10155            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10156            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10157                    && callingUid != lockTaskUid
10158                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10159                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10160                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10161            }
10162        }
10163        long ident = Binder.clearCallingIdentity();
10164        try {
10165            Log.d(TAG, "stopLockTaskMode");
10166            // Stop lock task
10167            synchronized (this) {
10168                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10169                        "stopLockTask", true);
10170            }
10171            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10172            if (tm != null) {
10173                tm.showInCallScreen(false);
10174            }
10175        } finally {
10176            Binder.restoreCallingIdentity(ident);
10177        }
10178    }
10179
10180    /**
10181     * This API should be called by SystemUI only when user perform certain action to dismiss
10182     * lock task mode. We should only dismiss pinned lock task mode in this case.
10183     */
10184    @Override
10185    public void stopSystemLockTaskMode() throws RemoteException {
10186        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10187            stopLockTaskMode();
10188        } else {
10189            mStackSupervisor.showLockTaskToast();
10190        }
10191    }
10192
10193    @Override
10194    public boolean isInLockTaskMode() {
10195        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10196    }
10197
10198    @Override
10199    public int getLockTaskModeState() {
10200        synchronized (this) {
10201            return mStackSupervisor.getLockTaskModeState();
10202        }
10203    }
10204
10205    @Override
10206    public void showLockTaskEscapeMessage(IBinder token) {
10207        synchronized (this) {
10208            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10209            if (r == null) {
10210                return;
10211            }
10212            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10213        }
10214    }
10215
10216    // =========================================================
10217    // CONTENT PROVIDERS
10218    // =========================================================
10219
10220    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10221        List<ProviderInfo> providers = null;
10222        try {
10223            providers = AppGlobals.getPackageManager()
10224                    .queryContentProviders(app.processName, app.uid,
10225                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10226                                    | MATCH_DEBUG_TRIAGED_MISSING)
10227                    .getList();
10228        } catch (RemoteException ex) {
10229        }
10230        if (DEBUG_MU) Slog.v(TAG_MU,
10231                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10232        int userId = app.userId;
10233        if (providers != null) {
10234            int N = providers.size();
10235            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10236            for (int i=0; i<N; i++) {
10237                // TODO: keep logic in sync with installEncryptionUnawareProviders
10238                ProviderInfo cpi =
10239                    (ProviderInfo)providers.get(i);
10240                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10241                        cpi.name, cpi.flags);
10242                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10243                    // This is a singleton provider, but a user besides the
10244                    // default user is asking to initialize a process it runs
10245                    // in...  well, no, it doesn't actually run in this process,
10246                    // it runs in the process of the default user.  Get rid of it.
10247                    providers.remove(i);
10248                    N--;
10249                    i--;
10250                    continue;
10251                }
10252
10253                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10254                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10255                if (cpr == null) {
10256                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10257                    mProviderMap.putProviderByClass(comp, cpr);
10258                }
10259                if (DEBUG_MU) Slog.v(TAG_MU,
10260                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10261                app.pubProviders.put(cpi.name, cpr);
10262                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10263                    // Don't add this if it is a platform component that is marked
10264                    // to run in multiple processes, because this is actually
10265                    // part of the framework so doesn't make sense to track as a
10266                    // separate apk in the process.
10267                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10268                            mProcessStats);
10269                }
10270                notifyPackageUse(cpi.applicationInfo.packageName,
10271                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10272            }
10273        }
10274        return providers;
10275    }
10276
10277    /**
10278     * Check if {@link ProcessRecord} has a possible chance at accessing the
10279     * given {@link ProviderInfo}. Final permission checking is always done
10280     * in {@link ContentProvider}.
10281     */
10282    private final String checkContentProviderPermissionLocked(
10283            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10284        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10285        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10286        boolean checkedGrants = false;
10287        if (checkUser) {
10288            // Looking for cross-user grants before enforcing the typical cross-users permissions
10289            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10290            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10291                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10292                    return null;
10293                }
10294                checkedGrants = true;
10295            }
10296            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10297                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10298            if (userId != tmpTargetUserId) {
10299                // When we actually went to determine the final targer user ID, this ended
10300                // up different than our initial check for the authority.  This is because
10301                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10302                // SELF.  So we need to re-check the grants again.
10303                checkedGrants = false;
10304            }
10305        }
10306        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10307                cpi.applicationInfo.uid, cpi.exported)
10308                == PackageManager.PERMISSION_GRANTED) {
10309            return null;
10310        }
10311        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10312                cpi.applicationInfo.uid, cpi.exported)
10313                == PackageManager.PERMISSION_GRANTED) {
10314            return null;
10315        }
10316
10317        PathPermission[] pps = cpi.pathPermissions;
10318        if (pps != null) {
10319            int i = pps.length;
10320            while (i > 0) {
10321                i--;
10322                PathPermission pp = pps[i];
10323                String pprperm = pp.getReadPermission();
10324                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10325                        cpi.applicationInfo.uid, cpi.exported)
10326                        == PackageManager.PERMISSION_GRANTED) {
10327                    return null;
10328                }
10329                String ppwperm = pp.getWritePermission();
10330                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10331                        cpi.applicationInfo.uid, cpi.exported)
10332                        == PackageManager.PERMISSION_GRANTED) {
10333                    return null;
10334                }
10335            }
10336        }
10337        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10338            return null;
10339        }
10340
10341        String msg;
10342        if (!cpi.exported) {
10343            msg = "Permission Denial: opening provider " + cpi.name
10344                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10345                    + ", uid=" + callingUid + ") that is not exported from uid "
10346                    + cpi.applicationInfo.uid;
10347        } else {
10348            msg = "Permission Denial: opening provider " + cpi.name
10349                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10350                    + ", uid=" + callingUid + ") requires "
10351                    + cpi.readPermission + " or " + cpi.writePermission;
10352        }
10353        Slog.w(TAG, msg);
10354        return msg;
10355    }
10356
10357    /**
10358     * Returns if the ContentProvider has granted a uri to callingUid
10359     */
10360    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10361        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10362        if (perms != null) {
10363            for (int i=perms.size()-1; i>=0; i--) {
10364                GrantUri grantUri = perms.keyAt(i);
10365                if (grantUri.sourceUserId == userId || !checkUser) {
10366                    if (matchesProvider(grantUri.uri, cpi)) {
10367                        return true;
10368                    }
10369                }
10370            }
10371        }
10372        return false;
10373    }
10374
10375    /**
10376     * Returns true if the uri authority is one of the authorities specified in the provider.
10377     */
10378    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10379        String uriAuth = uri.getAuthority();
10380        String cpiAuth = cpi.authority;
10381        if (cpiAuth.indexOf(';') == -1) {
10382            return cpiAuth.equals(uriAuth);
10383        }
10384        String[] cpiAuths = cpiAuth.split(";");
10385        int length = cpiAuths.length;
10386        for (int i = 0; i < length; i++) {
10387            if (cpiAuths[i].equals(uriAuth)) return true;
10388        }
10389        return false;
10390    }
10391
10392    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10393            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10394        if (r != null) {
10395            for (int i=0; i<r.conProviders.size(); i++) {
10396                ContentProviderConnection conn = r.conProviders.get(i);
10397                if (conn.provider == cpr) {
10398                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10399                            "Adding provider requested by "
10400                            + r.processName + " from process "
10401                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10402                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10403                    if (stable) {
10404                        conn.stableCount++;
10405                        conn.numStableIncs++;
10406                    } else {
10407                        conn.unstableCount++;
10408                        conn.numUnstableIncs++;
10409                    }
10410                    return conn;
10411                }
10412            }
10413            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10414            if (stable) {
10415                conn.stableCount = 1;
10416                conn.numStableIncs = 1;
10417            } else {
10418                conn.unstableCount = 1;
10419                conn.numUnstableIncs = 1;
10420            }
10421            cpr.connections.add(conn);
10422            r.conProviders.add(conn);
10423            startAssociationLocked(r.uid, r.processName, r.curProcState,
10424                    cpr.uid, cpr.name, cpr.info.processName);
10425            return conn;
10426        }
10427        cpr.addExternalProcessHandleLocked(externalProcessToken);
10428        return null;
10429    }
10430
10431    boolean decProviderCountLocked(ContentProviderConnection conn,
10432            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433        if (conn != null) {
10434            cpr = conn.provider;
10435            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10436                    "Removing provider requested by "
10437                    + conn.client.processName + " from process "
10438                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10439                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10440            if (stable) {
10441                conn.stableCount--;
10442            } else {
10443                conn.unstableCount--;
10444            }
10445            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10446                cpr.connections.remove(conn);
10447                conn.client.conProviders.remove(conn);
10448                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10449                    // The client is more important than last activity -- note the time this
10450                    // is happening, so we keep the old provider process around a bit as last
10451                    // activity to avoid thrashing it.
10452                    if (cpr.proc != null) {
10453                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10454                    }
10455                }
10456                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10457                return true;
10458            }
10459            return false;
10460        }
10461        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10462        return false;
10463    }
10464
10465    private void checkTime(long startTime, String where) {
10466        long now = SystemClock.uptimeMillis();
10467        if ((now-startTime) > 50) {
10468            // If we are taking more than 50ms, log about it.
10469            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10470        }
10471    }
10472
10473    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10474            String name, IBinder token, boolean stable, int userId) {
10475        ContentProviderRecord cpr;
10476        ContentProviderConnection conn = null;
10477        ProviderInfo cpi = null;
10478
10479        synchronized(this) {
10480            long startTime = SystemClock.uptimeMillis();
10481
10482            ProcessRecord r = null;
10483            if (caller != null) {
10484                r = getRecordForAppLocked(caller);
10485                if (r == null) {
10486                    throw new SecurityException(
10487                            "Unable to find app for caller " + caller
10488                          + " (pid=" + Binder.getCallingPid()
10489                          + ") when getting content provider " + name);
10490                }
10491            }
10492
10493            boolean checkCrossUser = true;
10494
10495            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10496
10497            // First check if this content provider has been published...
10498            cpr = mProviderMap.getProviderByName(name, userId);
10499            // If that didn't work, check if it exists for user 0 and then
10500            // verify that it's a singleton provider before using it.
10501            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10502                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10503                if (cpr != null) {
10504                    cpi = cpr.info;
10505                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10506                            cpi.name, cpi.flags)
10507                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10508                        userId = UserHandle.USER_SYSTEM;
10509                        checkCrossUser = false;
10510                    } else {
10511                        cpr = null;
10512                        cpi = null;
10513                    }
10514                }
10515            }
10516
10517            boolean providerRunning = cpr != null;
10518            if (providerRunning) {
10519                cpi = cpr.info;
10520                String msg;
10521                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10522                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10523                        != null) {
10524                    throw new SecurityException(msg);
10525                }
10526                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10527
10528                if (r != null && cpr.canRunHere(r)) {
10529                    // This provider has been published or is in the process
10530                    // of being published...  but it is also allowed to run
10531                    // in the caller's process, so don't make a connection
10532                    // and just let the caller instantiate its own instance.
10533                    ContentProviderHolder holder = cpr.newHolder(null);
10534                    // don't give caller the provider object, it needs
10535                    // to make its own.
10536                    holder.provider = null;
10537                    return holder;
10538                }
10539
10540                final long origId = Binder.clearCallingIdentity();
10541
10542                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10543
10544                // In this case the provider instance already exists, so we can
10545                // return it right away.
10546                conn = incProviderCountLocked(r, cpr, token, stable);
10547                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10548                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10549                        // If this is a perceptible app accessing the provider,
10550                        // make sure to count it as being accessed and thus
10551                        // back up on the LRU list.  This is good because
10552                        // content providers are often expensive to start.
10553                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10554                        updateLruProcessLocked(cpr.proc, false, null);
10555                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10556                    }
10557                }
10558
10559                if (cpr.proc != null) {
10560                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10561                    boolean success = updateOomAdjLocked(cpr.proc);
10562                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10563                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10564                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10565                    // NOTE: there is still a race here where a signal could be
10566                    // pending on the process even though we managed to update its
10567                    // adj level.  Not sure what to do about this, but at least
10568                    // the race is now smaller.
10569                    if (!success) {
10570                        // Uh oh...  it looks like the provider's process
10571                        // has been killed on us.  We need to wait for a new
10572                        // process to be started, and make sure its death
10573                        // doesn't kill our process.
10574                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10575                                + " is crashing; detaching " + r);
10576                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10577                        checkTime(startTime, "getContentProviderImpl: before appDied");
10578                        appDiedLocked(cpr.proc);
10579                        checkTime(startTime, "getContentProviderImpl: after appDied");
10580                        if (!lastRef) {
10581                            // This wasn't the last ref our process had on
10582                            // the provider...  we have now been killed, bail.
10583                            return null;
10584                        }
10585                        providerRunning = false;
10586                        conn = null;
10587                    }
10588                }
10589
10590                Binder.restoreCallingIdentity(origId);
10591            }
10592
10593            if (!providerRunning) {
10594                try {
10595                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10596                    cpi = AppGlobals.getPackageManager().
10597                        resolveContentProvider(name,
10598                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10599                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10600                } catch (RemoteException ex) {
10601                }
10602                if (cpi == null) {
10603                    return null;
10604                }
10605                // If the provider is a singleton AND
10606                // (it's a call within the same user || the provider is a
10607                // privileged app)
10608                // Then allow connecting to the singleton provider
10609                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10610                        cpi.name, cpi.flags)
10611                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10612                if (singleton) {
10613                    userId = UserHandle.USER_SYSTEM;
10614                }
10615                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10616                checkTime(startTime, "getContentProviderImpl: got app info for user");
10617
10618                String msg;
10619                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10620                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10621                        != null) {
10622                    throw new SecurityException(msg);
10623                }
10624                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10625
10626                if (!mProcessesReady
10627                        && !cpi.processName.equals("system")) {
10628                    // If this content provider does not run in the system
10629                    // process, and the system is not yet ready to run other
10630                    // processes, then fail fast instead of hanging.
10631                    throw new IllegalArgumentException(
10632                            "Attempt to launch content provider before system ready");
10633                }
10634
10635                // Make sure that the user who owns this provider is running.  If not,
10636                // we don't want to allow it to run.
10637                if (!mUserController.isUserRunningLocked(userId, 0)) {
10638                    Slog.w(TAG, "Unable to launch app "
10639                            + cpi.applicationInfo.packageName + "/"
10640                            + cpi.applicationInfo.uid + " for provider "
10641                            + name + ": user " + userId + " is stopped");
10642                    return null;
10643                }
10644
10645                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10646                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10647                cpr = mProviderMap.getProviderByClass(comp, userId);
10648                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10649                final boolean firstClass = cpr == null;
10650                if (firstClass) {
10651                    final long ident = Binder.clearCallingIdentity();
10652
10653                    // If permissions need a review before any of the app components can run,
10654                    // we return no provider and launch a review activity if the calling app
10655                    // is in the foreground.
10656                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10657                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10658                            return null;
10659                        }
10660                    }
10661
10662                    try {
10663                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10664                        ApplicationInfo ai =
10665                            AppGlobals.getPackageManager().
10666                                getApplicationInfo(
10667                                        cpi.applicationInfo.packageName,
10668                                        STOCK_PM_FLAGS, userId);
10669                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10670                        if (ai == null) {
10671                            Slog.w(TAG, "No package info for content provider "
10672                                    + cpi.name);
10673                            return null;
10674                        }
10675                        ai = getAppInfoForUser(ai, userId);
10676                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10677                    } catch (RemoteException ex) {
10678                        // pm is in same process, this will never happen.
10679                    } finally {
10680                        Binder.restoreCallingIdentity(ident);
10681                    }
10682                }
10683
10684                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10685
10686                if (r != null && cpr.canRunHere(r)) {
10687                    // If this is a multiprocess provider, then just return its
10688                    // info and allow the caller to instantiate it.  Only do
10689                    // this if the provider is the same user as the caller's
10690                    // process, or can run as root (so can be in any process).
10691                    return cpr.newHolder(null);
10692                }
10693
10694                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10695                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10696                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10697
10698                // This is single process, and our app is now connecting to it.
10699                // See if we are already in the process of launching this
10700                // provider.
10701                final int N = mLaunchingProviders.size();
10702                int i;
10703                for (i = 0; i < N; i++) {
10704                    if (mLaunchingProviders.get(i) == cpr) {
10705                        break;
10706                    }
10707                }
10708
10709                // If the provider is not already being launched, then get it
10710                // started.
10711                if (i >= N) {
10712                    final long origId = Binder.clearCallingIdentity();
10713
10714                    try {
10715                        // Content provider is now in use, its package can't be stopped.
10716                        try {
10717                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10718                            AppGlobals.getPackageManager().setPackageStoppedState(
10719                                    cpr.appInfo.packageName, false, userId);
10720                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10721                        } catch (RemoteException e) {
10722                        } catch (IllegalArgumentException e) {
10723                            Slog.w(TAG, "Failed trying to unstop package "
10724                                    + cpr.appInfo.packageName + ": " + e);
10725                        }
10726
10727                        // Use existing process if already started
10728                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10729                        ProcessRecord proc = getProcessRecordLocked(
10730                                cpi.processName, cpr.appInfo.uid, false);
10731                        if (proc != null && proc.thread != null) {
10732                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10733                                    "Installing in existing process " + proc);
10734                            if (!proc.pubProviders.containsKey(cpi.name)) {
10735                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10736                                proc.pubProviders.put(cpi.name, cpr);
10737                                try {
10738                                    proc.thread.scheduleInstallProvider(cpi);
10739                                } catch (RemoteException e) {
10740                                }
10741                            }
10742                        } else {
10743                            checkTime(startTime, "getContentProviderImpl: before start process");
10744                            proc = startProcessLocked(cpi.processName,
10745                                    cpr.appInfo, false, 0, "content provider",
10746                                    new ComponentName(cpi.applicationInfo.packageName,
10747                                            cpi.name), false, false, false);
10748                            checkTime(startTime, "getContentProviderImpl: after start process");
10749                            if (proc == null) {
10750                                Slog.w(TAG, "Unable to launch app "
10751                                        + cpi.applicationInfo.packageName + "/"
10752                                        + cpi.applicationInfo.uid + " for provider "
10753                                        + name + ": process is bad");
10754                                return null;
10755                            }
10756                        }
10757                        cpr.launchingApp = proc;
10758                        mLaunchingProviders.add(cpr);
10759                    } finally {
10760                        Binder.restoreCallingIdentity(origId);
10761                    }
10762                }
10763
10764                checkTime(startTime, "getContentProviderImpl: updating data structures");
10765
10766                // Make sure the provider is published (the same provider class
10767                // may be published under multiple names).
10768                if (firstClass) {
10769                    mProviderMap.putProviderByClass(comp, cpr);
10770                }
10771
10772                mProviderMap.putProviderByName(name, cpr);
10773                conn = incProviderCountLocked(r, cpr, token, stable);
10774                if (conn != null) {
10775                    conn.waiting = true;
10776                }
10777            }
10778            checkTime(startTime, "getContentProviderImpl: done!");
10779        }
10780
10781        // Wait for the provider to be published...
10782        synchronized (cpr) {
10783            while (cpr.provider == null) {
10784                if (cpr.launchingApp == null) {
10785                    Slog.w(TAG, "Unable to launch app "
10786                            + cpi.applicationInfo.packageName + "/"
10787                            + cpi.applicationInfo.uid + " for provider "
10788                            + name + ": launching app became null");
10789                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10790                            UserHandle.getUserId(cpi.applicationInfo.uid),
10791                            cpi.applicationInfo.packageName,
10792                            cpi.applicationInfo.uid, name);
10793                    return null;
10794                }
10795                try {
10796                    if (DEBUG_MU) Slog.v(TAG_MU,
10797                            "Waiting to start provider " + cpr
10798                            + " launchingApp=" + cpr.launchingApp);
10799                    if (conn != null) {
10800                        conn.waiting = true;
10801                    }
10802                    cpr.wait();
10803                } catch (InterruptedException ex) {
10804                } finally {
10805                    if (conn != null) {
10806                        conn.waiting = false;
10807                    }
10808                }
10809            }
10810        }
10811        return cpr != null ? cpr.newHolder(conn) : null;
10812    }
10813
10814    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10815            ProcessRecord r, final int userId) {
10816        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10817                cpi.packageName, userId)) {
10818
10819            final boolean callerForeground = r == null || r.setSchedGroup
10820                    != ProcessList.SCHED_GROUP_BACKGROUND;
10821
10822            // Show a permission review UI only for starting from a foreground app
10823            if (!callerForeground) {
10824                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10825                        + cpi.packageName + " requires a permissions review");
10826                return false;
10827            }
10828
10829            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10830            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10831                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10832            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10833
10834            if (DEBUG_PERMISSIONS_REVIEW) {
10835                Slog.i(TAG, "u" + userId + " Launching permission review "
10836                        + "for package " + cpi.packageName);
10837            }
10838
10839            final UserHandle userHandle = new UserHandle(userId);
10840            mHandler.post(new Runnable() {
10841                @Override
10842                public void run() {
10843                    mContext.startActivityAsUser(intent, userHandle);
10844                }
10845            });
10846
10847            return false;
10848        }
10849
10850        return true;
10851    }
10852
10853    PackageManagerInternal getPackageManagerInternalLocked() {
10854        if (mPackageManagerInt == null) {
10855            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10856        }
10857        return mPackageManagerInt;
10858    }
10859
10860    @Override
10861    public final ContentProviderHolder getContentProvider(
10862            IApplicationThread caller, String name, int userId, boolean stable) {
10863        enforceNotIsolatedCaller("getContentProvider");
10864        if (caller == null) {
10865            String msg = "null IApplicationThread when getting content provider "
10866                    + name;
10867            Slog.w(TAG, msg);
10868            throw new SecurityException(msg);
10869        }
10870        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10871        // with cross-user grant.
10872        return getContentProviderImpl(caller, name, null, stable, userId);
10873    }
10874
10875    public ContentProviderHolder getContentProviderExternal(
10876            String name, int userId, IBinder token) {
10877        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10878            "Do not have permission in call getContentProviderExternal()");
10879        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10880                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10881        return getContentProviderExternalUnchecked(name, token, userId);
10882    }
10883
10884    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10885            IBinder token, int userId) {
10886        return getContentProviderImpl(null, name, token, true, userId);
10887    }
10888
10889    /**
10890     * Drop a content provider from a ProcessRecord's bookkeeping
10891     */
10892    public void removeContentProvider(IBinder connection, boolean stable) {
10893        enforceNotIsolatedCaller("removeContentProvider");
10894        long ident = Binder.clearCallingIdentity();
10895        try {
10896            synchronized (this) {
10897                ContentProviderConnection conn;
10898                try {
10899                    conn = (ContentProviderConnection)connection;
10900                } catch (ClassCastException e) {
10901                    String msg ="removeContentProvider: " + connection
10902                            + " not a ContentProviderConnection";
10903                    Slog.w(TAG, msg);
10904                    throw new IllegalArgumentException(msg);
10905                }
10906                if (conn == null) {
10907                    throw new NullPointerException("connection is null");
10908                }
10909                if (decProviderCountLocked(conn, null, null, stable)) {
10910                    updateOomAdjLocked();
10911                }
10912            }
10913        } finally {
10914            Binder.restoreCallingIdentity(ident);
10915        }
10916    }
10917
10918    public void removeContentProviderExternal(String name, IBinder token) {
10919        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10920            "Do not have permission in call removeContentProviderExternal()");
10921        int userId = UserHandle.getCallingUserId();
10922        long ident = Binder.clearCallingIdentity();
10923        try {
10924            removeContentProviderExternalUnchecked(name, token, userId);
10925        } finally {
10926            Binder.restoreCallingIdentity(ident);
10927        }
10928    }
10929
10930    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10931        synchronized (this) {
10932            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10933            if(cpr == null) {
10934                //remove from mProvidersByClass
10935                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10936                return;
10937            }
10938
10939            //update content provider record entry info
10940            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10941            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10942            if (localCpr.hasExternalProcessHandles()) {
10943                if (localCpr.removeExternalProcessHandleLocked(token)) {
10944                    updateOomAdjLocked();
10945                } else {
10946                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10947                            + " with no external reference for token: "
10948                            + token + ".");
10949                }
10950            } else {
10951                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10952                        + " with no external references.");
10953            }
10954        }
10955    }
10956
10957    public final void publishContentProviders(IApplicationThread caller,
10958            List<ContentProviderHolder> providers) {
10959        if (providers == null) {
10960            return;
10961        }
10962
10963        enforceNotIsolatedCaller("publishContentProviders");
10964        synchronized (this) {
10965            final ProcessRecord r = getRecordForAppLocked(caller);
10966            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10967            if (r == null) {
10968                throw new SecurityException(
10969                        "Unable to find app for caller " + caller
10970                      + " (pid=" + Binder.getCallingPid()
10971                      + ") when publishing content providers");
10972            }
10973
10974            final long origId = Binder.clearCallingIdentity();
10975
10976            final int N = providers.size();
10977            for (int i = 0; i < N; i++) {
10978                ContentProviderHolder src = providers.get(i);
10979                if (src == null || src.info == null || src.provider == null) {
10980                    continue;
10981                }
10982                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10983                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10984                if (dst != null) {
10985                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10986                    mProviderMap.putProviderByClass(comp, dst);
10987                    String names[] = dst.info.authority.split(";");
10988                    for (int j = 0; j < names.length; j++) {
10989                        mProviderMap.putProviderByName(names[j], dst);
10990                    }
10991
10992                    int launchingCount = mLaunchingProviders.size();
10993                    int j;
10994                    boolean wasInLaunchingProviders = false;
10995                    for (j = 0; j < launchingCount; j++) {
10996                        if (mLaunchingProviders.get(j) == dst) {
10997                            mLaunchingProviders.remove(j);
10998                            wasInLaunchingProviders = true;
10999                            j--;
11000                            launchingCount--;
11001                        }
11002                    }
11003                    if (wasInLaunchingProviders) {
11004                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11005                    }
11006                    synchronized (dst) {
11007                        dst.provider = src.provider;
11008                        dst.proc = r;
11009                        dst.notifyAll();
11010                    }
11011                    updateOomAdjLocked(r);
11012                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11013                            src.info.authority);
11014                }
11015            }
11016
11017            Binder.restoreCallingIdentity(origId);
11018        }
11019    }
11020
11021    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11022        ContentProviderConnection conn;
11023        try {
11024            conn = (ContentProviderConnection)connection;
11025        } catch (ClassCastException e) {
11026            String msg ="refContentProvider: " + connection
11027                    + " not a ContentProviderConnection";
11028            Slog.w(TAG, msg);
11029            throw new IllegalArgumentException(msg);
11030        }
11031        if (conn == null) {
11032            throw new NullPointerException("connection is null");
11033        }
11034
11035        synchronized (this) {
11036            if (stable > 0) {
11037                conn.numStableIncs += stable;
11038            }
11039            stable = conn.stableCount + stable;
11040            if (stable < 0) {
11041                throw new IllegalStateException("stableCount < 0: " + stable);
11042            }
11043
11044            if (unstable > 0) {
11045                conn.numUnstableIncs += unstable;
11046            }
11047            unstable = conn.unstableCount + unstable;
11048            if (unstable < 0) {
11049                throw new IllegalStateException("unstableCount < 0: " + unstable);
11050            }
11051
11052            if ((stable+unstable) <= 0) {
11053                throw new IllegalStateException("ref counts can't go to zero here: stable="
11054                        + stable + " unstable=" + unstable);
11055            }
11056            conn.stableCount = stable;
11057            conn.unstableCount = unstable;
11058            return !conn.dead;
11059        }
11060    }
11061
11062    public void unstableProviderDied(IBinder connection) {
11063        ContentProviderConnection conn;
11064        try {
11065            conn = (ContentProviderConnection)connection;
11066        } catch (ClassCastException e) {
11067            String msg ="refContentProvider: " + connection
11068                    + " not a ContentProviderConnection";
11069            Slog.w(TAG, msg);
11070            throw new IllegalArgumentException(msg);
11071        }
11072        if (conn == null) {
11073            throw new NullPointerException("connection is null");
11074        }
11075
11076        // Safely retrieve the content provider associated with the connection.
11077        IContentProvider provider;
11078        synchronized (this) {
11079            provider = conn.provider.provider;
11080        }
11081
11082        if (provider == null) {
11083            // Um, yeah, we're way ahead of you.
11084            return;
11085        }
11086
11087        // Make sure the caller is being honest with us.
11088        if (provider.asBinder().pingBinder()) {
11089            // Er, no, still looks good to us.
11090            synchronized (this) {
11091                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11092                        + " says " + conn + " died, but we don't agree");
11093                return;
11094            }
11095        }
11096
11097        // Well look at that!  It's dead!
11098        synchronized (this) {
11099            if (conn.provider.provider != provider) {
11100                // But something changed...  good enough.
11101                return;
11102            }
11103
11104            ProcessRecord proc = conn.provider.proc;
11105            if (proc == null || proc.thread == null) {
11106                // Seems like the process is already cleaned up.
11107                return;
11108            }
11109
11110            // As far as we're concerned, this is just like receiving a
11111            // death notification...  just a bit prematurely.
11112            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11113                    + ") early provider death");
11114            final long ident = Binder.clearCallingIdentity();
11115            try {
11116                appDiedLocked(proc);
11117            } finally {
11118                Binder.restoreCallingIdentity(ident);
11119            }
11120        }
11121    }
11122
11123    @Override
11124    public void appNotRespondingViaProvider(IBinder connection) {
11125        enforceCallingPermission(
11126                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11127
11128        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11129        if (conn == null) {
11130            Slog.w(TAG, "ContentProviderConnection is null");
11131            return;
11132        }
11133
11134        final ProcessRecord host = conn.provider.proc;
11135        if (host == null) {
11136            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11137            return;
11138        }
11139
11140        mHandler.post(new Runnable() {
11141            @Override
11142            public void run() {
11143                mAppErrors.appNotResponding(host, null, null, false,
11144                        "ContentProvider not responding");
11145            }
11146        });
11147    }
11148
11149    public final void installSystemProviders() {
11150        List<ProviderInfo> providers;
11151        synchronized (this) {
11152            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11153            providers = generateApplicationProvidersLocked(app);
11154            if (providers != null) {
11155                for (int i=providers.size()-1; i>=0; i--) {
11156                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11157                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11158                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11159                                + ": not system .apk");
11160                        providers.remove(i);
11161                    }
11162                }
11163            }
11164        }
11165        if (providers != null) {
11166            mSystemThread.installSystemProviders(providers);
11167        }
11168
11169        mCoreSettingsObserver = new CoreSettingsObserver(this);
11170        mFontScaleSettingObserver = new FontScaleSettingObserver();
11171
11172        //mUsageStatsService.monitorPackages();
11173    }
11174
11175    private void startPersistentApps(int matchFlags) {
11176        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11177
11178        synchronized (this) {
11179            try {
11180                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11181                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11182                for (ApplicationInfo app : apps) {
11183                    if (!"android".equals(app.packageName)) {
11184                        addAppLocked(app, false, null /* ABI override */);
11185                    }
11186                }
11187            } catch (RemoteException ex) {
11188            }
11189        }
11190    }
11191
11192    /**
11193     * When a user is unlocked, we need to install encryption-unaware providers
11194     * belonging to any running apps.
11195     */
11196    private void installEncryptionUnawareProviders(int userId) {
11197        // We're only interested in providers that are encryption unaware, and
11198        // we don't care about uninstalled apps, since there's no way they're
11199        // running at this point.
11200        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11201
11202        synchronized (this) {
11203            final int NP = mProcessNames.getMap().size();
11204            for (int ip = 0; ip < NP; ip++) {
11205                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11206                final int NA = apps.size();
11207                for (int ia = 0; ia < NA; ia++) {
11208                    final ProcessRecord app = apps.valueAt(ia);
11209                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11210
11211                    final int NG = app.pkgList.size();
11212                    for (int ig = 0; ig < NG; ig++) {
11213                        try {
11214                            final String pkgName = app.pkgList.keyAt(ig);
11215                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11216                                    .getPackageInfo(pkgName, matchFlags, userId);
11217                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11218                                for (ProviderInfo pi : pkgInfo.providers) {
11219                                    // TODO: keep in sync with generateApplicationProvidersLocked
11220                                    final boolean processMatch = Objects.equals(pi.processName,
11221                                            app.processName) || pi.multiprocess;
11222                                    final boolean userMatch = isSingleton(pi.processName,
11223                                            pi.applicationInfo, pi.name, pi.flags)
11224                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11225                                    if (processMatch && userMatch) {
11226                                        Log.v(TAG, "Installing " + pi);
11227                                        app.thread.scheduleInstallProvider(pi);
11228                                    } else {
11229                                        Log.v(TAG, "Skipping " + pi);
11230                                    }
11231                                }
11232                            }
11233                        } catch (RemoteException ignored) {
11234                        }
11235                    }
11236                }
11237            }
11238        }
11239    }
11240
11241    /**
11242     * Allows apps to retrieve the MIME type of a URI.
11243     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11244     * users, then it does not need permission to access the ContentProvider.
11245     * Either, it needs cross-user uri grants.
11246     *
11247     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11248     *
11249     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11250     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11251     */
11252    public String getProviderMimeType(Uri uri, int userId) {
11253        enforceNotIsolatedCaller("getProviderMimeType");
11254        final String name = uri.getAuthority();
11255        int callingUid = Binder.getCallingUid();
11256        int callingPid = Binder.getCallingPid();
11257        long ident = 0;
11258        boolean clearedIdentity = false;
11259        synchronized (this) {
11260            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11261        }
11262        if (canClearIdentity(callingPid, callingUid, userId)) {
11263            clearedIdentity = true;
11264            ident = Binder.clearCallingIdentity();
11265        }
11266        ContentProviderHolder holder = null;
11267        try {
11268            holder = getContentProviderExternalUnchecked(name, null, userId);
11269            if (holder != null) {
11270                return holder.provider.getType(uri);
11271            }
11272        } catch (RemoteException e) {
11273            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11274            return null;
11275        } catch (Exception e) {
11276            Log.w(TAG, "Exception while determining type of " + uri, e);
11277            return null;
11278        } finally {
11279            // We need to clear the identity to call removeContentProviderExternalUnchecked
11280            if (!clearedIdentity) {
11281                ident = Binder.clearCallingIdentity();
11282            }
11283            try {
11284                if (holder != null) {
11285                    removeContentProviderExternalUnchecked(name, null, userId);
11286                }
11287            } finally {
11288                Binder.restoreCallingIdentity(ident);
11289            }
11290        }
11291
11292        return null;
11293    }
11294
11295    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11296        if (UserHandle.getUserId(callingUid) == userId) {
11297            return true;
11298        }
11299        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11300                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11301                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11302                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11303                return true;
11304        }
11305        return false;
11306    }
11307
11308    // =========================================================
11309    // GLOBAL MANAGEMENT
11310    // =========================================================
11311
11312    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11313            boolean isolated, int isolatedUid) {
11314        String proc = customProcess != null ? customProcess : info.processName;
11315        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11316        final int userId = UserHandle.getUserId(info.uid);
11317        int uid = info.uid;
11318        if (isolated) {
11319            if (isolatedUid == 0) {
11320                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11321                while (true) {
11322                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11323                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11324                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11325                    }
11326                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11327                    mNextIsolatedProcessUid++;
11328                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11329                        // No process for this uid, use it.
11330                        break;
11331                    }
11332                    stepsLeft--;
11333                    if (stepsLeft <= 0) {
11334                        return null;
11335                    }
11336                }
11337            } else {
11338                // Special case for startIsolatedProcess (internal only), where
11339                // the uid of the isolated process is specified by the caller.
11340                uid = isolatedUid;
11341            }
11342        }
11343        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11344        if (!mBooted && !mBooting
11345                && userId == UserHandle.USER_SYSTEM
11346                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11347            r.persistent = true;
11348        }
11349        addProcessNameLocked(r);
11350        return r;
11351    }
11352
11353    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11354            String abiOverride) {
11355        ProcessRecord app;
11356        if (!isolated) {
11357            app = getProcessRecordLocked(info.processName, info.uid, true);
11358        } else {
11359            app = null;
11360        }
11361
11362        if (app == null) {
11363            app = newProcessRecordLocked(info, null, isolated, 0);
11364            updateLruProcessLocked(app, false, null);
11365            updateOomAdjLocked();
11366        }
11367
11368        // This package really, really can not be stopped.
11369        try {
11370            AppGlobals.getPackageManager().setPackageStoppedState(
11371                    info.packageName, false, UserHandle.getUserId(app.uid));
11372        } catch (RemoteException e) {
11373        } catch (IllegalArgumentException e) {
11374            Slog.w(TAG, "Failed trying to unstop package "
11375                    + info.packageName + ": " + e);
11376        }
11377
11378        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11379            app.persistent = true;
11380            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11381        }
11382        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11383            mPersistentStartingProcesses.add(app);
11384            startProcessLocked(app, "added application", app.processName, abiOverride,
11385                    null /* entryPoint */, null /* entryPointArgs */);
11386        }
11387
11388        return app;
11389    }
11390
11391    public void unhandledBack() {
11392        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11393                "unhandledBack()");
11394
11395        synchronized(this) {
11396            final long origId = Binder.clearCallingIdentity();
11397            try {
11398                getFocusedStack().unhandledBackLocked();
11399            } finally {
11400                Binder.restoreCallingIdentity(origId);
11401            }
11402        }
11403    }
11404
11405    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11406        enforceNotIsolatedCaller("openContentUri");
11407        final int userId = UserHandle.getCallingUserId();
11408        String name = uri.getAuthority();
11409        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11410        ParcelFileDescriptor pfd = null;
11411        if (cph != null) {
11412            // We record the binder invoker's uid in thread-local storage before
11413            // going to the content provider to open the file.  Later, in the code
11414            // that handles all permissions checks, we look for this uid and use
11415            // that rather than the Activity Manager's own uid.  The effect is that
11416            // we do the check against the caller's permissions even though it looks
11417            // to the content provider like the Activity Manager itself is making
11418            // the request.
11419            Binder token = new Binder();
11420            sCallerIdentity.set(new Identity(
11421                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11422            try {
11423                pfd = cph.provider.openFile(null, uri, "r", null, token);
11424            } catch (FileNotFoundException e) {
11425                // do nothing; pfd will be returned null
11426            } finally {
11427                // Ensure that whatever happens, we clean up the identity state
11428                sCallerIdentity.remove();
11429                // Ensure we're done with the provider.
11430                removeContentProviderExternalUnchecked(name, null, userId);
11431            }
11432        } else {
11433            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11434        }
11435        return pfd;
11436    }
11437
11438    // Actually is sleeping or shutting down or whatever else in the future
11439    // is an inactive state.
11440    public boolean isSleepingOrShuttingDown() {
11441        return isSleeping() || mShuttingDown;
11442    }
11443
11444    public boolean isSleeping() {
11445        return mSleeping;
11446    }
11447
11448    void onWakefulnessChanged(int wakefulness) {
11449        synchronized(this) {
11450            mWakefulness = wakefulness;
11451            updateSleepIfNeededLocked();
11452        }
11453    }
11454
11455    void finishRunningVoiceLocked() {
11456        if (mRunningVoice != null) {
11457            mRunningVoice = null;
11458            mVoiceWakeLock.release();
11459            updateSleepIfNeededLocked();
11460        }
11461    }
11462
11463    void startTimeTrackingFocusedActivityLocked() {
11464        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11465            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11466        }
11467    }
11468
11469    void updateSleepIfNeededLocked() {
11470        if (mSleeping && !shouldSleepLocked()) {
11471            mSleeping = false;
11472            startTimeTrackingFocusedActivityLocked();
11473            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11474            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11475            updateOomAdjLocked();
11476        } else if (!mSleeping && shouldSleepLocked()) {
11477            mSleeping = true;
11478            if (mCurAppTimeTracker != null) {
11479                mCurAppTimeTracker.stop();
11480            }
11481            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11482            mStackSupervisor.goingToSleepLocked();
11483            updateOomAdjLocked();
11484
11485            // Initialize the wake times of all processes.
11486            checkExcessivePowerUsageLocked(false);
11487            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11488            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11489            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11490        }
11491    }
11492
11493    private boolean shouldSleepLocked() {
11494        // Resume applications while running a voice interactor.
11495        if (mRunningVoice != null) {
11496            return false;
11497        }
11498
11499        // TODO: Transform the lock screen state into a sleep token instead.
11500        switch (mWakefulness) {
11501            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11502            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11503            case PowerManagerInternal.WAKEFULNESS_DOZING:
11504                // Pause applications whenever the lock screen is shown or any sleep
11505                // tokens have been acquired.
11506                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11507            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11508            default:
11509                // If we're asleep then pause applications unconditionally.
11510                return true;
11511        }
11512    }
11513
11514    /** Pokes the task persister. */
11515    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11516        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11517    }
11518
11519    /** Notifies all listeners when the task stack has changed. */
11520    void notifyTaskStackChangedLocked() {
11521        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11522        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11523        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11524        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11525    }
11526
11527    /** Notifies all listeners when an Activity is pinned. */
11528    void notifyActivityPinnedLocked() {
11529        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11530        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11531    }
11532
11533    /**
11534     * Notifies all listeners when an attempt was made to start an an activity that is already
11535     * running in the pinned stack and the activity was not actually started, but the task is
11536     * either brought to the front or a new Intent is delivered to it.
11537     */
11538    void notifyPinnedActivityRestartAttemptLocked() {
11539        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11540        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11541    }
11542
11543    /** Notifies all listeners when the pinned stack animation ends. */
11544    @Override
11545    public void notifyPinnedStackAnimationEnded() {
11546        synchronized (this) {
11547            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11548            mHandler.obtainMessage(
11549                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11550        }
11551    }
11552
11553    @Override
11554    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11555        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11556    }
11557
11558    @Override
11559    public boolean shutdown(int timeout) {
11560        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11561                != PackageManager.PERMISSION_GRANTED) {
11562            throw new SecurityException("Requires permission "
11563                    + android.Manifest.permission.SHUTDOWN);
11564        }
11565
11566        boolean timedout = false;
11567
11568        synchronized(this) {
11569            mShuttingDown = true;
11570            updateEventDispatchingLocked();
11571            timedout = mStackSupervisor.shutdownLocked(timeout);
11572        }
11573
11574        mAppOpsService.shutdown();
11575        if (mUsageStatsService != null) {
11576            mUsageStatsService.prepareShutdown();
11577        }
11578        mBatteryStatsService.shutdown();
11579        synchronized (this) {
11580            mProcessStats.shutdownLocked();
11581            notifyTaskPersisterLocked(null, true);
11582        }
11583
11584        return timedout;
11585    }
11586
11587    public final void activitySlept(IBinder token) {
11588        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11589
11590        final long origId = Binder.clearCallingIdentity();
11591
11592        synchronized (this) {
11593            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11594            if (r != null) {
11595                mStackSupervisor.activitySleptLocked(r);
11596            }
11597        }
11598
11599        Binder.restoreCallingIdentity(origId);
11600    }
11601
11602    private String lockScreenShownToString() {
11603        switch (mLockScreenShown) {
11604            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11605            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11606            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11607            default: return "Unknown=" + mLockScreenShown;
11608        }
11609    }
11610
11611    void logLockScreen(String msg) {
11612        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11613                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11614                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11615                + " mSleeping=" + mSleeping);
11616    }
11617
11618    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11619        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11620        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11621        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11622            boolean wasRunningVoice = mRunningVoice != null;
11623            mRunningVoice = session;
11624            if (!wasRunningVoice) {
11625                mVoiceWakeLock.acquire();
11626                updateSleepIfNeededLocked();
11627            }
11628        }
11629    }
11630
11631    private void updateEventDispatchingLocked() {
11632        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11633    }
11634
11635    public void setLockScreenShown(boolean showing, boolean occluded) {
11636        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11637                != PackageManager.PERMISSION_GRANTED) {
11638            throw new SecurityException("Requires permission "
11639                    + android.Manifest.permission.DEVICE_POWER);
11640        }
11641
11642        synchronized(this) {
11643            long ident = Binder.clearCallingIdentity();
11644            try {
11645                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11646                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11647                if (showing && occluded) {
11648                    // The lock screen is currently showing, but is occluded by a window that can
11649                    // show on top of the lock screen. In this can we want to dismiss the docked
11650                    // stack since it will be complicated/risky to try to put the activity on top
11651                    // of the lock screen in the right fullscreen configuration.
11652                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11653                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11654                }
11655
11656                updateSleepIfNeededLocked();
11657            } finally {
11658                Binder.restoreCallingIdentity(ident);
11659            }
11660        }
11661    }
11662
11663    @Override
11664    public void notifyLockedProfile(@UserIdInt int userId) {
11665        try {
11666            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11667                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11668            }
11669        } catch (RemoteException ex) {
11670            throw new SecurityException("Fail to check is caller a privileged app", ex);
11671        }
11672
11673        synchronized (this) {
11674            if (mStackSupervisor.isUserLockedProfile(userId)) {
11675                final long ident = Binder.clearCallingIdentity();
11676                try {
11677                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11678                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11679                        // If there is no device lock, we will show the profile's credential page.
11680                        mActivityStarter.showConfirmDeviceCredential(userId);
11681                    } else {
11682                        // Showing launcher to avoid user entering credential twice.
11683                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11684                    }
11685                } finally {
11686                    Binder.restoreCallingIdentity(ident);
11687                }
11688            }
11689        }
11690    }
11691
11692    @Override
11693    public void startConfirmDeviceCredentialIntent(Intent intent) {
11694        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11695        synchronized (this) {
11696            final long ident = Binder.clearCallingIdentity();
11697            try {
11698                mActivityStarter.startConfirmCredentialIntent(intent);
11699            } finally {
11700                Binder.restoreCallingIdentity(ident);
11701            }
11702        }
11703    }
11704
11705    @Override
11706    public void stopAppSwitches() {
11707        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11708                != PackageManager.PERMISSION_GRANTED) {
11709            throw new SecurityException("viewquires permission "
11710                    + android.Manifest.permission.STOP_APP_SWITCHES);
11711        }
11712
11713        synchronized(this) {
11714            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11715                    + APP_SWITCH_DELAY_TIME;
11716            mDidAppSwitch = false;
11717            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11718            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11719            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11720        }
11721    }
11722
11723    public void resumeAppSwitches() {
11724        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11725                != PackageManager.PERMISSION_GRANTED) {
11726            throw new SecurityException("Requires permission "
11727                    + android.Manifest.permission.STOP_APP_SWITCHES);
11728        }
11729
11730        synchronized(this) {
11731            // Note that we don't execute any pending app switches... we will
11732            // let those wait until either the timeout, or the next start
11733            // activity request.
11734            mAppSwitchesAllowedTime = 0;
11735        }
11736    }
11737
11738    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11739            int callingPid, int callingUid, String name) {
11740        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11741            return true;
11742        }
11743
11744        int perm = checkComponentPermission(
11745                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11746                sourceUid, -1, true);
11747        if (perm == PackageManager.PERMISSION_GRANTED) {
11748            return true;
11749        }
11750
11751        // If the actual IPC caller is different from the logical source, then
11752        // also see if they are allowed to control app switches.
11753        if (callingUid != -1 && callingUid != sourceUid) {
11754            perm = checkComponentPermission(
11755                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11756                    callingUid, -1, true);
11757            if (perm == PackageManager.PERMISSION_GRANTED) {
11758                return true;
11759            }
11760        }
11761
11762        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11763        return false;
11764    }
11765
11766    public void setDebugApp(String packageName, boolean waitForDebugger,
11767            boolean persistent) {
11768        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11769                "setDebugApp()");
11770
11771        long ident = Binder.clearCallingIdentity();
11772        try {
11773            // Note that this is not really thread safe if there are multiple
11774            // callers into it at the same time, but that's not a situation we
11775            // care about.
11776            if (persistent) {
11777                final ContentResolver resolver = mContext.getContentResolver();
11778                Settings.Global.putString(
11779                    resolver, Settings.Global.DEBUG_APP,
11780                    packageName);
11781                Settings.Global.putInt(
11782                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11783                    waitForDebugger ? 1 : 0);
11784            }
11785
11786            synchronized (this) {
11787                if (!persistent) {
11788                    mOrigDebugApp = mDebugApp;
11789                    mOrigWaitForDebugger = mWaitForDebugger;
11790                }
11791                mDebugApp = packageName;
11792                mWaitForDebugger = waitForDebugger;
11793                mDebugTransient = !persistent;
11794                if (packageName != null) {
11795                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11796                            false, UserHandle.USER_ALL, "set debug app");
11797                }
11798            }
11799        } finally {
11800            Binder.restoreCallingIdentity(ident);
11801        }
11802    }
11803
11804    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11805        synchronized (this) {
11806            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11807            if (!isDebuggable) {
11808                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11809                    throw new SecurityException("Process not debuggable: " + app.packageName);
11810                }
11811            }
11812
11813            mTrackAllocationApp = processName;
11814        }
11815    }
11816
11817    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11818        synchronized (this) {
11819            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11820            if (!isDebuggable) {
11821                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11822                    throw new SecurityException("Process not debuggable: " + app.packageName);
11823                }
11824            }
11825            mProfileApp = processName;
11826            mProfileFile = profilerInfo.profileFile;
11827            if (mProfileFd != null) {
11828                try {
11829                    mProfileFd.close();
11830                } catch (IOException e) {
11831                }
11832                mProfileFd = null;
11833            }
11834            mProfileFd = profilerInfo.profileFd;
11835            mSamplingInterval = profilerInfo.samplingInterval;
11836            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11837            mProfileType = 0;
11838        }
11839    }
11840
11841    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11842        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11843        if (!isDebuggable) {
11844            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11845                throw new SecurityException("Process not debuggable: " + app.packageName);
11846            }
11847        }
11848        mNativeDebuggingApp = processName;
11849    }
11850
11851    @Override
11852    public void setAlwaysFinish(boolean enabled) {
11853        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11854                "setAlwaysFinish()");
11855
11856        long ident = Binder.clearCallingIdentity();
11857        try {
11858            Settings.Global.putInt(
11859                    mContext.getContentResolver(),
11860                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11861
11862            synchronized (this) {
11863                mAlwaysFinishActivities = enabled;
11864            }
11865        } finally {
11866            Binder.restoreCallingIdentity(ident);
11867        }
11868    }
11869
11870    @Override
11871    public void setLenientBackgroundCheck(boolean enabled) {
11872        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11873                "setLenientBackgroundCheck()");
11874
11875        long ident = Binder.clearCallingIdentity();
11876        try {
11877            Settings.Global.putInt(
11878                    mContext.getContentResolver(),
11879                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11880
11881            synchronized (this) {
11882                mLenientBackgroundCheck = enabled;
11883            }
11884        } finally {
11885            Binder.restoreCallingIdentity(ident);
11886        }
11887    }
11888
11889    @Override
11890    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11891        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11892                "setActivityController()");
11893        synchronized (this) {
11894            mController = controller;
11895            mControllerIsAMonkey = imAMonkey;
11896            Watchdog.getInstance().setActivityController(controller);
11897        }
11898    }
11899
11900    @Override
11901    public void setUserIsMonkey(boolean userIsMonkey) {
11902        synchronized (this) {
11903            synchronized (mPidsSelfLocked) {
11904                final int callingPid = Binder.getCallingPid();
11905                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11906                if (precessRecord == null) {
11907                    throw new SecurityException("Unknown process: " + callingPid);
11908                }
11909                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11910                    throw new SecurityException("Only an instrumentation process "
11911                            + "with a UiAutomation can call setUserIsMonkey");
11912                }
11913            }
11914            mUserIsMonkey = userIsMonkey;
11915        }
11916    }
11917
11918    @Override
11919    public boolean isUserAMonkey() {
11920        synchronized (this) {
11921            // If there is a controller also implies the user is a monkey.
11922            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11923        }
11924    }
11925
11926    public void requestBugReport(int bugreportType) {
11927        String service = null;
11928        switch (bugreportType) {
11929            case ActivityManager.BUGREPORT_OPTION_FULL:
11930                service = "bugreport";
11931                break;
11932            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11933                service = "bugreportplus";
11934                break;
11935            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11936                service = "bugreportremote";
11937                break;
11938        }
11939        if (service == null) {
11940            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11941                    + bugreportType);
11942        }
11943        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11944        SystemProperties.set("ctl.start", service);
11945    }
11946
11947    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11948        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11949    }
11950
11951    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11952        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11953            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11954        }
11955        return KEY_DISPATCHING_TIMEOUT;
11956    }
11957
11958    @Override
11959    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11960        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11961                != PackageManager.PERMISSION_GRANTED) {
11962            throw new SecurityException("Requires permission "
11963                    + android.Manifest.permission.FILTER_EVENTS);
11964        }
11965        ProcessRecord proc;
11966        long timeout;
11967        synchronized (this) {
11968            synchronized (mPidsSelfLocked) {
11969                proc = mPidsSelfLocked.get(pid);
11970            }
11971            timeout = getInputDispatchingTimeoutLocked(proc);
11972        }
11973
11974        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11975            return -1;
11976        }
11977
11978        return timeout;
11979    }
11980
11981    /**
11982     * Handle input dispatching timeouts.
11983     * Returns whether input dispatching should be aborted or not.
11984     */
11985    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11986            final ActivityRecord activity, final ActivityRecord parent,
11987            final boolean aboveSystem, String reason) {
11988        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11989                != PackageManager.PERMISSION_GRANTED) {
11990            throw new SecurityException("Requires permission "
11991                    + android.Manifest.permission.FILTER_EVENTS);
11992        }
11993
11994        final String annotation;
11995        if (reason == null) {
11996            annotation = "Input dispatching timed out";
11997        } else {
11998            annotation = "Input dispatching timed out (" + reason + ")";
11999        }
12000
12001        if (proc != null) {
12002            synchronized (this) {
12003                if (proc.debugging) {
12004                    return false;
12005                }
12006
12007                if (mDidDexOpt) {
12008                    // Give more time since we were dexopting.
12009                    mDidDexOpt = false;
12010                    return false;
12011                }
12012
12013                if (proc.instrumentationClass != null) {
12014                    Bundle info = new Bundle();
12015                    info.putString("shortMsg", "keyDispatchingTimedOut");
12016                    info.putString("longMsg", annotation);
12017                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12018                    return true;
12019                }
12020            }
12021            mHandler.post(new Runnable() {
12022                @Override
12023                public void run() {
12024                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12025                }
12026            });
12027        }
12028
12029        return true;
12030    }
12031
12032    @Override
12033    public Bundle getAssistContextExtras(int requestType) {
12034        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12035                null, null, true /* focused */, true /* newSessionId */,
12036                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12037        if (pae == null) {
12038            return null;
12039        }
12040        synchronized (pae) {
12041            while (!pae.haveResult) {
12042                try {
12043                    pae.wait();
12044                } catch (InterruptedException e) {
12045                }
12046            }
12047        }
12048        synchronized (this) {
12049            buildAssistBundleLocked(pae, pae.result);
12050            mPendingAssistExtras.remove(pae);
12051            mUiHandler.removeCallbacks(pae);
12052        }
12053        return pae.extras;
12054    }
12055
12056    @Override
12057    public boolean isAssistDataAllowedOnCurrentActivity() {
12058        int userId;
12059        synchronized (this) {
12060            userId = mUserController.getCurrentUserIdLocked();
12061            ActivityRecord activity = getFocusedStack().topActivity();
12062            if (activity == null) {
12063                return false;
12064            }
12065            userId = activity.userId;
12066        }
12067        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12068                Context.DEVICE_POLICY_SERVICE);
12069        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12070    }
12071
12072    @Override
12073    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12074        long ident = Binder.clearCallingIdentity();
12075        try {
12076            synchronized (this) {
12077                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12078                ActivityRecord top = getFocusedStack().topActivity();
12079                if (top != caller) {
12080                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12081                            + " is not current top " + top);
12082                    return false;
12083                }
12084                if (!top.nowVisible) {
12085                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12086                            + " is not visible");
12087                    return false;
12088                }
12089            }
12090            AssistUtils utils = new AssistUtils(mContext);
12091            return utils.showSessionForActiveService(args,
12092                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12093        } finally {
12094            Binder.restoreCallingIdentity(ident);
12095        }
12096    }
12097
12098    @Override
12099    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12100            Bundle receiverExtras,
12101            IBinder activityToken, boolean focused, boolean newSessionId) {
12102        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12103                activityToken, focused, newSessionId,
12104                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12105                != null;
12106    }
12107
12108    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12109            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12110            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12111        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12112                "enqueueAssistContext()");
12113        synchronized (this) {
12114            ActivityRecord activity = getFocusedStack().topActivity();
12115            if (activity == null) {
12116                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12117                return null;
12118            }
12119            if (activity.app == null || activity.app.thread == null) {
12120                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12121                return null;
12122            }
12123            if (focused) {
12124                if (activityToken != null) {
12125                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12126                    if (activity != caller) {
12127                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12128                                + " is not current top " + activity);
12129                        return null;
12130                    }
12131                }
12132            } else {
12133                activity = ActivityRecord.forTokenLocked(activityToken);
12134                if (activity == null) {
12135                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12136                            + " couldn't be found");
12137                    return null;
12138                }
12139            }
12140
12141            PendingAssistExtras pae;
12142            Bundle extras = new Bundle();
12143            if (args != null) {
12144                extras.putAll(args);
12145            }
12146            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12147            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12148            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12149                    userHandle);
12150            // Increment the sessionId if necessary
12151            if (newSessionId) {
12152                mViSessionId++;
12153            }
12154            try {
12155                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12156                        requestType, mViSessionId);
12157                mPendingAssistExtras.add(pae);
12158                mUiHandler.postDelayed(pae, timeout);
12159            } catch (RemoteException e) {
12160                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12161                return null;
12162            }
12163            return pae;
12164        }
12165    }
12166
12167    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12168        IResultReceiver receiver;
12169        synchronized (this) {
12170            mPendingAssistExtras.remove(pae);
12171            receiver = pae.receiver;
12172        }
12173        if (receiver != null) {
12174            // Caller wants result sent back to them.
12175            Bundle sendBundle = new Bundle();
12176            // At least return the receiver extras
12177            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12178                    pae.receiverExtras);
12179            try {
12180                pae.receiver.send(0, sendBundle);
12181            } catch (RemoteException e) {
12182            }
12183        }
12184    }
12185
12186    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12187        if (result != null) {
12188            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12189        }
12190        if (pae.hint != null) {
12191            pae.extras.putBoolean(pae.hint, true);
12192        }
12193    }
12194
12195    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12196            AssistContent content, Uri referrer) {
12197        PendingAssistExtras pae = (PendingAssistExtras)token;
12198        synchronized (pae) {
12199            pae.result = extras;
12200            pae.structure = structure;
12201            pae.content = content;
12202            if (referrer != null) {
12203                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12204            }
12205            pae.haveResult = true;
12206            pae.notifyAll();
12207            if (pae.intent == null && pae.receiver == null) {
12208                // Caller is just waiting for the result.
12209                return;
12210            }
12211        }
12212
12213        // We are now ready to launch the assist activity.
12214        IResultReceiver sendReceiver = null;
12215        Bundle sendBundle = null;
12216        synchronized (this) {
12217            buildAssistBundleLocked(pae, extras);
12218            boolean exists = mPendingAssistExtras.remove(pae);
12219            mUiHandler.removeCallbacks(pae);
12220            if (!exists) {
12221                // Timed out.
12222                return;
12223            }
12224            if ((sendReceiver=pae.receiver) != null) {
12225                // Caller wants result sent back to them.
12226                sendBundle = new Bundle();
12227                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12228                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12229                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12230                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12231                        pae.receiverExtras);
12232            }
12233        }
12234        if (sendReceiver != null) {
12235            try {
12236                sendReceiver.send(0, sendBundle);
12237            } catch (RemoteException e) {
12238            }
12239            return;
12240        }
12241
12242        long ident = Binder.clearCallingIdentity();
12243        try {
12244            pae.intent.replaceExtras(pae.extras);
12245            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12246                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12247                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12248            closeSystemDialogs("assist");
12249            try {
12250                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12251            } catch (ActivityNotFoundException e) {
12252                Slog.w(TAG, "No activity to handle assist action.", e);
12253            }
12254        } finally {
12255            Binder.restoreCallingIdentity(ident);
12256        }
12257    }
12258
12259    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12260            Bundle args) {
12261        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12262                true /* focused */, true /* newSessionId */,
12263                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12264    }
12265
12266    public void registerProcessObserver(IProcessObserver observer) {
12267        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12268                "registerProcessObserver()");
12269        synchronized (this) {
12270            mProcessObservers.register(observer);
12271        }
12272    }
12273
12274    @Override
12275    public void unregisterProcessObserver(IProcessObserver observer) {
12276        synchronized (this) {
12277            mProcessObservers.unregister(observer);
12278        }
12279    }
12280
12281    @Override
12282    public void registerUidObserver(IUidObserver observer, int which) {
12283        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12284                "registerUidObserver()");
12285        synchronized (this) {
12286            mUidObservers.register(observer, which);
12287        }
12288    }
12289
12290    @Override
12291    public void unregisterUidObserver(IUidObserver observer) {
12292        synchronized (this) {
12293            mUidObservers.unregister(observer);
12294        }
12295    }
12296
12297    @Override
12298    public boolean convertFromTranslucent(IBinder token) {
12299        final long origId = Binder.clearCallingIdentity();
12300        try {
12301            synchronized (this) {
12302                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12303                if (r == null) {
12304                    return false;
12305                }
12306                final boolean translucentChanged = r.changeWindowTranslucency(true);
12307                if (translucentChanged) {
12308                    r.task.stack.releaseBackgroundResources(r);
12309                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12310                }
12311                mWindowManager.setAppFullscreen(token, true);
12312                return translucentChanged;
12313            }
12314        } finally {
12315            Binder.restoreCallingIdentity(origId);
12316        }
12317    }
12318
12319    @Override
12320    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12321        final long origId = Binder.clearCallingIdentity();
12322        try {
12323            synchronized (this) {
12324                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12325                if (r == null) {
12326                    return false;
12327                }
12328                int index = r.task.mActivities.lastIndexOf(r);
12329                if (index > 0) {
12330                    ActivityRecord under = r.task.mActivities.get(index - 1);
12331                    under.returningOptions = options;
12332                }
12333                final boolean translucentChanged = r.changeWindowTranslucency(false);
12334                if (translucentChanged) {
12335                    r.task.stack.convertActivityToTranslucent(r);
12336                }
12337                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12338                mWindowManager.setAppFullscreen(token, false);
12339                return translucentChanged;
12340            }
12341        } finally {
12342            Binder.restoreCallingIdentity(origId);
12343        }
12344    }
12345
12346    @Override
12347    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12348        final long origId = Binder.clearCallingIdentity();
12349        try {
12350            synchronized (this) {
12351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12352                if (r != null) {
12353                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12354                }
12355            }
12356            return false;
12357        } finally {
12358            Binder.restoreCallingIdentity(origId);
12359        }
12360    }
12361
12362    @Override
12363    public boolean isBackgroundVisibleBehind(IBinder token) {
12364        final long origId = Binder.clearCallingIdentity();
12365        try {
12366            synchronized (this) {
12367                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12368                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12369                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12370                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12371                return visible;
12372            }
12373        } finally {
12374            Binder.restoreCallingIdentity(origId);
12375        }
12376    }
12377
12378    @Override
12379    public ActivityOptions getActivityOptions(IBinder token) {
12380        final long origId = Binder.clearCallingIdentity();
12381        try {
12382            synchronized (this) {
12383                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12384                if (r != null) {
12385                    final ActivityOptions activityOptions = r.pendingOptions;
12386                    r.pendingOptions = null;
12387                    return activityOptions;
12388                }
12389                return null;
12390            }
12391        } finally {
12392            Binder.restoreCallingIdentity(origId);
12393        }
12394    }
12395
12396    @Override
12397    public void setImmersive(IBinder token, boolean immersive) {
12398        synchronized(this) {
12399            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12400            if (r == null) {
12401                throw new IllegalArgumentException();
12402            }
12403            r.immersive = immersive;
12404
12405            // update associated state if we're frontmost
12406            if (r == mFocusedActivity) {
12407                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12408                applyUpdateLockStateLocked(r);
12409            }
12410        }
12411    }
12412
12413    @Override
12414    public boolean isImmersive(IBinder token) {
12415        synchronized (this) {
12416            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12417            if (r == null) {
12418                throw new IllegalArgumentException();
12419            }
12420            return r.immersive;
12421        }
12422    }
12423
12424    @Override
12425    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12426        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12427            throw new UnsupportedOperationException("VR mode not supported on this device!");
12428        }
12429
12430        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12431
12432        ActivityRecord r;
12433        synchronized (this) {
12434            r = ActivityRecord.isInStackLocked(token);
12435        }
12436
12437        if (r == null) {
12438            throw new IllegalArgumentException();
12439        }
12440
12441        int err;
12442        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12443                VrManagerInternal.NO_ERROR) {
12444            return err;
12445        }
12446
12447        synchronized(this) {
12448            r.requestedVrComponent = (enabled) ? packageName : null;
12449
12450            // Update associated state if this activity is currently focused
12451            if (r == mFocusedActivity) {
12452                applyUpdateVrModeLocked(r);
12453            }
12454            return 0;
12455        }
12456    }
12457
12458    @Override
12459    public boolean isVrModePackageEnabled(ComponentName packageName) {
12460        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12461            throw new UnsupportedOperationException("VR mode not supported on this device!");
12462        }
12463
12464        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12465
12466        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12467                VrManagerInternal.NO_ERROR;
12468    }
12469
12470    public boolean isTopActivityImmersive() {
12471        enforceNotIsolatedCaller("startActivity");
12472        synchronized (this) {
12473            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12474            return (r != null) ? r.immersive : false;
12475        }
12476    }
12477
12478    @Override
12479    public boolean isTopOfTask(IBinder token) {
12480        synchronized (this) {
12481            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12482            if (r == null) {
12483                throw new IllegalArgumentException();
12484            }
12485            return r.task.getTopActivity() == r;
12486        }
12487    }
12488
12489    public final void enterSafeMode() {
12490        synchronized(this) {
12491            // It only makes sense to do this before the system is ready
12492            // and started launching other packages.
12493            if (!mSystemReady) {
12494                try {
12495                    AppGlobals.getPackageManager().enterSafeMode();
12496                } catch (RemoteException e) {
12497                }
12498            }
12499
12500            mSafeMode = true;
12501        }
12502    }
12503
12504    public final void showSafeModeOverlay() {
12505        View v = LayoutInflater.from(mContext).inflate(
12506                com.android.internal.R.layout.safe_mode, null);
12507        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12508        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12509        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12510        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12511        lp.gravity = Gravity.BOTTOM | Gravity.START;
12512        lp.format = v.getBackground().getOpacity();
12513        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12514                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12515        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12516        ((WindowManager)mContext.getSystemService(
12517                Context.WINDOW_SERVICE)).addView(v, lp);
12518    }
12519
12520    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12521        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12522            return;
12523        }
12524        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12525        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12526        synchronized (stats) {
12527            if (mBatteryStatsService.isOnBattery()) {
12528                mBatteryStatsService.enforceCallingPermission();
12529                int MY_UID = Binder.getCallingUid();
12530                final int uid;
12531                if (sender == null) {
12532                    uid = sourceUid;
12533                } else {
12534                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12535                }
12536                BatteryStatsImpl.Uid.Pkg pkg =
12537                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12538                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12539                pkg.noteWakeupAlarmLocked(tag);
12540            }
12541        }
12542    }
12543
12544    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12545        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12546            return;
12547        }
12548        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12549        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12550        synchronized (stats) {
12551            mBatteryStatsService.enforceCallingPermission();
12552            int MY_UID = Binder.getCallingUid();
12553            final int uid;
12554            if (sender == null) {
12555                uid = sourceUid;
12556            } else {
12557                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12558            }
12559            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12560        }
12561    }
12562
12563    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12564        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12565            return;
12566        }
12567        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12568        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12569        synchronized (stats) {
12570            mBatteryStatsService.enforceCallingPermission();
12571            int MY_UID = Binder.getCallingUid();
12572            final int uid;
12573            if (sender == null) {
12574                uid = sourceUid;
12575            } else {
12576                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12577            }
12578            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12579        }
12580    }
12581
12582    public boolean killPids(int[] pids, String pReason, boolean secure) {
12583        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12584            throw new SecurityException("killPids only available to the system");
12585        }
12586        String reason = (pReason == null) ? "Unknown" : pReason;
12587        // XXX Note: don't acquire main activity lock here, because the window
12588        // manager calls in with its locks held.
12589
12590        boolean killed = false;
12591        synchronized (mPidsSelfLocked) {
12592            int worstType = 0;
12593            for (int i=0; i<pids.length; i++) {
12594                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12595                if (proc != null) {
12596                    int type = proc.setAdj;
12597                    if (type > worstType) {
12598                        worstType = type;
12599                    }
12600                }
12601            }
12602
12603            // If the worst oom_adj is somewhere in the cached proc LRU range,
12604            // then constrain it so we will kill all cached procs.
12605            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12606                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12607                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12608            }
12609
12610            // If this is not a secure call, don't let it kill processes that
12611            // are important.
12612            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12613                worstType = ProcessList.SERVICE_ADJ;
12614            }
12615
12616            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12617            for (int i=0; i<pids.length; i++) {
12618                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12619                if (proc == null) {
12620                    continue;
12621                }
12622                int adj = proc.setAdj;
12623                if (adj >= worstType && !proc.killedByAm) {
12624                    proc.kill(reason, true);
12625                    killed = true;
12626                }
12627            }
12628        }
12629        return killed;
12630    }
12631
12632    @Override
12633    public void killUid(int appId, int userId, String reason) {
12634        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12635        synchronized (this) {
12636            final long identity = Binder.clearCallingIdentity();
12637            try {
12638                killPackageProcessesLocked(null, appId, userId,
12639                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12640                        reason != null ? reason : "kill uid");
12641            } finally {
12642                Binder.restoreCallingIdentity(identity);
12643            }
12644        }
12645    }
12646
12647    @Override
12648    public boolean killProcessesBelowForeground(String reason) {
12649        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12650            throw new SecurityException("killProcessesBelowForeground() only available to system");
12651        }
12652
12653        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12654    }
12655
12656    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12657        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12658            throw new SecurityException("killProcessesBelowAdj() only available to system");
12659        }
12660
12661        boolean killed = false;
12662        synchronized (mPidsSelfLocked) {
12663            final int size = mPidsSelfLocked.size();
12664            for (int i = 0; i < size; i++) {
12665                final int pid = mPidsSelfLocked.keyAt(i);
12666                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12667                if (proc == null) continue;
12668
12669                final int adj = proc.setAdj;
12670                if (adj > belowAdj && !proc.killedByAm) {
12671                    proc.kill(reason, true);
12672                    killed = true;
12673                }
12674            }
12675        }
12676        return killed;
12677    }
12678
12679    @Override
12680    public void hang(final IBinder who, boolean allowRestart) {
12681        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12682                != PackageManager.PERMISSION_GRANTED) {
12683            throw new SecurityException("Requires permission "
12684                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12685        }
12686
12687        final IBinder.DeathRecipient death = new DeathRecipient() {
12688            @Override
12689            public void binderDied() {
12690                synchronized (this) {
12691                    notifyAll();
12692                }
12693            }
12694        };
12695
12696        try {
12697            who.linkToDeath(death, 0);
12698        } catch (RemoteException e) {
12699            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12700            return;
12701        }
12702
12703        synchronized (this) {
12704            Watchdog.getInstance().setAllowRestart(allowRestart);
12705            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12706            synchronized (death) {
12707                while (who.isBinderAlive()) {
12708                    try {
12709                        death.wait();
12710                    } catch (InterruptedException e) {
12711                    }
12712                }
12713            }
12714            Watchdog.getInstance().setAllowRestart(true);
12715        }
12716    }
12717
12718    @Override
12719    public void restart() {
12720        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12721                != PackageManager.PERMISSION_GRANTED) {
12722            throw new SecurityException("Requires permission "
12723                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12724        }
12725
12726        Log.i(TAG, "Sending shutdown broadcast...");
12727
12728        BroadcastReceiver br = new BroadcastReceiver() {
12729            @Override public void onReceive(Context context, Intent intent) {
12730                // Now the broadcast is done, finish up the low-level shutdown.
12731                Log.i(TAG, "Shutting down activity manager...");
12732                shutdown(10000);
12733                Log.i(TAG, "Shutdown complete, restarting!");
12734                Process.killProcess(Process.myPid());
12735                System.exit(10);
12736            }
12737        };
12738
12739        // First send the high-level shut down broadcast.
12740        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12741        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12742        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12743        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12744        mContext.sendOrderedBroadcastAsUser(intent,
12745                UserHandle.ALL, null, br, mHandler, 0, null, null);
12746        */
12747        br.onReceive(mContext, intent);
12748    }
12749
12750    private long getLowRamTimeSinceIdle(long now) {
12751        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12752    }
12753
12754    @Override
12755    public void performIdleMaintenance() {
12756        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12757                != PackageManager.PERMISSION_GRANTED) {
12758            throw new SecurityException("Requires permission "
12759                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12760        }
12761
12762        synchronized (this) {
12763            final long now = SystemClock.uptimeMillis();
12764            final long timeSinceLastIdle = now - mLastIdleTime;
12765            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12766            mLastIdleTime = now;
12767            mLowRamTimeSinceLastIdle = 0;
12768            if (mLowRamStartTime != 0) {
12769                mLowRamStartTime = now;
12770            }
12771
12772            StringBuilder sb = new StringBuilder(128);
12773            sb.append("Idle maintenance over ");
12774            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12775            sb.append(" low RAM for ");
12776            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12777            Slog.i(TAG, sb.toString());
12778
12779            // If at least 1/3 of our time since the last idle period has been spent
12780            // with RAM low, then we want to kill processes.
12781            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12782
12783            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12784                ProcessRecord proc = mLruProcesses.get(i);
12785                if (proc.notCachedSinceIdle) {
12786                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12787                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12788                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12789                        if (doKilling && proc.initialIdlePss != 0
12790                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12791                            sb = new StringBuilder(128);
12792                            sb.append("Kill");
12793                            sb.append(proc.processName);
12794                            sb.append(" in idle maint: pss=");
12795                            sb.append(proc.lastPss);
12796                            sb.append(", swapPss=");
12797                            sb.append(proc.lastSwapPss);
12798                            sb.append(", initialPss=");
12799                            sb.append(proc.initialIdlePss);
12800                            sb.append(", period=");
12801                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12802                            sb.append(", lowRamPeriod=");
12803                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12804                            Slog.wtfQuiet(TAG, sb.toString());
12805                            proc.kill("idle maint (pss " + proc.lastPss
12806                                    + " from " + proc.initialIdlePss + ")", true);
12807                        }
12808                    }
12809                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12810                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12811                    proc.notCachedSinceIdle = true;
12812                    proc.initialIdlePss = 0;
12813                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12814                            mTestPssMode, isSleeping(), now);
12815                }
12816            }
12817
12818            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12819            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12820        }
12821    }
12822
12823    @Override
12824    public void sendIdleJobTrigger() {
12825        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12826                != PackageManager.PERMISSION_GRANTED) {
12827            throw new SecurityException("Requires permission "
12828                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12829        }
12830
12831        final long ident = Binder.clearCallingIdentity();
12832        try {
12833            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12834                    .setPackage("android")
12835                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12836            broadcastIntent(null, intent, null, null, 0, null, null, null,
12837                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12838        } finally {
12839            Binder.restoreCallingIdentity(ident);
12840        }
12841    }
12842
12843    private void retrieveSettings() {
12844        final ContentResolver resolver = mContext.getContentResolver();
12845        final boolean freeformWindowManagement =
12846                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12847                        || Settings.Global.getInt(
12848                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12849        final boolean supportsPictureInPicture =
12850                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12851
12852        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12853        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12854        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12855        final boolean alwaysFinishActivities =
12856                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12857        final boolean lenientBackgroundCheck =
12858                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12859        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12860        final boolean forceResizable = Settings.Global.getInt(
12861                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12862        final boolean supportsLeanbackOnly =
12863                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12864
12865        // Transfer any global setting for forcing RTL layout, into a System Property
12866        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12867
12868        final Configuration configuration = new Configuration();
12869        Settings.System.getConfiguration(resolver, configuration);
12870        if (forceRtl) {
12871            // This will take care of setting the correct layout direction flags
12872            configuration.setLayoutDirection(configuration.locale);
12873        }
12874
12875        synchronized (this) {
12876            mDebugApp = mOrigDebugApp = debugApp;
12877            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12878            mAlwaysFinishActivities = alwaysFinishActivities;
12879            mLenientBackgroundCheck = lenientBackgroundCheck;
12880            mSupportsLeanbackOnly = supportsLeanbackOnly;
12881            mForceResizableActivities = forceResizable;
12882            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12883            if (supportsMultiWindow || forceResizable) {
12884                mSupportsMultiWindow = true;
12885                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12886                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12887            } else {
12888                mSupportsMultiWindow = false;
12889                mSupportsFreeformWindowManagement = false;
12890                mSupportsPictureInPicture = false;
12891            }
12892            // This happens before any activities are started, so we can
12893            // change mConfiguration in-place.
12894            updateConfigurationLocked(configuration, null, true);
12895            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12896                    "Initial config: " + mConfiguration);
12897
12898            // Load resources only after the current configuration has been set.
12899            final Resources res = mContext.getResources();
12900            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12901            mThumbnailWidth = res.getDimensionPixelSize(
12902                    com.android.internal.R.dimen.thumbnail_width);
12903            mThumbnailHeight = res.getDimensionPixelSize(
12904                    com.android.internal.R.dimen.thumbnail_height);
12905            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12906                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12907            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12908                    com.android.internal.R.string.config_appsNotReportingCrashes));
12909            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12910                mFullscreenThumbnailScale = (float) res
12911                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12912                    (float) mConfiguration.screenWidthDp;
12913            } else {
12914                mFullscreenThumbnailScale = res.getFraction(
12915                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12916            }
12917        }
12918    }
12919
12920    public boolean testIsSystemReady() {
12921        // no need to synchronize(this) just to read & return the value
12922        return mSystemReady;
12923    }
12924
12925    public void systemReady(final Runnable goingCallback) {
12926        synchronized(this) {
12927            if (mSystemReady) {
12928                // If we're done calling all the receivers, run the next "boot phase" passed in
12929                // by the SystemServer
12930                if (goingCallback != null) {
12931                    goingCallback.run();
12932                }
12933                return;
12934            }
12935
12936            mLocalDeviceIdleController
12937                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12938
12939            // Make sure we have the current profile info, since it is needed for security checks.
12940            mUserController.onSystemReady();
12941            mRecentTasks.onSystemReadyLocked();
12942            mAppOpsService.systemReady();
12943            mSystemReady = true;
12944        }
12945
12946        ArrayList<ProcessRecord> procsToKill = null;
12947        synchronized(mPidsSelfLocked) {
12948            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12949                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12950                if (!isAllowedWhileBooting(proc.info)){
12951                    if (procsToKill == null) {
12952                        procsToKill = new ArrayList<ProcessRecord>();
12953                    }
12954                    procsToKill.add(proc);
12955                }
12956            }
12957        }
12958
12959        synchronized(this) {
12960            if (procsToKill != null) {
12961                for (int i=procsToKill.size()-1; i>=0; i--) {
12962                    ProcessRecord proc = procsToKill.get(i);
12963                    Slog.i(TAG, "Removing system update proc: " + proc);
12964                    removeProcessLocked(proc, true, false, "system update done");
12965                }
12966            }
12967
12968            // Now that we have cleaned up any update processes, we
12969            // are ready to start launching real processes and know that
12970            // we won't trample on them any more.
12971            mProcessesReady = true;
12972        }
12973
12974        Slog.i(TAG, "System now ready");
12975        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12976            SystemClock.uptimeMillis());
12977
12978        synchronized(this) {
12979            // Make sure we have no pre-ready processes sitting around.
12980
12981            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12982                ResolveInfo ri = mContext.getPackageManager()
12983                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12984                                STOCK_PM_FLAGS);
12985                CharSequence errorMsg = null;
12986                if (ri != null) {
12987                    ActivityInfo ai = ri.activityInfo;
12988                    ApplicationInfo app = ai.applicationInfo;
12989                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12990                        mTopAction = Intent.ACTION_FACTORY_TEST;
12991                        mTopData = null;
12992                        mTopComponent = new ComponentName(app.packageName,
12993                                ai.name);
12994                    } else {
12995                        errorMsg = mContext.getResources().getText(
12996                                com.android.internal.R.string.factorytest_not_system);
12997                    }
12998                } else {
12999                    errorMsg = mContext.getResources().getText(
13000                            com.android.internal.R.string.factorytest_no_action);
13001                }
13002                if (errorMsg != null) {
13003                    mTopAction = null;
13004                    mTopData = null;
13005                    mTopComponent = null;
13006                    Message msg = Message.obtain();
13007                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13008                    msg.getData().putCharSequence("msg", errorMsg);
13009                    mUiHandler.sendMessage(msg);
13010                }
13011            }
13012        }
13013
13014        retrieveSettings();
13015        final int currentUserId;
13016        synchronized (this) {
13017            currentUserId = mUserController.getCurrentUserIdLocked();
13018            readGrantedUriPermissionsLocked();
13019        }
13020
13021        if (goingCallback != null) goingCallback.run();
13022
13023        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13024                Integer.toString(currentUserId), currentUserId);
13025        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13026                Integer.toString(currentUserId), currentUserId);
13027        mSystemServiceManager.startUser(currentUserId);
13028
13029        synchronized (this) {
13030            // Only start up encryption-aware persistent apps; once user is
13031            // unlocked we'll come back around and start unaware apps
13032            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13033
13034            // Start up initial activity.
13035            mBooting = true;
13036            // Enable home activity for system user, so that the system can always boot
13037            if (UserManager.isSplitSystemUser()) {
13038                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13039                try {
13040                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13041                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13042                            UserHandle.USER_SYSTEM);
13043                } catch (RemoteException e) {
13044                    throw e.rethrowAsRuntimeException();
13045                }
13046            }
13047            startHomeActivityLocked(currentUserId, "systemReady");
13048
13049            try {
13050                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13051                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13052                            + " data partition or your device will be unstable.");
13053                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13054                }
13055            } catch (RemoteException e) {
13056            }
13057
13058            if (!Build.isBuildConsistent()) {
13059                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13060                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13061            }
13062
13063            long ident = Binder.clearCallingIdentity();
13064            try {
13065                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13066                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13067                        | Intent.FLAG_RECEIVER_FOREGROUND);
13068                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13069                broadcastIntentLocked(null, null, intent,
13070                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13071                        null, false, false, MY_PID, Process.SYSTEM_UID,
13072                        currentUserId);
13073                intent = new Intent(Intent.ACTION_USER_STARTING);
13074                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13075                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13076                broadcastIntentLocked(null, null, intent,
13077                        null, new IIntentReceiver.Stub() {
13078                            @Override
13079                            public void performReceive(Intent intent, int resultCode, String data,
13080                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13081                                    throws RemoteException {
13082                            }
13083                        }, 0, null, null,
13084                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13085                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13086            } catch (Throwable t) {
13087                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13088            } finally {
13089                Binder.restoreCallingIdentity(ident);
13090            }
13091            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13092            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13093        }
13094    }
13095
13096    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13097        synchronized (this) {
13098            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13099        }
13100    }
13101
13102    void skipCurrentReceiverLocked(ProcessRecord app) {
13103        for (BroadcastQueue queue : mBroadcastQueues) {
13104            queue.skipCurrentReceiverLocked(app);
13105        }
13106    }
13107
13108    /**
13109     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13110     * The application process will exit immediately after this call returns.
13111     * @param app object of the crashing app, null for the system server
13112     * @param crashInfo describing the exception
13113     */
13114    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13115        ProcessRecord r = findAppProcess(app, "Crash");
13116        final String processName = app == null ? "system_server"
13117                : (r == null ? "unknown" : r.processName);
13118
13119        handleApplicationCrashInner("crash", r, processName, crashInfo);
13120    }
13121
13122    /* Native crash reporting uses this inner version because it needs to be somewhat
13123     * decoupled from the AM-managed cleanup lifecycle
13124     */
13125    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13126            ApplicationErrorReport.CrashInfo crashInfo) {
13127        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13128                UserHandle.getUserId(Binder.getCallingUid()), processName,
13129                r == null ? -1 : r.info.flags,
13130                crashInfo.exceptionClassName,
13131                crashInfo.exceptionMessage,
13132                crashInfo.throwFileName,
13133                crashInfo.throwLineNumber);
13134
13135        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13136
13137        mAppErrors.crashApplication(r, crashInfo);
13138    }
13139
13140    public void handleApplicationStrictModeViolation(
13141            IBinder app,
13142            int violationMask,
13143            StrictMode.ViolationInfo info) {
13144        ProcessRecord r = findAppProcess(app, "StrictMode");
13145        if (r == null) {
13146            return;
13147        }
13148
13149        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13150            Integer stackFingerprint = info.hashCode();
13151            boolean logIt = true;
13152            synchronized (mAlreadyLoggedViolatedStacks) {
13153                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13154                    logIt = false;
13155                    // TODO: sub-sample into EventLog for these, with
13156                    // the info.durationMillis?  Then we'd get
13157                    // the relative pain numbers, without logging all
13158                    // the stack traces repeatedly.  We'd want to do
13159                    // likewise in the client code, which also does
13160                    // dup suppression, before the Binder call.
13161                } else {
13162                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13163                        mAlreadyLoggedViolatedStacks.clear();
13164                    }
13165                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13166                }
13167            }
13168            if (logIt) {
13169                logStrictModeViolationToDropBox(r, info);
13170            }
13171        }
13172
13173        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13174            AppErrorResult result = new AppErrorResult();
13175            synchronized (this) {
13176                final long origId = Binder.clearCallingIdentity();
13177
13178                Message msg = Message.obtain();
13179                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13180                HashMap<String, Object> data = new HashMap<String, Object>();
13181                data.put("result", result);
13182                data.put("app", r);
13183                data.put("violationMask", violationMask);
13184                data.put("info", info);
13185                msg.obj = data;
13186                mUiHandler.sendMessage(msg);
13187
13188                Binder.restoreCallingIdentity(origId);
13189            }
13190            int res = result.get();
13191            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13192        }
13193    }
13194
13195    // Depending on the policy in effect, there could be a bunch of
13196    // these in quick succession so we try to batch these together to
13197    // minimize disk writes, number of dropbox entries, and maximize
13198    // compression, by having more fewer, larger records.
13199    private void logStrictModeViolationToDropBox(
13200            ProcessRecord process,
13201            StrictMode.ViolationInfo info) {
13202        if (info == null) {
13203            return;
13204        }
13205        final boolean isSystemApp = process == null ||
13206                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13207                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13208        final String processName = process == null ? "unknown" : process.processName;
13209        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13210        final DropBoxManager dbox = (DropBoxManager)
13211                mContext.getSystemService(Context.DROPBOX_SERVICE);
13212
13213        // Exit early if the dropbox isn't configured to accept this report type.
13214        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13215
13216        boolean bufferWasEmpty;
13217        boolean needsFlush;
13218        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13219        synchronized (sb) {
13220            bufferWasEmpty = sb.length() == 0;
13221            appendDropBoxProcessHeaders(process, processName, sb);
13222            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13223            sb.append("System-App: ").append(isSystemApp).append("\n");
13224            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13225            if (info.violationNumThisLoop != 0) {
13226                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13227            }
13228            if (info.numAnimationsRunning != 0) {
13229                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13230            }
13231            if (info.broadcastIntentAction != null) {
13232                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13233            }
13234            if (info.durationMillis != -1) {
13235                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13236            }
13237            if (info.numInstances != -1) {
13238                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13239            }
13240            if (info.tags != null) {
13241                for (String tag : info.tags) {
13242                    sb.append("Span-Tag: ").append(tag).append("\n");
13243                }
13244            }
13245            sb.append("\n");
13246            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13247                sb.append(info.crashInfo.stackTrace);
13248                sb.append("\n");
13249            }
13250            if (info.message != null) {
13251                sb.append(info.message);
13252                sb.append("\n");
13253            }
13254
13255            // Only buffer up to ~64k.  Various logging bits truncate
13256            // things at 128k.
13257            needsFlush = (sb.length() > 64 * 1024);
13258        }
13259
13260        // Flush immediately if the buffer's grown too large, or this
13261        // is a non-system app.  Non-system apps are isolated with a
13262        // different tag & policy and not batched.
13263        //
13264        // Batching is useful during internal testing with
13265        // StrictMode settings turned up high.  Without batching,
13266        // thousands of separate files could be created on boot.
13267        if (!isSystemApp || needsFlush) {
13268            new Thread("Error dump: " + dropboxTag) {
13269                @Override
13270                public void run() {
13271                    String report;
13272                    synchronized (sb) {
13273                        report = sb.toString();
13274                        sb.delete(0, sb.length());
13275                        sb.trimToSize();
13276                    }
13277                    if (report.length() != 0) {
13278                        dbox.addText(dropboxTag, report);
13279                    }
13280                }
13281            }.start();
13282            return;
13283        }
13284
13285        // System app batching:
13286        if (!bufferWasEmpty) {
13287            // An existing dropbox-writing thread is outstanding, so
13288            // we don't need to start it up.  The existing thread will
13289            // catch the buffer appends we just did.
13290            return;
13291        }
13292
13293        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13294        // (After this point, we shouldn't access AMS internal data structures.)
13295        new Thread("Error dump: " + dropboxTag) {
13296            @Override
13297            public void run() {
13298                // 5 second sleep to let stacks arrive and be batched together
13299                try {
13300                    Thread.sleep(5000);  // 5 seconds
13301                } catch (InterruptedException e) {}
13302
13303                String errorReport;
13304                synchronized (mStrictModeBuffer) {
13305                    errorReport = mStrictModeBuffer.toString();
13306                    if (errorReport.length() == 0) {
13307                        return;
13308                    }
13309                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13310                    mStrictModeBuffer.trimToSize();
13311                }
13312                dbox.addText(dropboxTag, errorReport);
13313            }
13314        }.start();
13315    }
13316
13317    /**
13318     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13319     * @param app object of the crashing app, null for the system server
13320     * @param tag reported by the caller
13321     * @param system whether this wtf is coming from the system
13322     * @param crashInfo describing the context of the error
13323     * @return true if the process should exit immediately (WTF is fatal)
13324     */
13325    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13326            final ApplicationErrorReport.CrashInfo crashInfo) {
13327        final int callingUid = Binder.getCallingUid();
13328        final int callingPid = Binder.getCallingPid();
13329
13330        if (system) {
13331            // If this is coming from the system, we could very well have low-level
13332            // system locks held, so we want to do this all asynchronously.  And we
13333            // never want this to become fatal, so there is that too.
13334            mHandler.post(new Runnable() {
13335                @Override public void run() {
13336                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13337                }
13338            });
13339            return false;
13340        }
13341
13342        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13343                crashInfo);
13344
13345        if (r != null && r.pid != Process.myPid() &&
13346                Settings.Global.getInt(mContext.getContentResolver(),
13347                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13348            mAppErrors.crashApplication(r, crashInfo);
13349            return true;
13350        } else {
13351            return false;
13352        }
13353    }
13354
13355    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13356            final ApplicationErrorReport.CrashInfo crashInfo) {
13357        final ProcessRecord r = findAppProcess(app, "WTF");
13358        final String processName = app == null ? "system_server"
13359                : (r == null ? "unknown" : r.processName);
13360
13361        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13362                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13363
13364        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13365
13366        return r;
13367    }
13368
13369    /**
13370     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13371     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13372     */
13373    private ProcessRecord findAppProcess(IBinder app, String reason) {
13374        if (app == null) {
13375            return null;
13376        }
13377
13378        synchronized (this) {
13379            final int NP = mProcessNames.getMap().size();
13380            for (int ip=0; ip<NP; ip++) {
13381                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13382                final int NA = apps.size();
13383                for (int ia=0; ia<NA; ia++) {
13384                    ProcessRecord p = apps.valueAt(ia);
13385                    if (p.thread != null && p.thread.asBinder() == app) {
13386                        return p;
13387                    }
13388                }
13389            }
13390
13391            Slog.w(TAG, "Can't find mystery application for " + reason
13392                    + " from pid=" + Binder.getCallingPid()
13393                    + " uid=" + Binder.getCallingUid() + ": " + app);
13394            return null;
13395        }
13396    }
13397
13398    /**
13399     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13400     * to append various headers to the dropbox log text.
13401     */
13402    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13403            StringBuilder sb) {
13404        // Watchdog thread ends up invoking this function (with
13405        // a null ProcessRecord) to add the stack file to dropbox.
13406        // Do not acquire a lock on this (am) in such cases, as it
13407        // could cause a potential deadlock, if and when watchdog
13408        // is invoked due to unavailability of lock on am and it
13409        // would prevent watchdog from killing system_server.
13410        if (process == null) {
13411            sb.append("Process: ").append(processName).append("\n");
13412            return;
13413        }
13414        // Note: ProcessRecord 'process' is guarded by the service
13415        // instance.  (notably process.pkgList, which could otherwise change
13416        // concurrently during execution of this method)
13417        synchronized (this) {
13418            sb.append("Process: ").append(processName).append("\n");
13419            int flags = process.info.flags;
13420            IPackageManager pm = AppGlobals.getPackageManager();
13421            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13422            for (int ip=0; ip<process.pkgList.size(); ip++) {
13423                String pkg = process.pkgList.keyAt(ip);
13424                sb.append("Package: ").append(pkg);
13425                try {
13426                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13427                    if (pi != null) {
13428                        sb.append(" v").append(pi.versionCode);
13429                        if (pi.versionName != null) {
13430                            sb.append(" (").append(pi.versionName).append(")");
13431                        }
13432                    }
13433                } catch (RemoteException e) {
13434                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13435                }
13436                sb.append("\n");
13437            }
13438        }
13439    }
13440
13441    private static String processClass(ProcessRecord process) {
13442        if (process == null || process.pid == MY_PID) {
13443            return "system_server";
13444        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13445            return "system_app";
13446        } else {
13447            return "data_app";
13448        }
13449    }
13450
13451    private volatile long mWtfClusterStart;
13452    private volatile int mWtfClusterCount;
13453
13454    /**
13455     * Write a description of an error (crash, WTF, ANR) to the drop box.
13456     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13457     * @param process which caused the error, null means the system server
13458     * @param activity which triggered the error, null if unknown
13459     * @param parent activity related to the error, null if unknown
13460     * @param subject line related to the error, null if absent
13461     * @param report in long form describing the error, null if absent
13462     * @param logFile to include in the report, null if none
13463     * @param crashInfo giving an application stack trace, null if absent
13464     */
13465    public void addErrorToDropBox(String eventType,
13466            ProcessRecord process, String processName, ActivityRecord activity,
13467            ActivityRecord parent, String subject,
13468            final String report, final File logFile,
13469            final ApplicationErrorReport.CrashInfo crashInfo) {
13470        // NOTE -- this must never acquire the ActivityManagerService lock,
13471        // otherwise the watchdog may be prevented from resetting the system.
13472
13473        final String dropboxTag = processClass(process) + "_" + eventType;
13474        final DropBoxManager dbox = (DropBoxManager)
13475                mContext.getSystemService(Context.DROPBOX_SERVICE);
13476
13477        // Exit early if the dropbox isn't configured to accept this report type.
13478        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13479
13480        // Rate-limit how often we're willing to do the heavy lifting below to
13481        // collect and record logs; currently 5 logs per 10 second period.
13482        final long now = SystemClock.elapsedRealtime();
13483        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13484            mWtfClusterStart = now;
13485            mWtfClusterCount = 1;
13486        } else {
13487            if (mWtfClusterCount++ >= 5) return;
13488        }
13489
13490        final StringBuilder sb = new StringBuilder(1024);
13491        appendDropBoxProcessHeaders(process, processName, sb);
13492        if (process != null) {
13493            sb.append("Foreground: ")
13494                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13495                    .append("\n");
13496        }
13497        if (activity != null) {
13498            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13499        }
13500        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13501            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13502        }
13503        if (parent != null && parent != activity) {
13504            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13505        }
13506        if (subject != null) {
13507            sb.append("Subject: ").append(subject).append("\n");
13508        }
13509        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13510        if (Debug.isDebuggerConnected()) {
13511            sb.append("Debugger: Connected\n");
13512        }
13513        sb.append("\n");
13514
13515        // Do the rest in a worker thread to avoid blocking the caller on I/O
13516        // (After this point, we shouldn't access AMS internal data structures.)
13517        Thread worker = new Thread("Error dump: " + dropboxTag) {
13518            @Override
13519            public void run() {
13520                if (report != null) {
13521                    sb.append(report);
13522                }
13523                if (logFile != null) {
13524                    try {
13525                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13526                                    "\n\n[[TRUNCATED]]"));
13527                    } catch (IOException e) {
13528                        Slog.e(TAG, "Error reading " + logFile, e);
13529                    }
13530                }
13531                if (crashInfo != null && crashInfo.stackTrace != null) {
13532                    sb.append(crashInfo.stackTrace);
13533                }
13534
13535                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13536                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13537                if (lines > 0) {
13538                    sb.append("\n");
13539
13540                    // Merge several logcat streams, and take the last N lines
13541                    InputStreamReader input = null;
13542                    try {
13543                        java.lang.Process logcat = new ProcessBuilder(
13544                                "/system/bin/timeout", "-k", "15s", "10s",
13545                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13546                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13547                                        .redirectErrorStream(true).start();
13548
13549                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13550                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13551                        input = new InputStreamReader(logcat.getInputStream());
13552
13553                        int num;
13554                        char[] buf = new char[8192];
13555                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13556                    } catch (IOException e) {
13557                        Slog.e(TAG, "Error running logcat", e);
13558                    } finally {
13559                        if (input != null) try { input.close(); } catch (IOException e) {}
13560                    }
13561                }
13562
13563                dbox.addText(dropboxTag, sb.toString());
13564            }
13565        };
13566
13567        if (process == null) {
13568            // If process is null, we are being called from some internal code
13569            // and may be about to die -- run this synchronously.
13570            worker.run();
13571        } else {
13572            worker.start();
13573        }
13574    }
13575
13576    @Override
13577    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13578        enforceNotIsolatedCaller("getProcessesInErrorState");
13579        // assume our apps are happy - lazy create the list
13580        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13581
13582        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13583                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13584        int userId = UserHandle.getUserId(Binder.getCallingUid());
13585
13586        synchronized (this) {
13587
13588            // iterate across all processes
13589            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13590                ProcessRecord app = mLruProcesses.get(i);
13591                if (!allUsers && app.userId != userId) {
13592                    continue;
13593                }
13594                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13595                    // This one's in trouble, so we'll generate a report for it
13596                    // crashes are higher priority (in case there's a crash *and* an anr)
13597                    ActivityManager.ProcessErrorStateInfo report = null;
13598                    if (app.crashing) {
13599                        report = app.crashingReport;
13600                    } else if (app.notResponding) {
13601                        report = app.notRespondingReport;
13602                    }
13603
13604                    if (report != null) {
13605                        if (errList == null) {
13606                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13607                        }
13608                        errList.add(report);
13609                    } else {
13610                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13611                                " crashing = " + app.crashing +
13612                                " notResponding = " + app.notResponding);
13613                    }
13614                }
13615            }
13616        }
13617
13618        return errList;
13619    }
13620
13621    static int procStateToImportance(int procState, int memAdj,
13622            ActivityManager.RunningAppProcessInfo currApp) {
13623        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13624        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13625            currApp.lru = memAdj;
13626        } else {
13627            currApp.lru = 0;
13628        }
13629        return imp;
13630    }
13631
13632    private void fillInProcMemInfo(ProcessRecord app,
13633            ActivityManager.RunningAppProcessInfo outInfo) {
13634        outInfo.pid = app.pid;
13635        outInfo.uid = app.info.uid;
13636        if (mHeavyWeightProcess == app) {
13637            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13638        }
13639        if (app.persistent) {
13640            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13641        }
13642        if (app.activities.size() > 0) {
13643            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13644        }
13645        outInfo.lastTrimLevel = app.trimMemoryLevel;
13646        int adj = app.curAdj;
13647        int procState = app.curProcState;
13648        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13649        outInfo.importanceReasonCode = app.adjTypeCode;
13650        outInfo.processState = app.curProcState;
13651    }
13652
13653    @Override
13654    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13655        enforceNotIsolatedCaller("getRunningAppProcesses");
13656
13657        final int callingUid = Binder.getCallingUid();
13658
13659        // Lazy instantiation of list
13660        List<ActivityManager.RunningAppProcessInfo> runList = null;
13661        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13662                callingUid) == PackageManager.PERMISSION_GRANTED;
13663        final int userId = UserHandle.getUserId(callingUid);
13664        final boolean allUids = isGetTasksAllowed(
13665                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13666
13667        synchronized (this) {
13668            // Iterate across all processes
13669            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13670                ProcessRecord app = mLruProcesses.get(i);
13671                if ((!allUsers && app.userId != userId)
13672                        || (!allUids && app.uid != callingUid)) {
13673                    continue;
13674                }
13675                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13676                    // Generate process state info for running application
13677                    ActivityManager.RunningAppProcessInfo currApp =
13678                        new ActivityManager.RunningAppProcessInfo(app.processName,
13679                                app.pid, app.getPackageList());
13680                    fillInProcMemInfo(app, currApp);
13681                    if (app.adjSource instanceof ProcessRecord) {
13682                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13683                        currApp.importanceReasonImportance =
13684                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13685                                        app.adjSourceProcState);
13686                    } else if (app.adjSource instanceof ActivityRecord) {
13687                        ActivityRecord r = (ActivityRecord)app.adjSource;
13688                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13689                    }
13690                    if (app.adjTarget instanceof ComponentName) {
13691                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13692                    }
13693                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13694                    //        + " lru=" + currApp.lru);
13695                    if (runList == null) {
13696                        runList = new ArrayList<>();
13697                    }
13698                    runList.add(currApp);
13699                }
13700            }
13701        }
13702        return runList;
13703    }
13704
13705    @Override
13706    public List<ApplicationInfo> getRunningExternalApplications() {
13707        enforceNotIsolatedCaller("getRunningExternalApplications");
13708        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13709        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13710        if (runningApps != null && runningApps.size() > 0) {
13711            Set<String> extList = new HashSet<String>();
13712            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13713                if (app.pkgList != null) {
13714                    for (String pkg : app.pkgList) {
13715                        extList.add(pkg);
13716                    }
13717                }
13718            }
13719            IPackageManager pm = AppGlobals.getPackageManager();
13720            for (String pkg : extList) {
13721                try {
13722                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13723                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13724                        retList.add(info);
13725                    }
13726                } catch (RemoteException e) {
13727                }
13728            }
13729        }
13730        return retList;
13731    }
13732
13733    @Override
13734    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13735        enforceNotIsolatedCaller("getMyMemoryState");
13736        synchronized (this) {
13737            ProcessRecord proc;
13738            synchronized (mPidsSelfLocked) {
13739                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13740            }
13741            fillInProcMemInfo(proc, outInfo);
13742        }
13743    }
13744
13745    @Override
13746    public int getMemoryTrimLevel() {
13747        enforceNotIsolatedCaller("getMyMemoryState");
13748        synchronized (this) {
13749            return mLastMemoryLevel;
13750        }
13751    }
13752
13753    @Override
13754    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13755            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13756        (new ActivityManagerShellCommand(this, false)).exec(
13757                this, in, out, err, args, resultReceiver);
13758    }
13759
13760    @Override
13761    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13762        if (checkCallingPermission(android.Manifest.permission.DUMP)
13763                != PackageManager.PERMISSION_GRANTED) {
13764            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13765                    + Binder.getCallingPid()
13766                    + ", uid=" + Binder.getCallingUid()
13767                    + " without permission "
13768                    + android.Manifest.permission.DUMP);
13769            return;
13770        }
13771
13772        boolean dumpAll = false;
13773        boolean dumpClient = false;
13774        String dumpPackage = null;
13775
13776        int opti = 0;
13777        while (opti < args.length) {
13778            String opt = args[opti];
13779            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13780                break;
13781            }
13782            opti++;
13783            if ("-a".equals(opt)) {
13784                dumpAll = true;
13785            } else if ("-c".equals(opt)) {
13786                dumpClient = true;
13787            } else if ("-p".equals(opt)) {
13788                if (opti < args.length) {
13789                    dumpPackage = args[opti];
13790                    opti++;
13791                } else {
13792                    pw.println("Error: -p option requires package argument");
13793                    return;
13794                }
13795                dumpClient = true;
13796            } else if ("-h".equals(opt)) {
13797                ActivityManagerShellCommand.dumpHelp(pw, true);
13798                return;
13799            } else {
13800                pw.println("Unknown argument: " + opt + "; use -h for help");
13801            }
13802        }
13803
13804        long origId = Binder.clearCallingIdentity();
13805        boolean more = false;
13806        // Is the caller requesting to dump a particular piece of data?
13807        if (opti < args.length) {
13808            String cmd = args[opti];
13809            opti++;
13810            if ("activities".equals(cmd) || "a".equals(cmd)) {
13811                synchronized (this) {
13812                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13813                }
13814            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13815                synchronized (this) {
13816                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13817                }
13818            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13819                String[] newArgs;
13820                String name;
13821                if (opti >= args.length) {
13822                    name = null;
13823                    newArgs = EMPTY_STRING_ARRAY;
13824                } else {
13825                    dumpPackage = args[opti];
13826                    opti++;
13827                    newArgs = new String[args.length - opti];
13828                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13829                            args.length - opti);
13830                }
13831                synchronized (this) {
13832                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13833                }
13834            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13835                String[] newArgs;
13836                String name;
13837                if (opti >= args.length) {
13838                    name = null;
13839                    newArgs = EMPTY_STRING_ARRAY;
13840                } else {
13841                    dumpPackage = args[opti];
13842                    opti++;
13843                    newArgs = new String[args.length - opti];
13844                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13845                            args.length - opti);
13846                }
13847                synchronized (this) {
13848                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13849                }
13850            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13851                String[] newArgs;
13852                String name;
13853                if (opti >= args.length) {
13854                    name = null;
13855                    newArgs = EMPTY_STRING_ARRAY;
13856                } else {
13857                    dumpPackage = args[opti];
13858                    opti++;
13859                    newArgs = new String[args.length - opti];
13860                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13861                            args.length - opti);
13862                }
13863                synchronized (this) {
13864                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13865                }
13866            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13867                synchronized (this) {
13868                    dumpOomLocked(fd, pw, args, opti, true);
13869                }
13870            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13871                synchronized (this) {
13872                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13873                }
13874            } else if ("provider".equals(cmd)) {
13875                String[] newArgs;
13876                String name;
13877                if (opti >= args.length) {
13878                    name = null;
13879                    newArgs = EMPTY_STRING_ARRAY;
13880                } else {
13881                    name = args[opti];
13882                    opti++;
13883                    newArgs = new String[args.length - opti];
13884                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13885                }
13886                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13887                    pw.println("No providers match: " + name);
13888                    pw.println("Use -h for help.");
13889                }
13890            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13891                synchronized (this) {
13892                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13893                }
13894            } else if ("service".equals(cmd)) {
13895                String[] newArgs;
13896                String name;
13897                if (opti >= args.length) {
13898                    name = null;
13899                    newArgs = EMPTY_STRING_ARRAY;
13900                } else {
13901                    name = args[opti];
13902                    opti++;
13903                    newArgs = new String[args.length - opti];
13904                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13905                            args.length - opti);
13906                }
13907                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13908                    pw.println("No services match: " + name);
13909                    pw.println("Use -h for help.");
13910                }
13911            } else if ("package".equals(cmd)) {
13912                String[] newArgs;
13913                if (opti >= args.length) {
13914                    pw.println("package: no package name specified");
13915                    pw.println("Use -h for help.");
13916                } else {
13917                    dumpPackage = args[opti];
13918                    opti++;
13919                    newArgs = new String[args.length - opti];
13920                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13921                            args.length - opti);
13922                    args = newArgs;
13923                    opti = 0;
13924                    more = true;
13925                }
13926            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13927                synchronized (this) {
13928                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13929                }
13930            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13931                if (dumpClient) {
13932                    ActiveServices.ServiceDumper dumper;
13933                    synchronized (this) {
13934                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13935                                dumpPackage);
13936                    }
13937                    dumper.dumpWithClient();
13938                } else {
13939                    synchronized (this) {
13940                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13941                                dumpPackage).dumpLocked();
13942                    }
13943                }
13944            } else if ("locks".equals(cmd)) {
13945                LockGuard.dump(fd, pw, args);
13946            } else {
13947                // Dumping a single activity?
13948                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13949                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13950                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13951                    if (res < 0) {
13952                        pw.println("Bad activity command, or no activities match: " + cmd);
13953                        pw.println("Use -h for help.");
13954                    }
13955                }
13956            }
13957            if (!more) {
13958                Binder.restoreCallingIdentity(origId);
13959                return;
13960            }
13961        }
13962
13963        // No piece of data specified, dump everything.
13964        if (dumpClient) {
13965            ActiveServices.ServiceDumper sdumper;
13966            synchronized (this) {
13967                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13968                pw.println();
13969                if (dumpAll) {
13970                    pw.println("-------------------------------------------------------------------------------");
13971                }
13972                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13973                pw.println();
13974                if (dumpAll) {
13975                    pw.println("-------------------------------------------------------------------------------");
13976                }
13977                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13978                pw.println();
13979                if (dumpAll) {
13980                    pw.println("-------------------------------------------------------------------------------");
13981                }
13982                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13983                pw.println();
13984                if (dumpAll) {
13985                    pw.println("-------------------------------------------------------------------------------");
13986                }
13987                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13988                        dumpPackage);
13989            }
13990            sdumper.dumpWithClient();
13991            pw.println();
13992            synchronized (this) {
13993                if (dumpAll) {
13994                    pw.println("-------------------------------------------------------------------------------");
13995                }
13996                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13997                pw.println();
13998                if (dumpAll) {
13999                    pw.println("-------------------------------------------------------------------------------");
14000                }
14001                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14002                if (mAssociations.size() > 0) {
14003                    pw.println();
14004                    if (dumpAll) {
14005                        pw.println("-------------------------------------------------------------------------------");
14006                    }
14007                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14008                }
14009                pw.println();
14010                if (dumpAll) {
14011                    pw.println("-------------------------------------------------------------------------------");
14012                }
14013                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14014            }
14015
14016        } else {
14017            synchronized (this) {
14018                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14019                pw.println();
14020                if (dumpAll) {
14021                    pw.println("-------------------------------------------------------------------------------");
14022                }
14023                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14024                pw.println();
14025                if (dumpAll) {
14026                    pw.println("-------------------------------------------------------------------------------");
14027                }
14028                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14029                pw.println();
14030                if (dumpAll) {
14031                    pw.println("-------------------------------------------------------------------------------");
14032                }
14033                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14034                pw.println();
14035                if (dumpAll) {
14036                    pw.println("-------------------------------------------------------------------------------");
14037                }
14038                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14039                        .dumpLocked();
14040                pw.println();
14041                if (dumpAll) {
14042                    pw.println("-------------------------------------------------------------------------------");
14043                }
14044                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14045                pw.println();
14046                if (dumpAll) {
14047                    pw.println("-------------------------------------------------------------------------------");
14048                }
14049                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14050                if (mAssociations.size() > 0) {
14051                    pw.println();
14052                    if (dumpAll) {
14053                        pw.println("-------------------------------------------------------------------------------");
14054                    }
14055                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14056                }
14057                pw.println();
14058                if (dumpAll) {
14059                    pw.println("-------------------------------------------------------------------------------");
14060                }
14061                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14062            }
14063        }
14064        Binder.restoreCallingIdentity(origId);
14065    }
14066
14067    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14068            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14069        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14070
14071        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14072                dumpPackage);
14073        boolean needSep = printedAnything;
14074
14075        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14076                dumpPackage, needSep, "  mFocusedActivity: ");
14077        if (printed) {
14078            printedAnything = true;
14079            needSep = false;
14080        }
14081
14082        if (dumpPackage == null) {
14083            if (needSep) {
14084                pw.println();
14085            }
14086            needSep = true;
14087            printedAnything = true;
14088            mStackSupervisor.dump(pw, "  ");
14089        }
14090
14091        if (!printedAnything) {
14092            pw.println("  (nothing)");
14093        }
14094    }
14095
14096    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14097            int opti, boolean dumpAll, String dumpPackage) {
14098        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14099
14100        boolean printedAnything = false;
14101
14102        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14103            boolean printedHeader = false;
14104
14105            final int N = mRecentTasks.size();
14106            for (int i=0; i<N; i++) {
14107                TaskRecord tr = mRecentTasks.get(i);
14108                if (dumpPackage != null) {
14109                    if (tr.realActivity == null ||
14110                            !dumpPackage.equals(tr.realActivity)) {
14111                        continue;
14112                    }
14113                }
14114                if (!printedHeader) {
14115                    pw.println("  Recent tasks:");
14116                    printedHeader = true;
14117                    printedAnything = true;
14118                }
14119                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14120                        pw.println(tr);
14121                if (dumpAll) {
14122                    mRecentTasks.get(i).dump(pw, "    ");
14123                }
14124            }
14125        }
14126
14127        if (!printedAnything) {
14128            pw.println("  (nothing)");
14129        }
14130    }
14131
14132    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14133            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14134        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14135
14136        int dumpUid = 0;
14137        if (dumpPackage != null) {
14138            IPackageManager pm = AppGlobals.getPackageManager();
14139            try {
14140                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14141            } catch (RemoteException e) {
14142            }
14143        }
14144
14145        boolean printedAnything = false;
14146
14147        final long now = SystemClock.uptimeMillis();
14148
14149        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14150            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14151                    = mAssociations.valueAt(i1);
14152            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14153                SparseArray<ArrayMap<String, Association>> sourceUids
14154                        = targetComponents.valueAt(i2);
14155                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14156                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14157                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14158                        Association ass = sourceProcesses.valueAt(i4);
14159                        if (dumpPackage != null) {
14160                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14161                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14162                                continue;
14163                            }
14164                        }
14165                        printedAnything = true;
14166                        pw.print("  ");
14167                        pw.print(ass.mTargetProcess);
14168                        pw.print("/");
14169                        UserHandle.formatUid(pw, ass.mTargetUid);
14170                        pw.print(" <- ");
14171                        pw.print(ass.mSourceProcess);
14172                        pw.print("/");
14173                        UserHandle.formatUid(pw, ass.mSourceUid);
14174                        pw.println();
14175                        pw.print("    via ");
14176                        pw.print(ass.mTargetComponent.flattenToShortString());
14177                        pw.println();
14178                        pw.print("    ");
14179                        long dur = ass.mTime;
14180                        if (ass.mNesting > 0) {
14181                            dur += now - ass.mStartTime;
14182                        }
14183                        TimeUtils.formatDuration(dur, pw);
14184                        pw.print(" (");
14185                        pw.print(ass.mCount);
14186                        pw.print(" times)");
14187                        pw.print("  ");
14188                        for (int i=0; i<ass.mStateTimes.length; i++) {
14189                            long amt = ass.mStateTimes[i];
14190                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14191                                amt += now - ass.mLastStateUptime;
14192                            }
14193                            if (amt != 0) {
14194                                pw.print(" ");
14195                                pw.print(ProcessList.makeProcStateString(
14196                                            i + ActivityManager.MIN_PROCESS_STATE));
14197                                pw.print("=");
14198                                TimeUtils.formatDuration(amt, pw);
14199                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14200                                    pw.print("*");
14201                                }
14202                            }
14203                        }
14204                        pw.println();
14205                        if (ass.mNesting > 0) {
14206                            pw.print("    Currently active: ");
14207                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14208                            pw.println();
14209                        }
14210                    }
14211                }
14212            }
14213
14214        }
14215
14216        if (!printedAnything) {
14217            pw.println("  (nothing)");
14218        }
14219    }
14220
14221    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14222            String header, boolean needSep) {
14223        boolean printed = false;
14224        int whichAppId = -1;
14225        if (dumpPackage != null) {
14226            try {
14227                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14228                        dumpPackage, 0);
14229                whichAppId = UserHandle.getAppId(info.uid);
14230            } catch (NameNotFoundException e) {
14231                e.printStackTrace();
14232            }
14233        }
14234        for (int i=0; i<uids.size(); i++) {
14235            UidRecord uidRec = uids.valueAt(i);
14236            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14237                continue;
14238            }
14239            if (!printed) {
14240                printed = true;
14241                if (needSep) {
14242                    pw.println();
14243                }
14244                pw.print("  ");
14245                pw.println(header);
14246                needSep = true;
14247            }
14248            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14249            pw.print(": "); pw.println(uidRec);
14250        }
14251        return printed;
14252    }
14253
14254    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14255            int opti, boolean dumpAll, String dumpPackage) {
14256        boolean needSep = false;
14257        boolean printedAnything = false;
14258        int numPers = 0;
14259
14260        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14261
14262        if (dumpAll) {
14263            final int NP = mProcessNames.getMap().size();
14264            for (int ip=0; ip<NP; ip++) {
14265                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14266                final int NA = procs.size();
14267                for (int ia=0; ia<NA; ia++) {
14268                    ProcessRecord r = procs.valueAt(ia);
14269                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14270                        continue;
14271                    }
14272                    if (!needSep) {
14273                        pw.println("  All known processes:");
14274                        needSep = true;
14275                        printedAnything = true;
14276                    }
14277                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14278                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14279                        pw.print(" "); pw.println(r);
14280                    r.dump(pw, "    ");
14281                    if (r.persistent) {
14282                        numPers++;
14283                    }
14284                }
14285            }
14286        }
14287
14288        if (mIsolatedProcesses.size() > 0) {
14289            boolean printed = false;
14290            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14291                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14292                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14293                    continue;
14294                }
14295                if (!printed) {
14296                    if (needSep) {
14297                        pw.println();
14298                    }
14299                    pw.println("  Isolated process list (sorted by uid):");
14300                    printedAnything = true;
14301                    printed = true;
14302                    needSep = true;
14303                }
14304                pw.println(String.format("%sIsolated #%2d: %s",
14305                        "    ", i, r.toString()));
14306            }
14307        }
14308
14309        if (mActiveUids.size() > 0) {
14310            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14311                printedAnything = needSep = true;
14312            }
14313        }
14314        if (mValidateUids.size() > 0) {
14315            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14316                printedAnything = needSep = true;
14317            }
14318        }
14319
14320        if (mLruProcesses.size() > 0) {
14321            if (needSep) {
14322                pw.println();
14323            }
14324            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14325                    pw.print(" total, non-act at ");
14326                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14327                    pw.print(", non-svc at ");
14328                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14329                    pw.println("):");
14330            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14331            needSep = true;
14332            printedAnything = true;
14333        }
14334
14335        if (dumpAll || dumpPackage != null) {
14336            synchronized (mPidsSelfLocked) {
14337                boolean printed = false;
14338                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14339                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14340                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14341                        continue;
14342                    }
14343                    if (!printed) {
14344                        if (needSep) pw.println();
14345                        needSep = true;
14346                        pw.println("  PID mappings:");
14347                        printed = true;
14348                        printedAnything = true;
14349                    }
14350                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14351                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14352                }
14353            }
14354        }
14355
14356        if (mForegroundProcesses.size() > 0) {
14357            synchronized (mPidsSelfLocked) {
14358                boolean printed = false;
14359                for (int i=0; i<mForegroundProcesses.size(); i++) {
14360                    ProcessRecord r = mPidsSelfLocked.get(
14361                            mForegroundProcesses.valueAt(i).pid);
14362                    if (dumpPackage != null && (r == null
14363                            || !r.pkgList.containsKey(dumpPackage))) {
14364                        continue;
14365                    }
14366                    if (!printed) {
14367                        if (needSep) pw.println();
14368                        needSep = true;
14369                        pw.println("  Foreground Processes:");
14370                        printed = true;
14371                        printedAnything = true;
14372                    }
14373                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14374                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14375                }
14376            }
14377        }
14378
14379        if (mPersistentStartingProcesses.size() > 0) {
14380            if (needSep) pw.println();
14381            needSep = true;
14382            printedAnything = true;
14383            pw.println("  Persisent processes that are starting:");
14384            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14385                    "Starting Norm", "Restarting PERS", dumpPackage);
14386        }
14387
14388        if (mRemovedProcesses.size() > 0) {
14389            if (needSep) pw.println();
14390            needSep = true;
14391            printedAnything = true;
14392            pw.println("  Processes that are being removed:");
14393            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14394                    "Removed Norm", "Removed PERS", dumpPackage);
14395        }
14396
14397        if (mProcessesOnHold.size() > 0) {
14398            if (needSep) pw.println();
14399            needSep = true;
14400            printedAnything = true;
14401            pw.println("  Processes that are on old until the system is ready:");
14402            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14403                    "OnHold Norm", "OnHold PERS", dumpPackage);
14404        }
14405
14406        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14407
14408        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14409        if (needSep) {
14410            printedAnything = true;
14411        }
14412
14413        if (dumpPackage == null) {
14414            pw.println();
14415            needSep = false;
14416            mUserController.dump(pw, dumpAll);
14417        }
14418        if (mHomeProcess != null && (dumpPackage == null
14419                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14420            if (needSep) {
14421                pw.println();
14422                needSep = false;
14423            }
14424            pw.println("  mHomeProcess: " + mHomeProcess);
14425        }
14426        if (mPreviousProcess != null && (dumpPackage == null
14427                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14428            if (needSep) {
14429                pw.println();
14430                needSep = false;
14431            }
14432            pw.println("  mPreviousProcess: " + mPreviousProcess);
14433        }
14434        if (dumpAll) {
14435            StringBuilder sb = new StringBuilder(128);
14436            sb.append("  mPreviousProcessVisibleTime: ");
14437            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14438            pw.println(sb);
14439        }
14440        if (mHeavyWeightProcess != null && (dumpPackage == null
14441                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14442            if (needSep) {
14443                pw.println();
14444                needSep = false;
14445            }
14446            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14447        }
14448        if (dumpPackage == null) {
14449            pw.println("  mConfiguration: " + mConfiguration);
14450        }
14451        if (dumpAll) {
14452            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14453            if (mCompatModePackages.getPackages().size() > 0) {
14454                boolean printed = false;
14455                for (Map.Entry<String, Integer> entry
14456                        : mCompatModePackages.getPackages().entrySet()) {
14457                    String pkg = entry.getKey();
14458                    int mode = entry.getValue();
14459                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14460                        continue;
14461                    }
14462                    if (!printed) {
14463                        pw.println("  mScreenCompatPackages:");
14464                        printed = true;
14465                    }
14466                    pw.print("    "); pw.print(pkg); pw.print(": ");
14467                            pw.print(mode); pw.println();
14468                }
14469            }
14470        }
14471        if (dumpPackage == null) {
14472            pw.println("  mWakefulness="
14473                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14474            pw.println("  mSleepTokens=" + mSleepTokens);
14475            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14476                    + lockScreenShownToString());
14477            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14478            if (mRunningVoice != null) {
14479                pw.println("  mRunningVoice=" + mRunningVoice);
14480                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14481            }
14482        }
14483        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14484                || mOrigWaitForDebugger) {
14485            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14486                    || dumpPackage.equals(mOrigDebugApp)) {
14487                if (needSep) {
14488                    pw.println();
14489                    needSep = false;
14490                }
14491                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14492                        + " mDebugTransient=" + mDebugTransient
14493                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14494            }
14495        }
14496        if (mCurAppTimeTracker != null) {
14497            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14498        }
14499        if (mMemWatchProcesses.getMap().size() > 0) {
14500            pw.println("  Mem watch processes:");
14501            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14502                    = mMemWatchProcesses.getMap();
14503            for (int i=0; i<procs.size(); i++) {
14504                final String proc = procs.keyAt(i);
14505                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14506                for (int j=0; j<uids.size(); j++) {
14507                    if (needSep) {
14508                        pw.println();
14509                        needSep = false;
14510                    }
14511                    StringBuilder sb = new StringBuilder();
14512                    sb.append("    ").append(proc).append('/');
14513                    UserHandle.formatUid(sb, uids.keyAt(j));
14514                    Pair<Long, String> val = uids.valueAt(j);
14515                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14516                    if (val.second != null) {
14517                        sb.append(", report to ").append(val.second);
14518                    }
14519                    pw.println(sb.toString());
14520                }
14521            }
14522            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14523            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14524            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14525                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14526        }
14527        if (mTrackAllocationApp != null) {
14528            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14529                if (needSep) {
14530                    pw.println();
14531                    needSep = false;
14532                }
14533                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14534            }
14535        }
14536        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14537                || mProfileFd != null) {
14538            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14539                if (needSep) {
14540                    pw.println();
14541                    needSep = false;
14542                }
14543                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14544                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14545                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14546                        + mAutoStopProfiler);
14547                pw.println("  mProfileType=" + mProfileType);
14548            }
14549        }
14550        if (mNativeDebuggingApp != null) {
14551            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14552                if (needSep) {
14553                    pw.println();
14554                    needSep = false;
14555                }
14556                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14557            }
14558        }
14559        if (dumpPackage == null) {
14560            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14561                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14562                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14563            }
14564            if (mController != null) {
14565                pw.println("  mController=" + mController
14566                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14567            }
14568            if (dumpAll) {
14569                pw.println("  Total persistent processes: " + numPers);
14570                pw.println("  mProcessesReady=" + mProcessesReady
14571                        + " mSystemReady=" + mSystemReady
14572                        + " mBooted=" + mBooted
14573                        + " mFactoryTest=" + mFactoryTest);
14574                pw.println("  mBooting=" + mBooting
14575                        + " mCallFinishBooting=" + mCallFinishBooting
14576                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14577                pw.print("  mLastPowerCheckRealtime=");
14578                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14579                        pw.println("");
14580                pw.print("  mLastPowerCheckUptime=");
14581                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14582                        pw.println("");
14583                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14584                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14585                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14586                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14587                        + " (" + mLruProcesses.size() + " total)"
14588                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14589                        + " mNumServiceProcs=" + mNumServiceProcs
14590                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14591                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14592                        + " mLastMemoryLevel=" + mLastMemoryLevel
14593                        + " mLastNumProcesses=" + mLastNumProcesses);
14594                long now = SystemClock.uptimeMillis();
14595                pw.print("  mLastIdleTime=");
14596                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14597                        pw.print(" mLowRamSinceLastIdle=");
14598                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14599                        pw.println();
14600            }
14601        }
14602
14603        if (!printedAnything) {
14604            pw.println("  (nothing)");
14605        }
14606    }
14607
14608    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14609            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14610        if (mProcessesToGc.size() > 0) {
14611            boolean printed = false;
14612            long now = SystemClock.uptimeMillis();
14613            for (int i=0; i<mProcessesToGc.size(); i++) {
14614                ProcessRecord proc = mProcessesToGc.get(i);
14615                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14616                    continue;
14617                }
14618                if (!printed) {
14619                    if (needSep) pw.println();
14620                    needSep = true;
14621                    pw.println("  Processes that are waiting to GC:");
14622                    printed = true;
14623                }
14624                pw.print("    Process "); pw.println(proc);
14625                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14626                        pw.print(", last gced=");
14627                        pw.print(now-proc.lastRequestedGc);
14628                        pw.print(" ms ago, last lowMem=");
14629                        pw.print(now-proc.lastLowMemory);
14630                        pw.println(" ms ago");
14631
14632            }
14633        }
14634        return needSep;
14635    }
14636
14637    void printOomLevel(PrintWriter pw, String name, int adj) {
14638        pw.print("    ");
14639        if (adj >= 0) {
14640            pw.print(' ');
14641            if (adj < 10) pw.print(' ');
14642        } else {
14643            if (adj > -10) pw.print(' ');
14644        }
14645        pw.print(adj);
14646        pw.print(": ");
14647        pw.print(name);
14648        pw.print(" (");
14649        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14650        pw.println(")");
14651    }
14652
14653    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14654            int opti, boolean dumpAll) {
14655        boolean needSep = false;
14656
14657        if (mLruProcesses.size() > 0) {
14658            if (needSep) pw.println();
14659            needSep = true;
14660            pw.println("  OOM levels:");
14661            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14662            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14663            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14664            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14665            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14666            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14667            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14668            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14669            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14670            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14671            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14672            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14673            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14674            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14675
14676            if (needSep) pw.println();
14677            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14678                    pw.print(" total, non-act at ");
14679                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14680                    pw.print(", non-svc at ");
14681                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14682                    pw.println("):");
14683            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14684            needSep = true;
14685        }
14686
14687        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14688
14689        pw.println();
14690        pw.println("  mHomeProcess: " + mHomeProcess);
14691        pw.println("  mPreviousProcess: " + mPreviousProcess);
14692        if (mHeavyWeightProcess != null) {
14693            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14694        }
14695
14696        return true;
14697    }
14698
14699    /**
14700     * There are three ways to call this:
14701     *  - no provider specified: dump all the providers
14702     *  - a flattened component name that matched an existing provider was specified as the
14703     *    first arg: dump that one provider
14704     *  - the first arg isn't the flattened component name of an existing provider:
14705     *    dump all providers whose component contains the first arg as a substring
14706     */
14707    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14708            int opti, boolean dumpAll) {
14709        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14710    }
14711
14712    static class ItemMatcher {
14713        ArrayList<ComponentName> components;
14714        ArrayList<String> strings;
14715        ArrayList<Integer> objects;
14716        boolean all;
14717
14718        ItemMatcher() {
14719            all = true;
14720        }
14721
14722        void build(String name) {
14723            ComponentName componentName = ComponentName.unflattenFromString(name);
14724            if (componentName != null) {
14725                if (components == null) {
14726                    components = new ArrayList<ComponentName>();
14727                }
14728                components.add(componentName);
14729                all = false;
14730            } else {
14731                int objectId = 0;
14732                // Not a '/' separated full component name; maybe an object ID?
14733                try {
14734                    objectId = Integer.parseInt(name, 16);
14735                    if (objects == null) {
14736                        objects = new ArrayList<Integer>();
14737                    }
14738                    objects.add(objectId);
14739                    all = false;
14740                } catch (RuntimeException e) {
14741                    // Not an integer; just do string match.
14742                    if (strings == null) {
14743                        strings = new ArrayList<String>();
14744                    }
14745                    strings.add(name);
14746                    all = false;
14747                }
14748            }
14749        }
14750
14751        int build(String[] args, int opti) {
14752            for (; opti<args.length; opti++) {
14753                String name = args[opti];
14754                if ("--".equals(name)) {
14755                    return opti+1;
14756                }
14757                build(name);
14758            }
14759            return opti;
14760        }
14761
14762        boolean match(Object object, ComponentName comp) {
14763            if (all) {
14764                return true;
14765            }
14766            if (components != null) {
14767                for (int i=0; i<components.size(); i++) {
14768                    if (components.get(i).equals(comp)) {
14769                        return true;
14770                    }
14771                }
14772            }
14773            if (objects != null) {
14774                for (int i=0; i<objects.size(); i++) {
14775                    if (System.identityHashCode(object) == objects.get(i)) {
14776                        return true;
14777                    }
14778                }
14779            }
14780            if (strings != null) {
14781                String flat = comp.flattenToString();
14782                for (int i=0; i<strings.size(); i++) {
14783                    if (flat.contains(strings.get(i))) {
14784                        return true;
14785                    }
14786                }
14787            }
14788            return false;
14789        }
14790    }
14791
14792    /**
14793     * There are three things that cmd can be:
14794     *  - a flattened component name that matches an existing activity
14795     *  - the cmd arg isn't the flattened component name of an existing activity:
14796     *    dump all activity whose component contains the cmd as a substring
14797     *  - A hex number of the ActivityRecord object instance.
14798     */
14799    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14800            int opti, boolean dumpAll) {
14801        ArrayList<ActivityRecord> activities;
14802
14803        synchronized (this) {
14804            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14805        }
14806
14807        if (activities.size() <= 0) {
14808            return false;
14809        }
14810
14811        String[] newArgs = new String[args.length - opti];
14812        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14813
14814        TaskRecord lastTask = null;
14815        boolean needSep = false;
14816        for (int i=activities.size()-1; i>=0; i--) {
14817            ActivityRecord r = activities.get(i);
14818            if (needSep) {
14819                pw.println();
14820            }
14821            needSep = true;
14822            synchronized (this) {
14823                if (lastTask != r.task) {
14824                    lastTask = r.task;
14825                    pw.print("TASK "); pw.print(lastTask.affinity);
14826                            pw.print(" id="); pw.println(lastTask.taskId);
14827                    if (dumpAll) {
14828                        lastTask.dump(pw, "  ");
14829                    }
14830                }
14831            }
14832            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14833        }
14834        return true;
14835    }
14836
14837    /**
14838     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14839     * there is a thread associated with the activity.
14840     */
14841    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14842            final ActivityRecord r, String[] args, boolean dumpAll) {
14843        String innerPrefix = prefix + "  ";
14844        synchronized (this) {
14845            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14846                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14847                    pw.print(" pid=");
14848                    if (r.app != null) pw.println(r.app.pid);
14849                    else pw.println("(not running)");
14850            if (dumpAll) {
14851                r.dump(pw, innerPrefix);
14852            }
14853        }
14854        if (r.app != null && r.app.thread != null) {
14855            // flush anything that is already in the PrintWriter since the thread is going
14856            // to write to the file descriptor directly
14857            pw.flush();
14858            try {
14859                TransferPipe tp = new TransferPipe();
14860                try {
14861                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14862                            r.appToken, innerPrefix, args);
14863                    tp.go(fd);
14864                } finally {
14865                    tp.kill();
14866                }
14867            } catch (IOException e) {
14868                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14869            } catch (RemoteException e) {
14870                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14871            }
14872        }
14873    }
14874
14875    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14876            int opti, boolean dumpAll, String dumpPackage) {
14877        boolean needSep = false;
14878        boolean onlyHistory = false;
14879        boolean printedAnything = false;
14880
14881        if ("history".equals(dumpPackage)) {
14882            if (opti < args.length && "-s".equals(args[opti])) {
14883                dumpAll = false;
14884            }
14885            onlyHistory = true;
14886            dumpPackage = null;
14887        }
14888
14889        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14890        if (!onlyHistory && dumpAll) {
14891            if (mRegisteredReceivers.size() > 0) {
14892                boolean printed = false;
14893                Iterator it = mRegisteredReceivers.values().iterator();
14894                while (it.hasNext()) {
14895                    ReceiverList r = (ReceiverList)it.next();
14896                    if (dumpPackage != null && (r.app == null ||
14897                            !dumpPackage.equals(r.app.info.packageName))) {
14898                        continue;
14899                    }
14900                    if (!printed) {
14901                        pw.println("  Registered Receivers:");
14902                        needSep = true;
14903                        printed = true;
14904                        printedAnything = true;
14905                    }
14906                    pw.print("  * "); pw.println(r);
14907                    r.dump(pw, "    ");
14908                }
14909            }
14910
14911            if (mReceiverResolver.dump(pw, needSep ?
14912                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14913                    "    ", dumpPackage, false, false)) {
14914                needSep = true;
14915                printedAnything = true;
14916            }
14917        }
14918
14919        for (BroadcastQueue q : mBroadcastQueues) {
14920            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14921            printedAnything |= needSep;
14922        }
14923
14924        needSep = true;
14925
14926        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14927            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14928                if (needSep) {
14929                    pw.println();
14930                }
14931                needSep = true;
14932                printedAnything = true;
14933                pw.print("  Sticky broadcasts for user ");
14934                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14935                StringBuilder sb = new StringBuilder(128);
14936                for (Map.Entry<String, ArrayList<Intent>> ent
14937                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14938                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14939                    if (dumpAll) {
14940                        pw.println(":");
14941                        ArrayList<Intent> intents = ent.getValue();
14942                        final int N = intents.size();
14943                        for (int i=0; i<N; i++) {
14944                            sb.setLength(0);
14945                            sb.append("    Intent: ");
14946                            intents.get(i).toShortString(sb, false, true, false, false);
14947                            pw.println(sb.toString());
14948                            Bundle bundle = intents.get(i).getExtras();
14949                            if (bundle != null) {
14950                                pw.print("      ");
14951                                pw.println(bundle.toString());
14952                            }
14953                        }
14954                    } else {
14955                        pw.println("");
14956                    }
14957                }
14958            }
14959        }
14960
14961        if (!onlyHistory && dumpAll) {
14962            pw.println();
14963            for (BroadcastQueue queue : mBroadcastQueues) {
14964                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14965                        + queue.mBroadcastsScheduled);
14966            }
14967            pw.println("  mHandler:");
14968            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14969            needSep = true;
14970            printedAnything = true;
14971        }
14972
14973        if (!printedAnything) {
14974            pw.println("  (nothing)");
14975        }
14976    }
14977
14978    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14979            int opti, boolean dumpAll, String dumpPackage) {
14980        boolean needSep;
14981        boolean printedAnything = false;
14982
14983        ItemMatcher matcher = new ItemMatcher();
14984        matcher.build(args, opti);
14985
14986        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14987
14988        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14989        printedAnything |= needSep;
14990
14991        if (mLaunchingProviders.size() > 0) {
14992            boolean printed = false;
14993            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14994                ContentProviderRecord r = mLaunchingProviders.get(i);
14995                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14996                    continue;
14997                }
14998                if (!printed) {
14999                    if (needSep) pw.println();
15000                    needSep = true;
15001                    pw.println("  Launching content providers:");
15002                    printed = true;
15003                    printedAnything = true;
15004                }
15005                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15006                        pw.println(r);
15007            }
15008        }
15009
15010        if (!printedAnything) {
15011            pw.println("  (nothing)");
15012        }
15013    }
15014
15015    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15016            int opti, boolean dumpAll, String dumpPackage) {
15017        boolean needSep = false;
15018        boolean printedAnything = false;
15019
15020        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15021
15022        if (mGrantedUriPermissions.size() > 0) {
15023            boolean printed = false;
15024            int dumpUid = -2;
15025            if (dumpPackage != null) {
15026                try {
15027                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15028                            MATCH_UNINSTALLED_PACKAGES, 0);
15029                } catch (NameNotFoundException e) {
15030                    dumpUid = -1;
15031                }
15032            }
15033            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15034                int uid = mGrantedUriPermissions.keyAt(i);
15035                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15036                    continue;
15037                }
15038                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15039                if (!printed) {
15040                    if (needSep) pw.println();
15041                    needSep = true;
15042                    pw.println("  Granted Uri Permissions:");
15043                    printed = true;
15044                    printedAnything = true;
15045                }
15046                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15047                for (UriPermission perm : perms.values()) {
15048                    pw.print("    "); pw.println(perm);
15049                    if (dumpAll) {
15050                        perm.dump(pw, "      ");
15051                    }
15052                }
15053            }
15054        }
15055
15056        if (!printedAnything) {
15057            pw.println("  (nothing)");
15058        }
15059    }
15060
15061    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15062            int opti, boolean dumpAll, String dumpPackage) {
15063        boolean printed = false;
15064
15065        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15066
15067        if (mIntentSenderRecords.size() > 0) {
15068            Iterator<WeakReference<PendingIntentRecord>> it
15069                    = mIntentSenderRecords.values().iterator();
15070            while (it.hasNext()) {
15071                WeakReference<PendingIntentRecord> ref = it.next();
15072                PendingIntentRecord rec = ref != null ? ref.get(): null;
15073                if (dumpPackage != null && (rec == null
15074                        || !dumpPackage.equals(rec.key.packageName))) {
15075                    continue;
15076                }
15077                printed = true;
15078                if (rec != null) {
15079                    pw.print("  * "); pw.println(rec);
15080                    if (dumpAll) {
15081                        rec.dump(pw, "    ");
15082                    }
15083                } else {
15084                    pw.print("  * "); pw.println(ref);
15085                }
15086            }
15087        }
15088
15089        if (!printed) {
15090            pw.println("  (nothing)");
15091        }
15092    }
15093
15094    private static final int dumpProcessList(PrintWriter pw,
15095            ActivityManagerService service, List list,
15096            String prefix, String normalLabel, String persistentLabel,
15097            String dumpPackage) {
15098        int numPers = 0;
15099        final int N = list.size()-1;
15100        for (int i=N; i>=0; i--) {
15101            ProcessRecord r = (ProcessRecord)list.get(i);
15102            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15103                continue;
15104            }
15105            pw.println(String.format("%s%s #%2d: %s",
15106                    prefix, (r.persistent ? persistentLabel : normalLabel),
15107                    i, r.toString()));
15108            if (r.persistent) {
15109                numPers++;
15110            }
15111        }
15112        return numPers;
15113    }
15114
15115    private static final boolean dumpProcessOomList(PrintWriter pw,
15116            ActivityManagerService service, List<ProcessRecord> origList,
15117            String prefix, String normalLabel, String persistentLabel,
15118            boolean inclDetails, String dumpPackage) {
15119
15120        ArrayList<Pair<ProcessRecord, Integer>> list
15121                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15122        for (int i=0; i<origList.size(); i++) {
15123            ProcessRecord r = origList.get(i);
15124            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15125                continue;
15126            }
15127            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15128        }
15129
15130        if (list.size() <= 0) {
15131            return false;
15132        }
15133
15134        Comparator<Pair<ProcessRecord, Integer>> comparator
15135                = new Comparator<Pair<ProcessRecord, Integer>>() {
15136            @Override
15137            public int compare(Pair<ProcessRecord, Integer> object1,
15138                    Pair<ProcessRecord, Integer> object2) {
15139                if (object1.first.setAdj != object2.first.setAdj) {
15140                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15141                }
15142                if (object1.first.setProcState != object2.first.setProcState) {
15143                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15144                }
15145                if (object1.second.intValue() != object2.second.intValue()) {
15146                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15147                }
15148                return 0;
15149            }
15150        };
15151
15152        Collections.sort(list, comparator);
15153
15154        final long curRealtime = SystemClock.elapsedRealtime();
15155        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15156        final long curUptime = SystemClock.uptimeMillis();
15157        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15158
15159        for (int i=list.size()-1; i>=0; i--) {
15160            ProcessRecord r = list.get(i).first;
15161            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15162            char schedGroup;
15163            switch (r.setSchedGroup) {
15164                case ProcessList.SCHED_GROUP_BACKGROUND:
15165                    schedGroup = 'B';
15166                    break;
15167                case ProcessList.SCHED_GROUP_DEFAULT:
15168                    schedGroup = 'F';
15169                    break;
15170                case ProcessList.SCHED_GROUP_TOP_APP:
15171                    schedGroup = 'T';
15172                    break;
15173                default:
15174                    schedGroup = '?';
15175                    break;
15176            }
15177            char foreground;
15178            if (r.foregroundActivities) {
15179                foreground = 'A';
15180            } else if (r.foregroundServices) {
15181                foreground = 'S';
15182            } else {
15183                foreground = ' ';
15184            }
15185            String procState = ProcessList.makeProcStateString(r.curProcState);
15186            pw.print(prefix);
15187            pw.print(r.persistent ? persistentLabel : normalLabel);
15188            pw.print(" #");
15189            int num = (origList.size()-1)-list.get(i).second;
15190            if (num < 10) pw.print(' ');
15191            pw.print(num);
15192            pw.print(": ");
15193            pw.print(oomAdj);
15194            pw.print(' ');
15195            pw.print(schedGroup);
15196            pw.print('/');
15197            pw.print(foreground);
15198            pw.print('/');
15199            pw.print(procState);
15200            pw.print(" trm:");
15201            if (r.trimMemoryLevel < 10) pw.print(' ');
15202            pw.print(r.trimMemoryLevel);
15203            pw.print(' ');
15204            pw.print(r.toShortString());
15205            pw.print(" (");
15206            pw.print(r.adjType);
15207            pw.println(')');
15208            if (r.adjSource != null || r.adjTarget != null) {
15209                pw.print(prefix);
15210                pw.print("    ");
15211                if (r.adjTarget instanceof ComponentName) {
15212                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15213                } else if (r.adjTarget != null) {
15214                    pw.print(r.adjTarget.toString());
15215                } else {
15216                    pw.print("{null}");
15217                }
15218                pw.print("<=");
15219                if (r.adjSource instanceof ProcessRecord) {
15220                    pw.print("Proc{");
15221                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15222                    pw.println("}");
15223                } else if (r.adjSource != null) {
15224                    pw.println(r.adjSource.toString());
15225                } else {
15226                    pw.println("{null}");
15227                }
15228            }
15229            if (inclDetails) {
15230                pw.print(prefix);
15231                pw.print("    ");
15232                pw.print("oom: max="); pw.print(r.maxAdj);
15233                pw.print(" curRaw="); pw.print(r.curRawAdj);
15234                pw.print(" setRaw="); pw.print(r.setRawAdj);
15235                pw.print(" cur="); pw.print(r.curAdj);
15236                pw.print(" set="); pw.println(r.setAdj);
15237                pw.print(prefix);
15238                pw.print("    ");
15239                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15240                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15241                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15242                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15243                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15244                pw.println();
15245                pw.print(prefix);
15246                pw.print("    ");
15247                pw.print("cached="); pw.print(r.cached);
15248                pw.print(" empty="); pw.print(r.empty);
15249                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15250
15251                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15252                    if (r.lastWakeTime != 0) {
15253                        long wtime;
15254                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15255                        synchronized (stats) {
15256                            wtime = stats.getProcessWakeTime(r.info.uid,
15257                                    r.pid, curRealtime);
15258                        }
15259                        long timeUsed = wtime - r.lastWakeTime;
15260                        pw.print(prefix);
15261                        pw.print("    ");
15262                        pw.print("keep awake over ");
15263                        TimeUtils.formatDuration(realtimeSince, pw);
15264                        pw.print(" used ");
15265                        TimeUtils.formatDuration(timeUsed, pw);
15266                        pw.print(" (");
15267                        pw.print((timeUsed*100)/realtimeSince);
15268                        pw.println("%)");
15269                    }
15270                    if (r.lastCpuTime != 0) {
15271                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15272                        pw.print(prefix);
15273                        pw.print("    ");
15274                        pw.print("run cpu over ");
15275                        TimeUtils.formatDuration(uptimeSince, pw);
15276                        pw.print(" used ");
15277                        TimeUtils.formatDuration(timeUsed, pw);
15278                        pw.print(" (");
15279                        pw.print((timeUsed*100)/uptimeSince);
15280                        pw.println("%)");
15281                    }
15282                }
15283            }
15284        }
15285        return true;
15286    }
15287
15288    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15289            String[] args) {
15290        ArrayList<ProcessRecord> procs;
15291        synchronized (this) {
15292            if (args != null && args.length > start
15293                    && args[start].charAt(0) != '-') {
15294                procs = new ArrayList<ProcessRecord>();
15295                int pid = -1;
15296                try {
15297                    pid = Integer.parseInt(args[start]);
15298                } catch (NumberFormatException e) {
15299                }
15300                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15301                    ProcessRecord proc = mLruProcesses.get(i);
15302                    if (proc.pid == pid) {
15303                        procs.add(proc);
15304                    } else if (allPkgs && proc.pkgList != null
15305                            && proc.pkgList.containsKey(args[start])) {
15306                        procs.add(proc);
15307                    } else if (proc.processName.equals(args[start])) {
15308                        procs.add(proc);
15309                    }
15310                }
15311                if (procs.size() <= 0) {
15312                    return null;
15313                }
15314            } else {
15315                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15316            }
15317        }
15318        return procs;
15319    }
15320
15321    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15322            PrintWriter pw, String[] args) {
15323        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15324        if (procs == null) {
15325            pw.println("No process found for: " + args[0]);
15326            return;
15327        }
15328
15329        long uptime = SystemClock.uptimeMillis();
15330        long realtime = SystemClock.elapsedRealtime();
15331        pw.println("Applications Graphics Acceleration Info:");
15332        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15333
15334        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15335            ProcessRecord r = procs.get(i);
15336            if (r.thread != null) {
15337                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15338                pw.flush();
15339                try {
15340                    TransferPipe tp = new TransferPipe();
15341                    try {
15342                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15343                        tp.go(fd);
15344                    } finally {
15345                        tp.kill();
15346                    }
15347                } catch (IOException e) {
15348                    pw.println("Failure while dumping the app: " + r);
15349                    pw.flush();
15350                } catch (RemoteException e) {
15351                    pw.println("Got a RemoteException while dumping the app " + r);
15352                    pw.flush();
15353                }
15354            }
15355        }
15356    }
15357
15358    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15359        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15360        if (procs == null) {
15361            pw.println("No process found for: " + args[0]);
15362            return;
15363        }
15364
15365        pw.println("Applications Database Info:");
15366
15367        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15368            ProcessRecord r = procs.get(i);
15369            if (r.thread != null) {
15370                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15371                pw.flush();
15372                try {
15373                    TransferPipe tp = new TransferPipe();
15374                    try {
15375                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15376                        tp.go(fd);
15377                    } finally {
15378                        tp.kill();
15379                    }
15380                } catch (IOException e) {
15381                    pw.println("Failure while dumping the app: " + r);
15382                    pw.flush();
15383                } catch (RemoteException e) {
15384                    pw.println("Got a RemoteException while dumping the app " + r);
15385                    pw.flush();
15386                }
15387            }
15388        }
15389    }
15390
15391    final static class MemItem {
15392        final boolean isProc;
15393        final String label;
15394        final String shortLabel;
15395        final long pss;
15396        final long swapPss;
15397        final int id;
15398        final boolean hasActivities;
15399        ArrayList<MemItem> subitems;
15400
15401        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15402                boolean _hasActivities) {
15403            isProc = true;
15404            label = _label;
15405            shortLabel = _shortLabel;
15406            pss = _pss;
15407            swapPss = _swapPss;
15408            id = _id;
15409            hasActivities = _hasActivities;
15410        }
15411
15412        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15413            isProc = false;
15414            label = _label;
15415            shortLabel = _shortLabel;
15416            pss = _pss;
15417            swapPss = _swapPss;
15418            id = _id;
15419            hasActivities = false;
15420        }
15421    }
15422
15423    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15424            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15425        if (sort && !isCompact) {
15426            Collections.sort(items, new Comparator<MemItem>() {
15427                @Override
15428                public int compare(MemItem lhs, MemItem rhs) {
15429                    if (lhs.pss < rhs.pss) {
15430                        return 1;
15431                    } else if (lhs.pss > rhs.pss) {
15432                        return -1;
15433                    }
15434                    return 0;
15435                }
15436            });
15437        }
15438
15439        for (int i=0; i<items.size(); i++) {
15440            MemItem mi = items.get(i);
15441            if (!isCompact) {
15442                if (dumpSwapPss) {
15443                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15444                            mi.label, stringifyKBSize(mi.swapPss));
15445                } else {
15446                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15447                }
15448            } else if (mi.isProc) {
15449                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15450                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15451                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15452                pw.println(mi.hasActivities ? ",a" : ",e");
15453            } else {
15454                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15455                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15456            }
15457            if (mi.subitems != null) {
15458                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15459                        true, isCompact, dumpSwapPss);
15460            }
15461        }
15462    }
15463
15464    // These are in KB.
15465    static final long[] DUMP_MEM_BUCKETS = new long[] {
15466        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15467        120*1024, 160*1024, 200*1024,
15468        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15469        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15470    };
15471
15472    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15473            boolean stackLike) {
15474        int start = label.lastIndexOf('.');
15475        if (start >= 0) start++;
15476        else start = 0;
15477        int end = label.length();
15478        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15479            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15480                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15481                out.append(bucket);
15482                out.append(stackLike ? "MB." : "MB ");
15483                out.append(label, start, end);
15484                return;
15485            }
15486        }
15487        out.append(memKB/1024);
15488        out.append(stackLike ? "MB." : "MB ");
15489        out.append(label, start, end);
15490    }
15491
15492    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15493            ProcessList.NATIVE_ADJ,
15494            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15495            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15496            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15497            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15498            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15499            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15500    };
15501    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15502            "Native",
15503            "System", "Persistent", "Persistent Service", "Foreground",
15504            "Visible", "Perceptible",
15505            "Heavy Weight", "Backup",
15506            "A Services", "Home",
15507            "Previous", "B Services", "Cached"
15508    };
15509    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15510            "native",
15511            "sys", "pers", "persvc", "fore",
15512            "vis", "percept",
15513            "heavy", "backup",
15514            "servicea", "home",
15515            "prev", "serviceb", "cached"
15516    };
15517
15518    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15519            long realtime, boolean isCheckinRequest, boolean isCompact) {
15520        if (isCompact) {
15521            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15522        }
15523        if (isCheckinRequest || isCompact) {
15524            // short checkin version
15525            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15526        } else {
15527            pw.println("Applications Memory Usage (in Kilobytes):");
15528            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15529        }
15530    }
15531
15532    private static final int KSM_SHARED = 0;
15533    private static final int KSM_SHARING = 1;
15534    private static final int KSM_UNSHARED = 2;
15535    private static final int KSM_VOLATILE = 3;
15536
15537    private final long[] getKsmInfo() {
15538        long[] longOut = new long[4];
15539        final int[] SINGLE_LONG_FORMAT = new int[] {
15540            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15541        };
15542        long[] longTmp = new long[1];
15543        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15544                SINGLE_LONG_FORMAT, null, longTmp, null);
15545        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15546        longTmp[0] = 0;
15547        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15548                SINGLE_LONG_FORMAT, null, longTmp, null);
15549        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15550        longTmp[0] = 0;
15551        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15552                SINGLE_LONG_FORMAT, null, longTmp, null);
15553        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15554        longTmp[0] = 0;
15555        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15556                SINGLE_LONG_FORMAT, null, longTmp, null);
15557        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15558        return longOut;
15559    }
15560
15561    private static String stringifySize(long size, int order) {
15562        Locale locale = Locale.US;
15563        switch (order) {
15564            case 1:
15565                return String.format(locale, "%,13d", size);
15566            case 1024:
15567                return String.format(locale, "%,9dK", size / 1024);
15568            case 1024 * 1024:
15569                return String.format(locale, "%,5dM", size / 1024 / 1024);
15570            case 1024 * 1024 * 1024:
15571                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15572            default:
15573                throw new IllegalArgumentException("Invalid size order");
15574        }
15575    }
15576
15577    private static String stringifyKBSize(long size) {
15578        return stringifySize(size * 1024, 1024);
15579    }
15580
15581    // Update this version number in case you change the 'compact' format
15582    private static final int MEMINFO_COMPACT_VERSION = 1;
15583
15584    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15585            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15586        boolean dumpDetails = false;
15587        boolean dumpFullDetails = false;
15588        boolean dumpDalvik = false;
15589        boolean dumpSummaryOnly = false;
15590        boolean dumpUnreachable = false;
15591        boolean oomOnly = false;
15592        boolean isCompact = false;
15593        boolean localOnly = false;
15594        boolean packages = false;
15595        boolean isCheckinRequest = false;
15596        boolean dumpSwapPss = false;
15597
15598        int opti = 0;
15599        while (opti < args.length) {
15600            String opt = args[opti];
15601            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15602                break;
15603            }
15604            opti++;
15605            if ("-a".equals(opt)) {
15606                dumpDetails = true;
15607                dumpFullDetails = true;
15608                dumpDalvik = true;
15609                dumpSwapPss = true;
15610            } else if ("-d".equals(opt)) {
15611                dumpDalvik = true;
15612            } else if ("-c".equals(opt)) {
15613                isCompact = true;
15614            } else if ("-s".equals(opt)) {
15615                dumpDetails = true;
15616                dumpSummaryOnly = true;
15617            } else if ("-S".equals(opt)) {
15618                dumpSwapPss = true;
15619            } else if ("--unreachable".equals(opt)) {
15620                dumpUnreachable = true;
15621            } else if ("--oom".equals(opt)) {
15622                oomOnly = true;
15623            } else if ("--local".equals(opt)) {
15624                localOnly = true;
15625            } else if ("--package".equals(opt)) {
15626                packages = true;
15627            } else if ("--checkin".equals(opt)) {
15628                isCheckinRequest = true;
15629
15630            } else if ("-h".equals(opt)) {
15631                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15632                pw.println("  -a: include all available information for each process.");
15633                pw.println("  -d: include dalvik details.");
15634                pw.println("  -c: dump in a compact machine-parseable representation.");
15635                pw.println("  -s: dump only summary of application memory usage.");
15636                pw.println("  -S: dump also SwapPss.");
15637                pw.println("  --oom: only show processes organized by oom adj.");
15638                pw.println("  --local: only collect details locally, don't call process.");
15639                pw.println("  --package: interpret process arg as package, dumping all");
15640                pw.println("             processes that have loaded that package.");
15641                pw.println("  --checkin: dump data for a checkin");
15642                pw.println("If [process] is specified it can be the name or ");
15643                pw.println("pid of a specific process to dump.");
15644                return;
15645            } else {
15646                pw.println("Unknown argument: " + opt + "; use -h for help");
15647            }
15648        }
15649
15650        long uptime = SystemClock.uptimeMillis();
15651        long realtime = SystemClock.elapsedRealtime();
15652        final long[] tmpLong = new long[1];
15653
15654        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15655        if (procs == null) {
15656            // No Java processes.  Maybe they want to print a native process.
15657            if (args != null && args.length > opti
15658                    && args[opti].charAt(0) != '-') {
15659                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15660                        = new ArrayList<ProcessCpuTracker.Stats>();
15661                updateCpuStatsNow();
15662                int findPid = -1;
15663                try {
15664                    findPid = Integer.parseInt(args[opti]);
15665                } catch (NumberFormatException e) {
15666                }
15667                synchronized (mProcessCpuTracker) {
15668                    final int N = mProcessCpuTracker.countStats();
15669                    for (int i=0; i<N; i++) {
15670                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15671                        if (st.pid == findPid || (st.baseName != null
15672                                && st.baseName.equals(args[opti]))) {
15673                            nativeProcs.add(st);
15674                        }
15675                    }
15676                }
15677                if (nativeProcs.size() > 0) {
15678                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15679                            isCompact);
15680                    Debug.MemoryInfo mi = null;
15681                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15682                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15683                        final int pid = r.pid;
15684                        if (!isCheckinRequest && dumpDetails) {
15685                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15686                        }
15687                        if (mi == null) {
15688                            mi = new Debug.MemoryInfo();
15689                        }
15690                        if (dumpDetails || (!brief && !oomOnly)) {
15691                            Debug.getMemoryInfo(pid, mi);
15692                        } else {
15693                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15694                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15695                        }
15696                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15697                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15698                        if (isCheckinRequest) {
15699                            pw.println();
15700                        }
15701                    }
15702                    return;
15703                }
15704            }
15705            pw.println("No process found for: " + args[opti]);
15706            return;
15707        }
15708
15709        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15710            dumpDetails = true;
15711        }
15712
15713        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15714
15715        String[] innerArgs = new String[args.length-opti];
15716        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15717
15718        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15719        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15720        long nativePss = 0;
15721        long nativeSwapPss = 0;
15722        long dalvikPss = 0;
15723        long dalvikSwapPss = 0;
15724        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15725                EmptyArray.LONG;
15726        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15727                EmptyArray.LONG;
15728        long otherPss = 0;
15729        long otherSwapPss = 0;
15730        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15731        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15732
15733        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15734        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15735        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15736                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15737
15738        long totalPss = 0;
15739        long totalSwapPss = 0;
15740        long cachedPss = 0;
15741        long cachedSwapPss = 0;
15742        boolean hasSwapPss = false;
15743
15744        Debug.MemoryInfo mi = null;
15745        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15746            final ProcessRecord r = procs.get(i);
15747            final IApplicationThread thread;
15748            final int pid;
15749            final int oomAdj;
15750            final boolean hasActivities;
15751            synchronized (this) {
15752                thread = r.thread;
15753                pid = r.pid;
15754                oomAdj = r.getSetAdjWithServices();
15755                hasActivities = r.activities.size() > 0;
15756            }
15757            if (thread != null) {
15758                if (!isCheckinRequest && dumpDetails) {
15759                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15760                }
15761                if (mi == null) {
15762                    mi = new Debug.MemoryInfo();
15763                }
15764                if (dumpDetails || (!brief && !oomOnly)) {
15765                    Debug.getMemoryInfo(pid, mi);
15766                    hasSwapPss = mi.hasSwappedOutPss;
15767                } else {
15768                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15769                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15770                }
15771                if (dumpDetails) {
15772                    if (localOnly) {
15773                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15774                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15775                        if (isCheckinRequest) {
15776                            pw.println();
15777                        }
15778                    } else {
15779                        try {
15780                            pw.flush();
15781                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15782                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15783                        } catch (RemoteException e) {
15784                            if (!isCheckinRequest) {
15785                                pw.println("Got RemoteException!");
15786                                pw.flush();
15787                            }
15788                        }
15789                    }
15790                }
15791
15792                final long myTotalPss = mi.getTotalPss();
15793                final long myTotalUss = mi.getTotalUss();
15794                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15795
15796                synchronized (this) {
15797                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15798                        // Record this for posterity if the process has been stable.
15799                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15800                    }
15801                }
15802
15803                if (!isCheckinRequest && mi != null) {
15804                    totalPss += myTotalPss;
15805                    totalSwapPss += myTotalSwapPss;
15806                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15807                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15808                            myTotalSwapPss, pid, hasActivities);
15809                    procMems.add(pssItem);
15810                    procMemsMap.put(pid, pssItem);
15811
15812                    nativePss += mi.nativePss;
15813                    nativeSwapPss += mi.nativeSwappedOutPss;
15814                    dalvikPss += mi.dalvikPss;
15815                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15816                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15817                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15818                        dalvikSubitemSwapPss[j] +=
15819                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15820                    }
15821                    otherPss += mi.otherPss;
15822                    otherSwapPss += mi.otherSwappedOutPss;
15823                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15824                        long mem = mi.getOtherPss(j);
15825                        miscPss[j] += mem;
15826                        otherPss -= mem;
15827                        mem = mi.getOtherSwappedOutPss(j);
15828                        miscSwapPss[j] += mem;
15829                        otherSwapPss -= mem;
15830                    }
15831
15832                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15833                        cachedPss += myTotalPss;
15834                        cachedSwapPss += myTotalSwapPss;
15835                    }
15836
15837                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15838                        if (oomIndex == (oomPss.length - 1)
15839                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15840                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15841                            oomPss[oomIndex] += myTotalPss;
15842                            oomSwapPss[oomIndex] += myTotalSwapPss;
15843                            if (oomProcs[oomIndex] == null) {
15844                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15845                            }
15846                            oomProcs[oomIndex].add(pssItem);
15847                            break;
15848                        }
15849                    }
15850                }
15851            }
15852        }
15853
15854        long nativeProcTotalPss = 0;
15855
15856        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15857            // If we are showing aggregations, also look for native processes to
15858            // include so that our aggregations are more accurate.
15859            updateCpuStatsNow();
15860            mi = null;
15861            synchronized (mProcessCpuTracker) {
15862                final int N = mProcessCpuTracker.countStats();
15863                for (int i=0; i<N; i++) {
15864                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15865                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15866                        if (mi == null) {
15867                            mi = new Debug.MemoryInfo();
15868                        }
15869                        if (!brief && !oomOnly) {
15870                            Debug.getMemoryInfo(st.pid, mi);
15871                        } else {
15872                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15873                            mi.nativePrivateDirty = (int)tmpLong[0];
15874                        }
15875
15876                        final long myTotalPss = mi.getTotalPss();
15877                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15878                        totalPss += myTotalPss;
15879                        nativeProcTotalPss += myTotalPss;
15880
15881                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15882                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15883                        procMems.add(pssItem);
15884
15885                        nativePss += mi.nativePss;
15886                        nativeSwapPss += mi.nativeSwappedOutPss;
15887                        dalvikPss += mi.dalvikPss;
15888                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15889                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15890                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15891                            dalvikSubitemSwapPss[j] +=
15892                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15893                        }
15894                        otherPss += mi.otherPss;
15895                        otherSwapPss += mi.otherSwappedOutPss;
15896                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15897                            long mem = mi.getOtherPss(j);
15898                            miscPss[j] += mem;
15899                            otherPss -= mem;
15900                            mem = mi.getOtherSwappedOutPss(j);
15901                            miscSwapPss[j] += mem;
15902                            otherSwapPss -= mem;
15903                        }
15904                        oomPss[0] += myTotalPss;
15905                        oomSwapPss[0] += myTotalSwapPss;
15906                        if (oomProcs[0] == null) {
15907                            oomProcs[0] = new ArrayList<MemItem>();
15908                        }
15909                        oomProcs[0].add(pssItem);
15910                    }
15911                }
15912            }
15913
15914            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15915
15916            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15917            final MemItem dalvikItem =
15918                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15919            if (dalvikSubitemPss.length > 0) {
15920                dalvikItem.subitems = new ArrayList<MemItem>();
15921                for (int j=0; j<dalvikSubitemPss.length; j++) {
15922                    final String name = Debug.MemoryInfo.getOtherLabel(
15923                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15924                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15925                                    dalvikSubitemSwapPss[j], j));
15926                }
15927            }
15928            catMems.add(dalvikItem);
15929            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15930            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15931                String label = Debug.MemoryInfo.getOtherLabel(j);
15932                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15933            }
15934
15935            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15936            for (int j=0; j<oomPss.length; j++) {
15937                if (oomPss[j] != 0) {
15938                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15939                            : DUMP_MEM_OOM_LABEL[j];
15940                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15941                            DUMP_MEM_OOM_ADJ[j]);
15942                    item.subitems = oomProcs[j];
15943                    oomMems.add(item);
15944                }
15945            }
15946
15947            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15948            if (!brief && !oomOnly && !isCompact) {
15949                pw.println();
15950                pw.println("Total PSS by process:");
15951                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15952                pw.println();
15953            }
15954            if (!isCompact) {
15955                pw.println("Total PSS by OOM adjustment:");
15956            }
15957            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15958            if (!brief && !oomOnly) {
15959                PrintWriter out = categoryPw != null ? categoryPw : pw;
15960                if (!isCompact) {
15961                    out.println();
15962                    out.println("Total PSS by category:");
15963                }
15964                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15965            }
15966            if (!isCompact) {
15967                pw.println();
15968            }
15969            MemInfoReader memInfo = new MemInfoReader();
15970            memInfo.readMemInfo();
15971            if (nativeProcTotalPss > 0) {
15972                synchronized (this) {
15973                    final long cachedKb = memInfo.getCachedSizeKb();
15974                    final long freeKb = memInfo.getFreeSizeKb();
15975                    final long zramKb = memInfo.getZramTotalSizeKb();
15976                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15977                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15978                            kernelKb*1024, nativeProcTotalPss*1024);
15979                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15980                            nativeProcTotalPss);
15981                }
15982            }
15983            if (!brief) {
15984                if (!isCompact) {
15985                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15986                    pw.print(" (status ");
15987                    switch (mLastMemoryLevel) {
15988                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15989                            pw.println("normal)");
15990                            break;
15991                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15992                            pw.println("moderate)");
15993                            break;
15994                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15995                            pw.println("low)");
15996                            break;
15997                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15998                            pw.println("critical)");
15999                            break;
16000                        default:
16001                            pw.print(mLastMemoryLevel);
16002                            pw.println(")");
16003                            break;
16004                    }
16005                    pw.print(" Free RAM: ");
16006                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16007                            + memInfo.getFreeSizeKb()));
16008                    pw.print(" (");
16009                    pw.print(stringifyKBSize(cachedPss));
16010                    pw.print(" cached pss + ");
16011                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16012                    pw.print(" cached kernel + ");
16013                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16014                    pw.println(" free)");
16015                } else {
16016                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16017                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16018                            + memInfo.getFreeSizeKb()); pw.print(",");
16019                    pw.println(totalPss - cachedPss);
16020                }
16021            }
16022            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16023                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16024                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16025            if (!isCompact) {
16026                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16027                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16028                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16029                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16030                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16031            } else {
16032                pw.print("lostram,"); pw.println(lostRAM);
16033            }
16034            if (!brief) {
16035                if (memInfo.getZramTotalSizeKb() != 0) {
16036                    if (!isCompact) {
16037                        pw.print("     ZRAM: ");
16038                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16039                                pw.print(" physical used for ");
16040                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16041                                        - memInfo.getSwapFreeSizeKb()));
16042                                pw.print(" in swap (");
16043                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16044                                pw.println(" total swap)");
16045                    } else {
16046                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16047                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16048                                pw.println(memInfo.getSwapFreeSizeKb());
16049                    }
16050                }
16051                final long[] ksm = getKsmInfo();
16052                if (!isCompact) {
16053                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16054                            || ksm[KSM_VOLATILE] != 0) {
16055                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16056                                pw.print(" saved from shared ");
16057                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16058                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16059                                pw.print(" unshared; ");
16060                                pw.print(stringifyKBSize(
16061                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16062                    }
16063                    pw.print("   Tuning: ");
16064                    pw.print(ActivityManager.staticGetMemoryClass());
16065                    pw.print(" (large ");
16066                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16067                    pw.print("), oom ");
16068                    pw.print(stringifySize(
16069                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16070                    pw.print(", restore limit ");
16071                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16072                    if (ActivityManager.isLowRamDeviceStatic()) {
16073                        pw.print(" (low-ram)");
16074                    }
16075                    if (ActivityManager.isHighEndGfx()) {
16076                        pw.print(" (high-end-gfx)");
16077                    }
16078                    pw.println();
16079                } else {
16080                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16081                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16082                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16083                    pw.print("tuning,");
16084                    pw.print(ActivityManager.staticGetMemoryClass());
16085                    pw.print(',');
16086                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16087                    pw.print(',');
16088                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16089                    if (ActivityManager.isLowRamDeviceStatic()) {
16090                        pw.print(",low-ram");
16091                    }
16092                    if (ActivityManager.isHighEndGfx()) {
16093                        pw.print(",high-end-gfx");
16094                    }
16095                    pw.println();
16096                }
16097            }
16098        }
16099    }
16100
16101    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16102            long memtrack, String name) {
16103        sb.append("  ");
16104        sb.append(ProcessList.makeOomAdjString(oomAdj));
16105        sb.append(' ');
16106        sb.append(ProcessList.makeProcStateString(procState));
16107        sb.append(' ');
16108        ProcessList.appendRamKb(sb, pss);
16109        sb.append(": ");
16110        sb.append(name);
16111        if (memtrack > 0) {
16112            sb.append(" (");
16113            sb.append(stringifyKBSize(memtrack));
16114            sb.append(" memtrack)");
16115        }
16116    }
16117
16118    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16119        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16120        sb.append(" (pid ");
16121        sb.append(mi.pid);
16122        sb.append(") ");
16123        sb.append(mi.adjType);
16124        sb.append('\n');
16125        if (mi.adjReason != null) {
16126            sb.append("                      ");
16127            sb.append(mi.adjReason);
16128            sb.append('\n');
16129        }
16130    }
16131
16132    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16133        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16134        for (int i=0, N=memInfos.size(); i<N; i++) {
16135            ProcessMemInfo mi = memInfos.get(i);
16136            infoMap.put(mi.pid, mi);
16137        }
16138        updateCpuStatsNow();
16139        long[] memtrackTmp = new long[1];
16140        synchronized (mProcessCpuTracker) {
16141            final int N = mProcessCpuTracker.countStats();
16142            for (int i=0; i<N; i++) {
16143                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16144                if (st.vsize > 0) {
16145                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16146                    if (pss > 0) {
16147                        if (infoMap.indexOfKey(st.pid) < 0) {
16148                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16149                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16150                            mi.pss = pss;
16151                            mi.memtrack = memtrackTmp[0];
16152                            memInfos.add(mi);
16153                        }
16154                    }
16155                }
16156            }
16157        }
16158
16159        long totalPss = 0;
16160        long totalMemtrack = 0;
16161        for (int i=0, N=memInfos.size(); i<N; i++) {
16162            ProcessMemInfo mi = memInfos.get(i);
16163            if (mi.pss == 0) {
16164                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16165                mi.memtrack = memtrackTmp[0];
16166            }
16167            totalPss += mi.pss;
16168            totalMemtrack += mi.memtrack;
16169        }
16170        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16171            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16172                if (lhs.oomAdj != rhs.oomAdj) {
16173                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16174                }
16175                if (lhs.pss != rhs.pss) {
16176                    return lhs.pss < rhs.pss ? 1 : -1;
16177                }
16178                return 0;
16179            }
16180        });
16181
16182        StringBuilder tag = new StringBuilder(128);
16183        StringBuilder stack = new StringBuilder(128);
16184        tag.append("Low on memory -- ");
16185        appendMemBucket(tag, totalPss, "total", false);
16186        appendMemBucket(stack, totalPss, "total", true);
16187
16188        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16189        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16190        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16191
16192        boolean firstLine = true;
16193        int lastOomAdj = Integer.MIN_VALUE;
16194        long extraNativeRam = 0;
16195        long extraNativeMemtrack = 0;
16196        long cachedPss = 0;
16197        for (int i=0, N=memInfos.size(); i<N; i++) {
16198            ProcessMemInfo mi = memInfos.get(i);
16199
16200            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16201                cachedPss += mi.pss;
16202            }
16203
16204            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16205                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16206                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16207                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16208                if (lastOomAdj != mi.oomAdj) {
16209                    lastOomAdj = mi.oomAdj;
16210                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16211                        tag.append(" / ");
16212                    }
16213                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16214                        if (firstLine) {
16215                            stack.append(":");
16216                            firstLine = false;
16217                        }
16218                        stack.append("\n\t at ");
16219                    } else {
16220                        stack.append("$");
16221                    }
16222                } else {
16223                    tag.append(" ");
16224                    stack.append("$");
16225                }
16226                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16227                    appendMemBucket(tag, mi.pss, mi.name, false);
16228                }
16229                appendMemBucket(stack, mi.pss, mi.name, true);
16230                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16231                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16232                    stack.append("(");
16233                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16234                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16235                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16236                            stack.append(":");
16237                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16238                        }
16239                    }
16240                    stack.append(")");
16241                }
16242            }
16243
16244            appendMemInfo(fullNativeBuilder, mi);
16245            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16246                // The short form only has native processes that are >= 512K.
16247                if (mi.pss >= 512) {
16248                    appendMemInfo(shortNativeBuilder, mi);
16249                } else {
16250                    extraNativeRam += mi.pss;
16251                    extraNativeMemtrack += mi.memtrack;
16252                }
16253            } else {
16254                // Short form has all other details, but if we have collected RAM
16255                // from smaller native processes let's dump a summary of that.
16256                if (extraNativeRam > 0) {
16257                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16258                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16259                    shortNativeBuilder.append('\n');
16260                    extraNativeRam = 0;
16261                }
16262                appendMemInfo(fullJavaBuilder, mi);
16263            }
16264        }
16265
16266        fullJavaBuilder.append("           ");
16267        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16268        fullJavaBuilder.append(": TOTAL");
16269        if (totalMemtrack > 0) {
16270            fullJavaBuilder.append(" (");
16271            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16272            fullJavaBuilder.append(" memtrack)");
16273        } else {
16274        }
16275        fullJavaBuilder.append("\n");
16276
16277        MemInfoReader memInfo = new MemInfoReader();
16278        memInfo.readMemInfo();
16279        final long[] infos = memInfo.getRawInfo();
16280
16281        StringBuilder memInfoBuilder = new StringBuilder(1024);
16282        Debug.getMemInfo(infos);
16283        memInfoBuilder.append("  MemInfo: ");
16284        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16285        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16286        memInfoBuilder.append(stringifyKBSize(
16287                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16288        memInfoBuilder.append(stringifyKBSize(
16289                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16290        memInfoBuilder.append(stringifyKBSize(
16291                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16292        memInfoBuilder.append("           ");
16293        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16294        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16295        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16296        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16297        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16298            memInfoBuilder.append("  ZRAM: ");
16299            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16300            memInfoBuilder.append(" RAM, ");
16301            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16302            memInfoBuilder.append(" swap total, ");
16303            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16304            memInfoBuilder.append(" swap free\n");
16305        }
16306        final long[] ksm = getKsmInfo();
16307        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16308                || ksm[KSM_VOLATILE] != 0) {
16309            memInfoBuilder.append("  KSM: ");
16310            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16311            memInfoBuilder.append(" saved from shared ");
16312            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16313            memInfoBuilder.append("\n       ");
16314            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16315            memInfoBuilder.append(" unshared; ");
16316            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16317            memInfoBuilder.append(" volatile\n");
16318        }
16319        memInfoBuilder.append("  Free RAM: ");
16320        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16321                + memInfo.getFreeSizeKb()));
16322        memInfoBuilder.append("\n");
16323        memInfoBuilder.append("  Used RAM: ");
16324        memInfoBuilder.append(stringifyKBSize(
16325                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16326        memInfoBuilder.append("\n");
16327        memInfoBuilder.append("  Lost RAM: ");
16328        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16329                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16330                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16331        memInfoBuilder.append("\n");
16332        Slog.i(TAG, "Low on memory:");
16333        Slog.i(TAG, shortNativeBuilder.toString());
16334        Slog.i(TAG, fullJavaBuilder.toString());
16335        Slog.i(TAG, memInfoBuilder.toString());
16336
16337        StringBuilder dropBuilder = new StringBuilder(1024);
16338        /*
16339        StringWriter oomSw = new StringWriter();
16340        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16341        StringWriter catSw = new StringWriter();
16342        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16343        String[] emptyArgs = new String[] { };
16344        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16345        oomPw.flush();
16346        String oomString = oomSw.toString();
16347        */
16348        dropBuilder.append("Low on memory:");
16349        dropBuilder.append(stack);
16350        dropBuilder.append('\n');
16351        dropBuilder.append(fullNativeBuilder);
16352        dropBuilder.append(fullJavaBuilder);
16353        dropBuilder.append('\n');
16354        dropBuilder.append(memInfoBuilder);
16355        dropBuilder.append('\n');
16356        /*
16357        dropBuilder.append(oomString);
16358        dropBuilder.append('\n');
16359        */
16360        StringWriter catSw = new StringWriter();
16361        synchronized (ActivityManagerService.this) {
16362            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16363            String[] emptyArgs = new String[] { };
16364            catPw.println();
16365            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16366            catPw.println();
16367            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16368                    false, null).dumpLocked();
16369            catPw.println();
16370            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16371            catPw.flush();
16372        }
16373        dropBuilder.append(catSw.toString());
16374        addErrorToDropBox("lowmem", null, "system_server", null,
16375                null, tag.toString(), dropBuilder.toString(), null, null);
16376        //Slog.i(TAG, "Sent to dropbox:");
16377        //Slog.i(TAG, dropBuilder.toString());
16378        synchronized (ActivityManagerService.this) {
16379            long now = SystemClock.uptimeMillis();
16380            if (mLastMemUsageReportTime < now) {
16381                mLastMemUsageReportTime = now;
16382            }
16383        }
16384    }
16385
16386    /**
16387     * Searches array of arguments for the specified string
16388     * @param args array of argument strings
16389     * @param value value to search for
16390     * @return true if the value is contained in the array
16391     */
16392    private static boolean scanArgs(String[] args, String value) {
16393        if (args != null) {
16394            for (String arg : args) {
16395                if (value.equals(arg)) {
16396                    return true;
16397                }
16398            }
16399        }
16400        return false;
16401    }
16402
16403    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16404            ContentProviderRecord cpr, boolean always) {
16405        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16406
16407        if (!inLaunching || always) {
16408            synchronized (cpr) {
16409                cpr.launchingApp = null;
16410                cpr.notifyAll();
16411            }
16412            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16413            String names[] = cpr.info.authority.split(";");
16414            for (int j = 0; j < names.length; j++) {
16415                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16416            }
16417        }
16418
16419        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16420            ContentProviderConnection conn = cpr.connections.get(i);
16421            if (conn.waiting) {
16422                // If this connection is waiting for the provider, then we don't
16423                // need to mess with its process unless we are always removing
16424                // or for some reason the provider is not currently launching.
16425                if (inLaunching && !always) {
16426                    continue;
16427                }
16428            }
16429            ProcessRecord capp = conn.client;
16430            conn.dead = true;
16431            if (conn.stableCount > 0) {
16432                if (!capp.persistent && capp.thread != null
16433                        && capp.pid != 0
16434                        && capp.pid != MY_PID) {
16435                    capp.kill("depends on provider "
16436                            + cpr.name.flattenToShortString()
16437                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16438                }
16439            } else if (capp.thread != null && conn.provider.provider != null) {
16440                try {
16441                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16442                } catch (RemoteException e) {
16443                }
16444                // In the protocol here, we don't expect the client to correctly
16445                // clean up this connection, we'll just remove it.
16446                cpr.connections.remove(i);
16447                if (conn.client.conProviders.remove(conn)) {
16448                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16449                }
16450            }
16451        }
16452
16453        if (inLaunching && always) {
16454            mLaunchingProviders.remove(cpr);
16455        }
16456        return inLaunching;
16457    }
16458
16459    /**
16460     * Main code for cleaning up a process when it has gone away.  This is
16461     * called both as a result of the process dying, or directly when stopping
16462     * a process when running in single process mode.
16463     *
16464     * @return Returns true if the given process has been restarted, so the
16465     * app that was passed in must remain on the process lists.
16466     */
16467    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16468            boolean restarting, boolean allowRestart, int index) {
16469        if (index >= 0) {
16470            removeLruProcessLocked(app);
16471            ProcessList.remove(app.pid);
16472        }
16473
16474        mProcessesToGc.remove(app);
16475        mPendingPssProcesses.remove(app);
16476
16477        // Dismiss any open dialogs.
16478        if (app.crashDialog != null && !app.forceCrashReport) {
16479            app.crashDialog.dismiss();
16480            app.crashDialog = null;
16481        }
16482        if (app.anrDialog != null) {
16483            app.anrDialog.dismiss();
16484            app.anrDialog = null;
16485        }
16486        if (app.waitDialog != null) {
16487            app.waitDialog.dismiss();
16488            app.waitDialog = null;
16489        }
16490
16491        app.crashing = false;
16492        app.notResponding = false;
16493
16494        app.resetPackageList(mProcessStats);
16495        app.unlinkDeathRecipient();
16496        app.makeInactive(mProcessStats);
16497        app.waitingToKill = null;
16498        app.forcingToForeground = null;
16499        updateProcessForegroundLocked(app, false, false);
16500        app.foregroundActivities = false;
16501        app.hasShownUi = false;
16502        app.treatLikeActivity = false;
16503        app.hasAboveClient = false;
16504        app.hasClientActivities = false;
16505
16506        mServices.killServicesLocked(app, allowRestart);
16507
16508        boolean restart = false;
16509
16510        // Remove published content providers.
16511        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16512            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16513            final boolean always = app.bad || !allowRestart;
16514            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16515            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16516                // We left the provider in the launching list, need to
16517                // restart it.
16518                restart = true;
16519            }
16520
16521            cpr.provider = null;
16522            cpr.proc = null;
16523        }
16524        app.pubProviders.clear();
16525
16526        // Take care of any launching providers waiting for this process.
16527        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16528            restart = true;
16529        }
16530
16531        // Unregister from connected content providers.
16532        if (!app.conProviders.isEmpty()) {
16533            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16534                ContentProviderConnection conn = app.conProviders.get(i);
16535                conn.provider.connections.remove(conn);
16536                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16537                        conn.provider.name);
16538            }
16539            app.conProviders.clear();
16540        }
16541
16542        // At this point there may be remaining entries in mLaunchingProviders
16543        // where we were the only one waiting, so they are no longer of use.
16544        // Look for these and clean up if found.
16545        // XXX Commented out for now.  Trying to figure out a way to reproduce
16546        // the actual situation to identify what is actually going on.
16547        if (false) {
16548            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16549                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16550                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16551                    synchronized (cpr) {
16552                        cpr.launchingApp = null;
16553                        cpr.notifyAll();
16554                    }
16555                }
16556            }
16557        }
16558
16559        skipCurrentReceiverLocked(app);
16560
16561        // Unregister any receivers.
16562        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16563            removeReceiverLocked(app.receivers.valueAt(i));
16564        }
16565        app.receivers.clear();
16566
16567        // If the app is undergoing backup, tell the backup manager about it
16568        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16569            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16570                    + mBackupTarget.appInfo + " died during backup");
16571            try {
16572                IBackupManager bm = IBackupManager.Stub.asInterface(
16573                        ServiceManager.getService(Context.BACKUP_SERVICE));
16574                bm.agentDisconnected(app.info.packageName);
16575            } catch (RemoteException e) {
16576                // can't happen; backup manager is local
16577            }
16578        }
16579
16580        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16581            ProcessChangeItem item = mPendingProcessChanges.get(i);
16582            if (item.pid == app.pid) {
16583                mPendingProcessChanges.remove(i);
16584                mAvailProcessChanges.add(item);
16585            }
16586        }
16587        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16588                null).sendToTarget();
16589
16590        // If the caller is restarting this app, then leave it in its
16591        // current lists and let the caller take care of it.
16592        if (restarting) {
16593            return false;
16594        }
16595
16596        if (!app.persistent || app.isolated) {
16597            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16598                    "Removing non-persistent process during cleanup: " + app);
16599            removeProcessNameLocked(app.processName, app.uid);
16600            if (mHeavyWeightProcess == app) {
16601                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16602                        mHeavyWeightProcess.userId, 0));
16603                mHeavyWeightProcess = null;
16604            }
16605        } else if (!app.removed) {
16606            // This app is persistent, so we need to keep its record around.
16607            // If it is not already on the pending app list, add it there
16608            // and start a new process for it.
16609            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16610                mPersistentStartingProcesses.add(app);
16611                restart = true;
16612            }
16613        }
16614        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16615                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16616        mProcessesOnHold.remove(app);
16617
16618        if (app == mHomeProcess) {
16619            mHomeProcess = null;
16620        }
16621        if (app == mPreviousProcess) {
16622            mPreviousProcess = null;
16623        }
16624
16625        if (restart && !app.isolated) {
16626            // We have components that still need to be running in the
16627            // process, so re-launch it.
16628            if (index < 0) {
16629                ProcessList.remove(app.pid);
16630            }
16631            addProcessNameLocked(app);
16632            startProcessLocked(app, "restart", app.processName);
16633            return true;
16634        } else if (app.pid > 0 && app.pid != MY_PID) {
16635            // Goodbye!
16636            boolean removed;
16637            synchronized (mPidsSelfLocked) {
16638                mPidsSelfLocked.remove(app.pid);
16639                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16640            }
16641            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16642            if (app.isolated) {
16643                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16644            }
16645            app.setPid(0);
16646        }
16647        return false;
16648    }
16649
16650    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16651        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16652            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16653            if (cpr.launchingApp == app) {
16654                return true;
16655            }
16656        }
16657        return false;
16658    }
16659
16660    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16661        // Look through the content providers we are waiting to have launched,
16662        // and if any run in this process then either schedule a restart of
16663        // the process or kill the client waiting for it if this process has
16664        // gone bad.
16665        boolean restart = false;
16666        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16667            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16668            if (cpr.launchingApp == app) {
16669                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16670                    restart = true;
16671                } else {
16672                    removeDyingProviderLocked(app, cpr, true);
16673                }
16674            }
16675        }
16676        return restart;
16677    }
16678
16679    // =========================================================
16680    // SERVICES
16681    // =========================================================
16682
16683    @Override
16684    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16685            int flags) {
16686        enforceNotIsolatedCaller("getServices");
16687        synchronized (this) {
16688            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16689        }
16690    }
16691
16692    @Override
16693    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16694        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16695        synchronized (this) {
16696            return mServices.getRunningServiceControlPanelLocked(name);
16697        }
16698    }
16699
16700    @Override
16701    public ComponentName startService(IApplicationThread caller, Intent service,
16702            String resolvedType, String callingPackage, int userId)
16703            throws TransactionTooLargeException {
16704        enforceNotIsolatedCaller("startService");
16705        // Refuse possible leaked file descriptors
16706        if (service != null && service.hasFileDescriptors() == true) {
16707            throw new IllegalArgumentException("File descriptors passed in Intent");
16708        }
16709
16710        if (callingPackage == null) {
16711            throw new IllegalArgumentException("callingPackage cannot be null");
16712        }
16713
16714        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16715                "startService: " + service + " type=" + resolvedType);
16716        synchronized(this) {
16717            final int callingPid = Binder.getCallingPid();
16718            final int callingUid = Binder.getCallingUid();
16719            final long origId = Binder.clearCallingIdentity();
16720            ComponentName res = mServices.startServiceLocked(caller, service,
16721                    resolvedType, callingPid, callingUid, callingPackage, userId);
16722            Binder.restoreCallingIdentity(origId);
16723            return res;
16724        }
16725    }
16726
16727    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16728            String callingPackage, int userId)
16729            throws TransactionTooLargeException {
16730        synchronized(this) {
16731            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16732                    "startServiceInPackage: " + service + " type=" + resolvedType);
16733            final long origId = Binder.clearCallingIdentity();
16734            ComponentName res = mServices.startServiceLocked(null, service,
16735                    resolvedType, -1, uid, callingPackage, userId);
16736            Binder.restoreCallingIdentity(origId);
16737            return res;
16738        }
16739    }
16740
16741    @Override
16742    public int stopService(IApplicationThread caller, Intent service,
16743            String resolvedType, int userId) {
16744        enforceNotIsolatedCaller("stopService");
16745        // Refuse possible leaked file descriptors
16746        if (service != null && service.hasFileDescriptors() == true) {
16747            throw new IllegalArgumentException("File descriptors passed in Intent");
16748        }
16749
16750        synchronized(this) {
16751            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16752        }
16753    }
16754
16755    @Override
16756    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16757        enforceNotIsolatedCaller("peekService");
16758        // Refuse possible leaked file descriptors
16759        if (service != null && service.hasFileDescriptors() == true) {
16760            throw new IllegalArgumentException("File descriptors passed in Intent");
16761        }
16762
16763        if (callingPackage == null) {
16764            throw new IllegalArgumentException("callingPackage cannot be null");
16765        }
16766
16767        synchronized(this) {
16768            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16769        }
16770    }
16771
16772    @Override
16773    public boolean stopServiceToken(ComponentName className, IBinder token,
16774            int startId) {
16775        synchronized(this) {
16776            return mServices.stopServiceTokenLocked(className, token, startId);
16777        }
16778    }
16779
16780    @Override
16781    public void setServiceForeground(ComponentName className, IBinder token,
16782            int id, Notification notification, int flags) {
16783        synchronized(this) {
16784            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16785        }
16786    }
16787
16788    @Override
16789    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16790            boolean requireFull, String name, String callerPackage) {
16791        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16792                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16793    }
16794
16795    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16796            String className, int flags) {
16797        boolean result = false;
16798        // For apps that don't have pre-defined UIDs, check for permission
16799        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16800            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16801                if (ActivityManager.checkUidPermission(
16802                        INTERACT_ACROSS_USERS,
16803                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16804                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16805                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16806                            + " requests FLAG_SINGLE_USER, but app does not hold "
16807                            + INTERACT_ACROSS_USERS;
16808                    Slog.w(TAG, msg);
16809                    throw new SecurityException(msg);
16810                }
16811                // Permission passed
16812                result = true;
16813            }
16814        } else if ("system".equals(componentProcessName)) {
16815            result = true;
16816        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16817            // Phone app and persistent apps are allowed to export singleuser providers.
16818            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16819                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16820        }
16821        if (DEBUG_MU) Slog.v(TAG_MU,
16822                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16823                + Integer.toHexString(flags) + ") = " + result);
16824        return result;
16825    }
16826
16827    /**
16828     * Checks to see if the caller is in the same app as the singleton
16829     * component, or the component is in a special app. It allows special apps
16830     * to export singleton components but prevents exporting singleton
16831     * components for regular apps.
16832     */
16833    boolean isValidSingletonCall(int callingUid, int componentUid) {
16834        int componentAppId = UserHandle.getAppId(componentUid);
16835        return UserHandle.isSameApp(callingUid, componentUid)
16836                || componentAppId == Process.SYSTEM_UID
16837                || componentAppId == Process.PHONE_UID
16838                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16839                        == PackageManager.PERMISSION_GRANTED;
16840    }
16841
16842    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16843            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16844            int userId) throws TransactionTooLargeException {
16845        enforceNotIsolatedCaller("bindService");
16846
16847        // Refuse possible leaked file descriptors
16848        if (service != null && service.hasFileDescriptors() == true) {
16849            throw new IllegalArgumentException("File descriptors passed in Intent");
16850        }
16851
16852        if (callingPackage == null) {
16853            throw new IllegalArgumentException("callingPackage cannot be null");
16854        }
16855
16856        synchronized(this) {
16857            return mServices.bindServiceLocked(caller, token, service,
16858                    resolvedType, connection, flags, callingPackage, userId);
16859        }
16860    }
16861
16862    public boolean unbindService(IServiceConnection connection) {
16863        synchronized (this) {
16864            return mServices.unbindServiceLocked(connection);
16865        }
16866    }
16867
16868    public void publishService(IBinder token, Intent intent, IBinder service) {
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            if (!(token instanceof ServiceRecord)) {
16876                throw new IllegalArgumentException("Invalid service token");
16877            }
16878            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16879        }
16880    }
16881
16882    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16883        // Refuse possible leaked file descriptors
16884        if (intent != null && intent.hasFileDescriptors() == true) {
16885            throw new IllegalArgumentException("File descriptors passed in Intent");
16886        }
16887
16888        synchronized(this) {
16889            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16890        }
16891    }
16892
16893    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16894        synchronized(this) {
16895            if (!(token instanceof ServiceRecord)) {
16896                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16897                throw new IllegalArgumentException("Invalid service token");
16898            }
16899            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16900        }
16901    }
16902
16903    // =========================================================
16904    // BACKUP AND RESTORE
16905    // =========================================================
16906
16907    // Cause the target app to be launched if necessary and its backup agent
16908    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16909    // activity manager to announce its creation.
16910    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16911        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16912                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16913        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16914
16915        synchronized(this) {
16916            // !!! TODO: currently no check here that we're already bound
16917            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16918            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16919            synchronized (stats) {
16920                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16921            }
16922
16923            // Backup agent is now in use, its package can't be stopped.
16924            try {
16925                AppGlobals.getPackageManager().setPackageStoppedState(
16926                        app.packageName, false, UserHandle.getUserId(app.uid));
16927            } catch (RemoteException e) {
16928            } catch (IllegalArgumentException e) {
16929                Slog.w(TAG, "Failed trying to unstop package "
16930                        + app.packageName + ": " + e);
16931            }
16932
16933            BackupRecord r = new BackupRecord(ss, app, backupMode);
16934            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16935                    ? new ComponentName(app.packageName, app.backupAgentName)
16936                    : new ComponentName("android", "FullBackupAgent");
16937            // startProcessLocked() returns existing proc's record if it's already running
16938            ProcessRecord proc = startProcessLocked(app.processName, app,
16939                    false, 0, "backup", hostingName, false, false, false);
16940            if (proc == null) {
16941                Slog.e(TAG, "Unable to start backup agent process " + r);
16942                return false;
16943            }
16944
16945            // If the app is a regular app (uid >= 10000) and not the system server or phone
16946            // process, etc, then mark it as being in full backup so that certain calls to the
16947            // process can be blocked. This is not reset to false anywhere because we kill the
16948            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16949            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16950                proc.inFullBackup = true;
16951            }
16952            r.app = proc;
16953            mBackupTarget = r;
16954            mBackupAppName = app.packageName;
16955
16956            // Try not to kill the process during backup
16957            updateOomAdjLocked(proc);
16958
16959            // If the process is already attached, schedule the creation of the backup agent now.
16960            // If it is not yet live, this will be done when it attaches to the framework.
16961            if (proc.thread != null) {
16962                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16963                try {
16964                    proc.thread.scheduleCreateBackupAgent(app,
16965                            compatibilityInfoForPackageLocked(app), backupMode);
16966                } catch (RemoteException e) {
16967                    // Will time out on the backup manager side
16968                }
16969            } else {
16970                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16971            }
16972            // Invariants: at this point, the target app process exists and the application
16973            // is either already running or in the process of coming up.  mBackupTarget and
16974            // mBackupAppName describe the app, so that when it binds back to the AM we
16975            // know that it's scheduled for a backup-agent operation.
16976        }
16977
16978        return true;
16979    }
16980
16981    @Override
16982    public void clearPendingBackup() {
16983        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16984        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16985
16986        synchronized (this) {
16987            mBackupTarget = null;
16988            mBackupAppName = null;
16989        }
16990    }
16991
16992    // A backup agent has just come up
16993    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16994        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16995                + " = " + agent);
16996
16997        synchronized(this) {
16998            if (!agentPackageName.equals(mBackupAppName)) {
16999                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17000                return;
17001            }
17002        }
17003
17004        long oldIdent = Binder.clearCallingIdentity();
17005        try {
17006            IBackupManager bm = IBackupManager.Stub.asInterface(
17007                    ServiceManager.getService(Context.BACKUP_SERVICE));
17008            bm.agentConnected(agentPackageName, agent);
17009        } catch (RemoteException e) {
17010            // can't happen; the backup manager service is local
17011        } catch (Exception e) {
17012            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17013            e.printStackTrace();
17014        } finally {
17015            Binder.restoreCallingIdentity(oldIdent);
17016        }
17017    }
17018
17019    // done with this agent
17020    public void unbindBackupAgent(ApplicationInfo appInfo) {
17021        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17022        if (appInfo == null) {
17023            Slog.w(TAG, "unbind backup agent for null app");
17024            return;
17025        }
17026
17027        synchronized(this) {
17028            try {
17029                if (mBackupAppName == null) {
17030                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17031                    return;
17032                }
17033
17034                if (!mBackupAppName.equals(appInfo.packageName)) {
17035                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17036                    return;
17037                }
17038
17039                // Not backing this app up any more; reset its OOM adjustment
17040                final ProcessRecord proc = mBackupTarget.app;
17041                updateOomAdjLocked(proc);
17042
17043                // If the app crashed during backup, 'thread' will be null here
17044                if (proc.thread != null) {
17045                    try {
17046                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17047                                compatibilityInfoForPackageLocked(appInfo));
17048                    } catch (Exception e) {
17049                        Slog.e(TAG, "Exception when unbinding backup agent:");
17050                        e.printStackTrace();
17051                    }
17052                }
17053            } finally {
17054                mBackupTarget = null;
17055                mBackupAppName = null;
17056            }
17057        }
17058    }
17059    // =========================================================
17060    // BROADCASTS
17061    // =========================================================
17062
17063    boolean isPendingBroadcastProcessLocked(int pid) {
17064        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17065                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17066    }
17067
17068    void skipPendingBroadcastLocked(int pid) {
17069            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17070            for (BroadcastQueue queue : mBroadcastQueues) {
17071                queue.skipPendingBroadcastLocked(pid);
17072            }
17073    }
17074
17075    // The app just attached; send any pending broadcasts that it should receive
17076    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17077        boolean didSomething = false;
17078        for (BroadcastQueue queue : mBroadcastQueues) {
17079            didSomething |= queue.sendPendingBroadcastsLocked(app);
17080        }
17081        return didSomething;
17082    }
17083
17084    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17085            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17086        enforceNotIsolatedCaller("registerReceiver");
17087        ArrayList<Intent> stickyIntents = null;
17088        ProcessRecord callerApp = null;
17089        int callingUid;
17090        int callingPid;
17091        synchronized(this) {
17092            if (caller != null) {
17093                callerApp = getRecordForAppLocked(caller);
17094                if (callerApp == null) {
17095                    throw new SecurityException(
17096                            "Unable to find app for caller " + caller
17097                            + " (pid=" + Binder.getCallingPid()
17098                            + ") when registering receiver " + receiver);
17099                }
17100                if (callerApp.info.uid != Process.SYSTEM_UID &&
17101                        !callerApp.pkgList.containsKey(callerPackage) &&
17102                        !"android".equals(callerPackage)) {
17103                    throw new SecurityException("Given caller package " + callerPackage
17104                            + " is not running in process " + callerApp);
17105                }
17106                callingUid = callerApp.info.uid;
17107                callingPid = callerApp.pid;
17108            } else {
17109                callerPackage = null;
17110                callingUid = Binder.getCallingUid();
17111                callingPid = Binder.getCallingPid();
17112            }
17113
17114            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17115                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17116
17117            Iterator<String> actions = filter.actionsIterator();
17118            if (actions == null) {
17119                ArrayList<String> noAction = new ArrayList<String>(1);
17120                noAction.add(null);
17121                actions = noAction.iterator();
17122            }
17123
17124            // Collect stickies of users
17125            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17126            while (actions.hasNext()) {
17127                String action = actions.next();
17128                for (int id : userIds) {
17129                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17130                    if (stickies != null) {
17131                        ArrayList<Intent> intents = stickies.get(action);
17132                        if (intents != null) {
17133                            if (stickyIntents == null) {
17134                                stickyIntents = new ArrayList<Intent>();
17135                            }
17136                            stickyIntents.addAll(intents);
17137                        }
17138                    }
17139                }
17140            }
17141        }
17142
17143        ArrayList<Intent> allSticky = null;
17144        if (stickyIntents != null) {
17145            final ContentResolver resolver = mContext.getContentResolver();
17146            // Look for any matching sticky broadcasts...
17147            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17148                Intent intent = stickyIntents.get(i);
17149                // If intent has scheme "content", it will need to acccess
17150                // provider that needs to lock mProviderMap in ActivityThread
17151                // and also it may need to wait application response, so we
17152                // cannot lock ActivityManagerService here.
17153                if (filter.match(resolver, intent, true, TAG) >= 0) {
17154                    if (allSticky == null) {
17155                        allSticky = new ArrayList<Intent>();
17156                    }
17157                    allSticky.add(intent);
17158                }
17159            }
17160        }
17161
17162        // The first sticky in the list is returned directly back to the client.
17163        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17164        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17165        if (receiver == null) {
17166            return sticky;
17167        }
17168
17169        synchronized (this) {
17170            if (callerApp != null && (callerApp.thread == null
17171                    || callerApp.thread.asBinder() != caller.asBinder())) {
17172                // Original caller already died
17173                return null;
17174            }
17175            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17176            if (rl == null) {
17177                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17178                        userId, receiver);
17179                if (rl.app != null) {
17180                    rl.app.receivers.add(rl);
17181                } else {
17182                    try {
17183                        receiver.asBinder().linkToDeath(rl, 0);
17184                    } catch (RemoteException e) {
17185                        return sticky;
17186                    }
17187                    rl.linkedToDeath = true;
17188                }
17189                mRegisteredReceivers.put(receiver.asBinder(), rl);
17190            } else if (rl.uid != callingUid) {
17191                throw new IllegalArgumentException(
17192                        "Receiver requested to register for uid " + callingUid
17193                        + " was previously registered for uid " + rl.uid);
17194            } else if (rl.pid != callingPid) {
17195                throw new IllegalArgumentException(
17196                        "Receiver requested to register for pid " + callingPid
17197                        + " was previously registered for pid " + rl.pid);
17198            } else if (rl.userId != userId) {
17199                throw new IllegalArgumentException(
17200                        "Receiver requested to register for user " + userId
17201                        + " was previously registered for user " + rl.userId);
17202            }
17203            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17204                    permission, callingUid, userId);
17205            rl.add(bf);
17206            if (!bf.debugCheck()) {
17207                Slog.w(TAG, "==> For Dynamic broadcast");
17208            }
17209            mReceiverResolver.addFilter(bf);
17210
17211            // Enqueue broadcasts for all existing stickies that match
17212            // this filter.
17213            if (allSticky != null) {
17214                ArrayList receivers = new ArrayList();
17215                receivers.add(bf);
17216
17217                final int stickyCount = allSticky.size();
17218                for (int i = 0; i < stickyCount; i++) {
17219                    Intent intent = allSticky.get(i);
17220                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17221                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17222                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17223                            null, 0, null, null, false, true, true, -1);
17224                    queue.enqueueParallelBroadcastLocked(r);
17225                    queue.scheduleBroadcastsLocked();
17226                }
17227            }
17228
17229            return sticky;
17230        }
17231    }
17232
17233    public void unregisterReceiver(IIntentReceiver receiver) {
17234        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17235
17236        final long origId = Binder.clearCallingIdentity();
17237        try {
17238            boolean doTrim = false;
17239
17240            synchronized(this) {
17241                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17242                if (rl != null) {
17243                    final BroadcastRecord r = rl.curBroadcast;
17244                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17245                        final boolean doNext = r.queue.finishReceiverLocked(
17246                                r, r.resultCode, r.resultData, r.resultExtras,
17247                                r.resultAbort, false);
17248                        if (doNext) {
17249                            doTrim = true;
17250                            r.queue.processNextBroadcast(false);
17251                        }
17252                    }
17253
17254                    if (rl.app != null) {
17255                        rl.app.receivers.remove(rl);
17256                    }
17257                    removeReceiverLocked(rl);
17258                    if (rl.linkedToDeath) {
17259                        rl.linkedToDeath = false;
17260                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17261                    }
17262                }
17263            }
17264
17265            // If we actually concluded any broadcasts, we might now be able
17266            // to trim the recipients' apps from our working set
17267            if (doTrim) {
17268                trimApplications();
17269                return;
17270            }
17271
17272        } finally {
17273            Binder.restoreCallingIdentity(origId);
17274        }
17275    }
17276
17277    void removeReceiverLocked(ReceiverList rl) {
17278        mRegisteredReceivers.remove(rl.receiver.asBinder());
17279        for (int i = rl.size() - 1; i >= 0; i--) {
17280            mReceiverResolver.removeFilter(rl.get(i));
17281        }
17282    }
17283
17284    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17285        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17286            ProcessRecord r = mLruProcesses.get(i);
17287            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17288                try {
17289                    r.thread.dispatchPackageBroadcast(cmd, packages);
17290                } catch (RemoteException ex) {
17291                }
17292            }
17293        }
17294    }
17295
17296    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17297            int callingUid, int[] users) {
17298        // TODO: come back and remove this assumption to triage all broadcasts
17299        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17300
17301        List<ResolveInfo> receivers = null;
17302        try {
17303            HashSet<ComponentName> singleUserReceivers = null;
17304            boolean scannedFirstReceivers = false;
17305            for (int user : users) {
17306                // Skip users that have Shell restrictions, with exception of always permitted
17307                // Shell broadcasts
17308                if (callingUid == Process.SHELL_UID
17309                        && mUserController.hasUserRestriction(
17310                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17311                        && !isPermittedShellBroadcast(intent)) {
17312                    continue;
17313                }
17314                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17315                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17316                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17317                    // If this is not the system user, we need to check for
17318                    // any receivers that should be filtered out.
17319                    for (int i=0; i<newReceivers.size(); i++) {
17320                        ResolveInfo ri = newReceivers.get(i);
17321                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17322                            newReceivers.remove(i);
17323                            i--;
17324                        }
17325                    }
17326                }
17327                if (newReceivers != null && newReceivers.size() == 0) {
17328                    newReceivers = null;
17329                }
17330                if (receivers == null) {
17331                    receivers = newReceivers;
17332                } else if (newReceivers != null) {
17333                    // We need to concatenate the additional receivers
17334                    // found with what we have do far.  This would be easy,
17335                    // but we also need to de-dup any receivers that are
17336                    // singleUser.
17337                    if (!scannedFirstReceivers) {
17338                        // Collect any single user receivers we had already retrieved.
17339                        scannedFirstReceivers = true;
17340                        for (int i=0; i<receivers.size(); i++) {
17341                            ResolveInfo ri = receivers.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                                singleUserReceivers.add(cn);
17349                            }
17350                        }
17351                    }
17352                    // Add the new results to the existing results, tracking
17353                    // and de-dupping single user receivers.
17354                    for (int i=0; i<newReceivers.size(); i++) {
17355                        ResolveInfo ri = newReceivers.get(i);
17356                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17357                            ComponentName cn = new ComponentName(
17358                                    ri.activityInfo.packageName, ri.activityInfo.name);
17359                            if (singleUserReceivers == null) {
17360                                singleUserReceivers = new HashSet<ComponentName>();
17361                            }
17362                            if (!singleUserReceivers.contains(cn)) {
17363                                singleUserReceivers.add(cn);
17364                                receivers.add(ri);
17365                            }
17366                        } else {
17367                            receivers.add(ri);
17368                        }
17369                    }
17370                }
17371            }
17372        } catch (RemoteException ex) {
17373            // pm is in same process, this will never happen.
17374        }
17375        return receivers;
17376    }
17377
17378    private boolean isPermittedShellBroadcast(Intent intent) {
17379        // remote bugreport should always be allowed to be taken
17380        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17381    }
17382
17383    final int broadcastIntentLocked(ProcessRecord callerApp,
17384            String callerPackage, Intent intent, String resolvedType,
17385            IIntentReceiver resultTo, int resultCode, String resultData,
17386            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17387            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17388        intent = new Intent(intent);
17389
17390        // By default broadcasts do not go to stopped apps.
17391        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17392
17393        // If we have not finished booting, don't allow this to launch new processes.
17394        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17395            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17396        }
17397
17398        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17399                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17400                + " ordered=" + ordered + " userid=" + userId);
17401        if ((resultTo != null) && !ordered) {
17402            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17403        }
17404
17405        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17406                ALLOW_NON_FULL, "broadcast", callerPackage);
17407
17408        // Make sure that the user who is receiving this broadcast is running.
17409        // If not, we will just skip it. Make an exception for shutdown broadcasts
17410        // and upgrade steps.
17411
17412        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17413            if ((callingUid != Process.SYSTEM_UID
17414                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17415                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17416                Slog.w(TAG, "Skipping broadcast of " + intent
17417                        + ": user " + userId + " is stopped");
17418                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17419            }
17420        }
17421
17422        BroadcastOptions brOptions = null;
17423        if (bOptions != null) {
17424            brOptions = new BroadcastOptions(bOptions);
17425            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17426                // See if the caller is allowed to do this.  Note we are checking against
17427                // the actual real caller (not whoever provided the operation as say a
17428                // PendingIntent), because that who is actually supplied the arguments.
17429                if (checkComponentPermission(
17430                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17431                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17432                        != PackageManager.PERMISSION_GRANTED) {
17433                    String msg = "Permission Denial: " + intent.getAction()
17434                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17435                            + ", uid=" + callingUid + ")"
17436                            + " requires "
17437                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17438                    Slog.w(TAG, msg);
17439                    throw new SecurityException(msg);
17440                }
17441            }
17442        }
17443
17444        // Verify that protected broadcasts are only being sent by system code,
17445        // and that system code is only sending protected broadcasts.
17446        final String action = intent.getAction();
17447        final boolean isProtectedBroadcast;
17448        try {
17449            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17450        } catch (RemoteException e) {
17451            Slog.w(TAG, "Remote exception", e);
17452            return ActivityManager.BROADCAST_SUCCESS;
17453        }
17454
17455        final boolean isCallerSystem;
17456        switch (UserHandle.getAppId(callingUid)) {
17457            case Process.ROOT_UID:
17458            case Process.SYSTEM_UID:
17459            case Process.PHONE_UID:
17460            case Process.BLUETOOTH_UID:
17461            case Process.NFC_UID:
17462                isCallerSystem = true;
17463                break;
17464            default:
17465                isCallerSystem = (callerApp != null) && callerApp.persistent;
17466                break;
17467        }
17468
17469        if (isCallerSystem) {
17470            if (isProtectedBroadcast
17471                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17472                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17473                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17474                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17475                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17476                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17477                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17478                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17479                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17480                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17481                // Broadcast is either protected, or it's a public action that
17482                // we've relaxed, so it's fine for system internals to send.
17483            } else {
17484                // The vast majority of broadcasts sent from system internals
17485                // should be protected to avoid security holes, so yell loudly
17486                // to ensure we examine these cases.
17487                if (callerApp != null) {
17488                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17489                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17490                            new Throwable());
17491                } else {
17492                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17493                            + " from system uid " + UserHandle.formatUid(callingUid)
17494                            + " pkg " + callerPackage,
17495                            new Throwable());
17496                }
17497            }
17498
17499        } else {
17500            if (isProtectedBroadcast) {
17501                String msg = "Permission Denial: not allowed to send broadcast "
17502                        + action + " from pid="
17503                        + callingPid + ", uid=" + callingUid;
17504                Slog.w(TAG, msg);
17505                throw new SecurityException(msg);
17506
17507            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17508                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17509                // Special case for compatibility: we don't want apps to send this,
17510                // but historically it has not been protected and apps may be using it
17511                // to poke their own app widget.  So, instead of making it protected,
17512                // just limit it to the caller.
17513                if (callerPackage == null) {
17514                    String msg = "Permission Denial: not allowed to send broadcast "
17515                            + action + " from unknown caller.";
17516                    Slog.w(TAG, msg);
17517                    throw new SecurityException(msg);
17518                } else if (intent.getComponent() != null) {
17519                    // They are good enough to send to an explicit component...  verify
17520                    // it is being sent to the calling app.
17521                    if (!intent.getComponent().getPackageName().equals(
17522                            callerPackage)) {
17523                        String msg = "Permission Denial: not allowed to send broadcast "
17524                                + action + " to "
17525                                + intent.getComponent().getPackageName() + " from "
17526                                + callerPackage;
17527                        Slog.w(TAG, msg);
17528                        throw new SecurityException(msg);
17529                    }
17530                } else {
17531                    // Limit broadcast to their own package.
17532                    intent.setPackage(callerPackage);
17533                }
17534            }
17535        }
17536
17537        if (action != null) {
17538            switch (action) {
17539                case Intent.ACTION_UID_REMOVED:
17540                case Intent.ACTION_PACKAGE_REMOVED:
17541                case Intent.ACTION_PACKAGE_CHANGED:
17542                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17543                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17544                case Intent.ACTION_PACKAGES_SUSPENDED:
17545                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17546                    // Handle special intents: if this broadcast is from the package
17547                    // manager about a package being removed, we need to remove all of
17548                    // its activities from the history stack.
17549                    if (checkComponentPermission(
17550                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17551                            callingPid, callingUid, -1, true)
17552                            != PackageManager.PERMISSION_GRANTED) {
17553                        String msg = "Permission Denial: " + intent.getAction()
17554                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17555                                + ", uid=" + callingUid + ")"
17556                                + " requires "
17557                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17558                        Slog.w(TAG, msg);
17559                        throw new SecurityException(msg);
17560                    }
17561                    switch (action) {
17562                        case Intent.ACTION_UID_REMOVED:
17563                            final Bundle intentExtras = intent.getExtras();
17564                            final int uid = intentExtras != null
17565                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17566                            if (uid >= 0) {
17567                                mBatteryStatsService.removeUid(uid);
17568                                mAppOpsService.uidRemoved(uid);
17569                            }
17570                            break;
17571                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17572                            // If resources are unavailable just force stop all those packages
17573                            // and flush the attribute cache as well.
17574                            String list[] =
17575                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17576                            if (list != null && list.length > 0) {
17577                                for (int i = 0; i < list.length; i++) {
17578                                    forceStopPackageLocked(list[i], -1, false, true, true,
17579                                            false, false, userId, "storage unmount");
17580                                }
17581                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17582                                sendPackageBroadcastLocked(
17583                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17584                                        userId);
17585                            }
17586                            break;
17587                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17588                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17589                            break;
17590                        case Intent.ACTION_PACKAGE_REMOVED:
17591                        case Intent.ACTION_PACKAGE_CHANGED:
17592                            Uri data = intent.getData();
17593                            String ssp;
17594                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17595                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17596                                final boolean replacing =
17597                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17598                                final boolean killProcess =
17599                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17600                                final boolean fullUninstall = removed && !replacing;
17601                                if (removed) {
17602                                    if (killProcess) {
17603                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17604                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17605                                                false, true, true, false, fullUninstall, userId,
17606                                                removed ? "pkg removed" : "pkg changed");
17607                                    }
17608                                    final int cmd = killProcess
17609                                            ? IApplicationThread.PACKAGE_REMOVED
17610                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17611                                    sendPackageBroadcastLocked(cmd,
17612                                            new String[] {ssp}, userId);
17613                                    if (fullUninstall) {
17614                                        mAppOpsService.packageRemoved(
17615                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17616
17617                                        // Remove all permissions granted from/to this package
17618                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17619
17620                                        removeTasksByPackageNameLocked(ssp, userId);
17621                                        mBatteryStatsService.notePackageUninstalled(ssp);
17622                                    }
17623                                } else {
17624                                    if (killProcess) {
17625                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17626                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17627                                                userId, ProcessList.INVALID_ADJ,
17628                                                false, true, true, false, "change " + ssp);
17629                                    }
17630                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17631                                            intent.getStringArrayExtra(
17632                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17633                                }
17634                            }
17635                            break;
17636                        case Intent.ACTION_PACKAGES_SUSPENDED:
17637                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17638                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17639                                    intent.getAction());
17640                            final String[] packageNames = intent.getStringArrayExtra(
17641                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17642                            final int userHandle = intent.getIntExtra(
17643                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17644
17645                            synchronized(ActivityManagerService.this) {
17646                                mRecentTasks.onPackagesSuspendedChanged(
17647                                        packageNames, suspended, userHandle);
17648                            }
17649                            break;
17650                    }
17651                    break;
17652                case Intent.ACTION_PACKAGE_REPLACED:
17653                {
17654                    final Uri data = intent.getData();
17655                    final String ssp;
17656                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17657                        final ApplicationInfo aInfo =
17658                                getPackageManagerInternalLocked().getApplicationInfo(
17659                                        ssp,
17660                                        userId);
17661                        if (aInfo == null) {
17662                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17663                                    + " ssp=" + ssp + " data=" + data);
17664                            return ActivityManager.BROADCAST_SUCCESS;
17665                        }
17666                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17667                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17668                                new String[] {ssp}, userId);
17669                    }
17670                    break;
17671                }
17672                case Intent.ACTION_PACKAGE_ADDED:
17673                {
17674                    // Special case for adding a package: by default turn on compatibility mode.
17675                    Uri data = intent.getData();
17676                    String ssp;
17677                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17678                        final boolean replacing =
17679                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17680                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17681
17682                        try {
17683                            ApplicationInfo ai = AppGlobals.getPackageManager().
17684                                    getApplicationInfo(ssp, 0, 0);
17685                            mBatteryStatsService.notePackageInstalled(ssp,
17686                                    ai != null ? ai.versionCode : 0);
17687                        } catch (RemoteException e) {
17688                        }
17689                    }
17690                    break;
17691                }
17692                case Intent.ACTION_TIMEZONE_CHANGED:
17693                    // If this is the time zone changed action, queue up a message that will reset
17694                    // the timezone of all currently running processes. This message will get
17695                    // queued up before the broadcast happens.
17696                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17697                    break;
17698                case Intent.ACTION_TIME_CHANGED:
17699                    // If the user set the time, let all running processes know.
17700                    final int is24Hour =
17701                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17702                                    : 0;
17703                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17704                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17705                    synchronized (stats) {
17706                        stats.noteCurrentTimeChangedLocked();
17707                    }
17708                    break;
17709                case Intent.ACTION_CLEAR_DNS_CACHE:
17710                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17711                    break;
17712                case Proxy.PROXY_CHANGE_ACTION:
17713                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17714                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17715                    break;
17716                case android.hardware.Camera.ACTION_NEW_PICTURE:
17717                case android.hardware.Camera.ACTION_NEW_VIDEO:
17718                    // These broadcasts are no longer allowed by the system, since they can
17719                    // cause significant thrashing at a crictical point (using the camera).
17720                    // Apps should use JobScehduler to monitor for media provider changes.
17721                    Slog.w(TAG, action + " no longer allowed; dropping from "
17722                            + UserHandle.formatUid(callingUid));
17723                    // Lie; we don't want to crash the app.
17724                    return ActivityManager.BROADCAST_SUCCESS;
17725            }
17726        }
17727
17728        // Add to the sticky list if requested.
17729        if (sticky) {
17730            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17731                    callingPid, callingUid)
17732                    != PackageManager.PERMISSION_GRANTED) {
17733                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17734                        + callingPid + ", uid=" + callingUid
17735                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17736                Slog.w(TAG, msg);
17737                throw new SecurityException(msg);
17738            }
17739            if (requiredPermissions != null && requiredPermissions.length > 0) {
17740                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17741                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17742                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17743            }
17744            if (intent.getComponent() != null) {
17745                throw new SecurityException(
17746                        "Sticky broadcasts can't target a specific component");
17747            }
17748            // We use userId directly here, since the "all" target is maintained
17749            // as a separate set of sticky broadcasts.
17750            if (userId != UserHandle.USER_ALL) {
17751                // But first, if this is not a broadcast to all users, then
17752                // make sure it doesn't conflict with an existing broadcast to
17753                // all users.
17754                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17755                        UserHandle.USER_ALL);
17756                if (stickies != null) {
17757                    ArrayList<Intent> list = stickies.get(intent.getAction());
17758                    if (list != null) {
17759                        int N = list.size();
17760                        int i;
17761                        for (i=0; i<N; i++) {
17762                            if (intent.filterEquals(list.get(i))) {
17763                                throw new IllegalArgumentException(
17764                                        "Sticky broadcast " + intent + " for user "
17765                                        + userId + " conflicts with existing global broadcast");
17766                            }
17767                        }
17768                    }
17769                }
17770            }
17771            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17772            if (stickies == null) {
17773                stickies = new ArrayMap<>();
17774                mStickyBroadcasts.put(userId, stickies);
17775            }
17776            ArrayList<Intent> list = stickies.get(intent.getAction());
17777            if (list == null) {
17778                list = new ArrayList<>();
17779                stickies.put(intent.getAction(), list);
17780            }
17781            final int stickiesCount = list.size();
17782            int i;
17783            for (i = 0; i < stickiesCount; i++) {
17784                if (intent.filterEquals(list.get(i))) {
17785                    // This sticky already exists, replace it.
17786                    list.set(i, new Intent(intent));
17787                    break;
17788                }
17789            }
17790            if (i >= stickiesCount) {
17791                list.add(new Intent(intent));
17792            }
17793        }
17794
17795        int[] users;
17796        if (userId == UserHandle.USER_ALL) {
17797            // Caller wants broadcast to go to all started users.
17798            users = mUserController.getStartedUserArrayLocked();
17799        } else {
17800            // Caller wants broadcast to go to one specific user.
17801            users = new int[] {userId};
17802        }
17803
17804        // Figure out who all will receive this broadcast.
17805        List receivers = null;
17806        List<BroadcastFilter> registeredReceivers = null;
17807        // Need to resolve the intent to interested receivers...
17808        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17809                 == 0) {
17810            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17811        }
17812        if (intent.getComponent() == null) {
17813            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17814                // Query one target user at a time, excluding shell-restricted users
17815                for (int i = 0; i < users.length; i++) {
17816                    if (mUserController.hasUserRestriction(
17817                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17818                        continue;
17819                    }
17820                    List<BroadcastFilter> registeredReceiversForUser =
17821                            mReceiverResolver.queryIntent(intent,
17822                                    resolvedType, false, users[i]);
17823                    if (registeredReceivers == null) {
17824                        registeredReceivers = registeredReceiversForUser;
17825                    } else if (registeredReceiversForUser != null) {
17826                        registeredReceivers.addAll(registeredReceiversForUser);
17827                    }
17828                }
17829            } else {
17830                registeredReceivers = mReceiverResolver.queryIntent(intent,
17831                        resolvedType, false, userId);
17832            }
17833        }
17834
17835        final boolean replacePending =
17836                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17837
17838        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17839                + " replacePending=" + replacePending);
17840
17841        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17842        if (!ordered && NR > 0) {
17843            // If we are not serializing this broadcast, then send the
17844            // registered receivers separately so they don't wait for the
17845            // components to be launched.
17846            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17847            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17848                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17849                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17850                    resultExtras, ordered, sticky, false, userId);
17851            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17852            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17853            if (!replaced) {
17854                queue.enqueueParallelBroadcastLocked(r);
17855                queue.scheduleBroadcastsLocked();
17856            }
17857            registeredReceivers = null;
17858            NR = 0;
17859        }
17860
17861        // Merge into one list.
17862        int ir = 0;
17863        if (receivers != null) {
17864            // A special case for PACKAGE_ADDED: do not allow the package
17865            // being added to see this broadcast.  This prevents them from
17866            // using this as a back door to get run as soon as they are
17867            // installed.  Maybe in the future we want to have a special install
17868            // broadcast or such for apps, but we'd like to deliberately make
17869            // this decision.
17870            String skipPackages[] = null;
17871            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17872                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17873                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17874                Uri data = intent.getData();
17875                if (data != null) {
17876                    String pkgName = data.getSchemeSpecificPart();
17877                    if (pkgName != null) {
17878                        skipPackages = new String[] { pkgName };
17879                    }
17880                }
17881            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17882                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17883            }
17884            if (skipPackages != null && (skipPackages.length > 0)) {
17885                for (String skipPackage : skipPackages) {
17886                    if (skipPackage != null) {
17887                        int NT = receivers.size();
17888                        for (int it=0; it<NT; it++) {
17889                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17890                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17891                                receivers.remove(it);
17892                                it--;
17893                                NT--;
17894                            }
17895                        }
17896                    }
17897                }
17898            }
17899
17900            int NT = receivers != null ? receivers.size() : 0;
17901            int it = 0;
17902            ResolveInfo curt = null;
17903            BroadcastFilter curr = null;
17904            while (it < NT && ir < NR) {
17905                if (curt == null) {
17906                    curt = (ResolveInfo)receivers.get(it);
17907                }
17908                if (curr == null) {
17909                    curr = registeredReceivers.get(ir);
17910                }
17911                if (curr.getPriority() >= curt.priority) {
17912                    // Insert this broadcast record into the final list.
17913                    receivers.add(it, curr);
17914                    ir++;
17915                    curr = null;
17916                    it++;
17917                    NT++;
17918                } else {
17919                    // Skip to the next ResolveInfo in the final list.
17920                    it++;
17921                    curt = null;
17922                }
17923            }
17924        }
17925        while (ir < NR) {
17926            if (receivers == null) {
17927                receivers = new ArrayList();
17928            }
17929            receivers.add(registeredReceivers.get(ir));
17930            ir++;
17931        }
17932
17933        if ((receivers != null && receivers.size() > 0)
17934                || resultTo != null) {
17935            BroadcastQueue queue = broadcastQueueForIntent(intent);
17936            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17937                    callerPackage, callingPid, callingUid, resolvedType,
17938                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17939                    resultData, resultExtras, ordered, sticky, false, userId);
17940
17941            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17942                    + ": prev had " + queue.mOrderedBroadcasts.size());
17943            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17944                    "Enqueueing broadcast " + r.intent.getAction());
17945
17946            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17947            if (!replaced) {
17948                queue.enqueueOrderedBroadcastLocked(r);
17949                queue.scheduleBroadcastsLocked();
17950            }
17951        }
17952
17953        return ActivityManager.BROADCAST_SUCCESS;
17954    }
17955
17956    final Intent verifyBroadcastLocked(Intent intent) {
17957        // Refuse possible leaked file descriptors
17958        if (intent != null && intent.hasFileDescriptors() == true) {
17959            throw new IllegalArgumentException("File descriptors passed in Intent");
17960        }
17961
17962        int flags = intent.getFlags();
17963
17964        if (!mProcessesReady) {
17965            // if the caller really truly claims to know what they're doing, go
17966            // ahead and allow the broadcast without launching any receivers
17967            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17968                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17969            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17970                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17971                        + " before boot completion");
17972                throw new IllegalStateException("Cannot broadcast before boot completed");
17973            }
17974        }
17975
17976        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17977            throw new IllegalArgumentException(
17978                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17979        }
17980
17981        return intent;
17982    }
17983
17984    public final int broadcastIntent(IApplicationThread caller,
17985            Intent intent, String resolvedType, IIntentReceiver resultTo,
17986            int resultCode, String resultData, Bundle resultExtras,
17987            String[] requiredPermissions, int appOp, Bundle bOptions,
17988            boolean serialized, boolean sticky, int userId) {
17989        enforceNotIsolatedCaller("broadcastIntent");
17990        synchronized(this) {
17991            intent = verifyBroadcastLocked(intent);
17992
17993            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17994            final int callingPid = Binder.getCallingPid();
17995            final int callingUid = Binder.getCallingUid();
17996            final long origId = Binder.clearCallingIdentity();
17997            int res = broadcastIntentLocked(callerApp,
17998                    callerApp != null ? callerApp.info.packageName : null,
17999                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18000                    requiredPermissions, appOp, bOptions, serialized, sticky,
18001                    callingPid, callingUid, userId);
18002            Binder.restoreCallingIdentity(origId);
18003            return res;
18004        }
18005    }
18006
18007
18008    int broadcastIntentInPackage(String packageName, int uid,
18009            Intent intent, String resolvedType, IIntentReceiver resultTo,
18010            int resultCode, String resultData, Bundle resultExtras,
18011            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18012            int userId) {
18013        synchronized(this) {
18014            intent = verifyBroadcastLocked(intent);
18015
18016            final long origId = Binder.clearCallingIdentity();
18017            String[] requiredPermissions = requiredPermission == null ? null
18018                    : new String[] {requiredPermission};
18019            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18020                    resultTo, resultCode, resultData, resultExtras,
18021                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18022                    sticky, -1, uid, userId);
18023            Binder.restoreCallingIdentity(origId);
18024            return res;
18025        }
18026    }
18027
18028    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18029        // Refuse possible leaked file descriptors
18030        if (intent != null && intent.hasFileDescriptors() == true) {
18031            throw new IllegalArgumentException("File descriptors passed in Intent");
18032        }
18033
18034        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18035                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18036
18037        synchronized(this) {
18038            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18039                    != PackageManager.PERMISSION_GRANTED) {
18040                String msg = "Permission Denial: unbroadcastIntent() from pid="
18041                        + Binder.getCallingPid()
18042                        + ", uid=" + Binder.getCallingUid()
18043                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18044                Slog.w(TAG, msg);
18045                throw new SecurityException(msg);
18046            }
18047            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18048            if (stickies != null) {
18049                ArrayList<Intent> list = stickies.get(intent.getAction());
18050                if (list != null) {
18051                    int N = list.size();
18052                    int i;
18053                    for (i=0; i<N; i++) {
18054                        if (intent.filterEquals(list.get(i))) {
18055                            list.remove(i);
18056                            break;
18057                        }
18058                    }
18059                    if (list.size() <= 0) {
18060                        stickies.remove(intent.getAction());
18061                    }
18062                }
18063                if (stickies.size() <= 0) {
18064                    mStickyBroadcasts.remove(userId);
18065                }
18066            }
18067        }
18068    }
18069
18070    void backgroundServicesFinishedLocked(int userId) {
18071        for (BroadcastQueue queue : mBroadcastQueues) {
18072            queue.backgroundServicesFinishedLocked(userId);
18073        }
18074    }
18075
18076    public void finishReceiver(IBinder who, int resultCode, String resultData,
18077            Bundle resultExtras, boolean resultAbort, int flags) {
18078        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18079
18080        // Refuse possible leaked file descriptors
18081        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18082            throw new IllegalArgumentException("File descriptors passed in Bundle");
18083        }
18084
18085        final long origId = Binder.clearCallingIdentity();
18086        try {
18087            boolean doNext = false;
18088            BroadcastRecord r;
18089
18090            synchronized(this) {
18091                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18092                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18093                r = queue.getMatchingOrderedReceiver(who);
18094                if (r != null) {
18095                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18096                        resultData, resultExtras, resultAbort, true);
18097                }
18098            }
18099
18100            if (doNext) {
18101                r.queue.processNextBroadcast(false);
18102            }
18103            trimApplications();
18104        } finally {
18105            Binder.restoreCallingIdentity(origId);
18106        }
18107    }
18108
18109    // =========================================================
18110    // INSTRUMENTATION
18111    // =========================================================
18112
18113    public boolean startInstrumentation(ComponentName className,
18114            String profileFile, int flags, Bundle arguments,
18115            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18116            int userId, String abiOverride) {
18117        enforceNotIsolatedCaller("startInstrumentation");
18118        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18119                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18120        // Refuse possible leaked file descriptors
18121        if (arguments != null && arguments.hasFileDescriptors()) {
18122            throw new IllegalArgumentException("File descriptors passed in Bundle");
18123        }
18124
18125        synchronized(this) {
18126            InstrumentationInfo ii = null;
18127            ApplicationInfo ai = null;
18128            try {
18129                ii = mContext.getPackageManager().getInstrumentationInfo(
18130                    className, STOCK_PM_FLAGS);
18131                ai = AppGlobals.getPackageManager().getApplicationInfo(
18132                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18133            } catch (PackageManager.NameNotFoundException e) {
18134            } catch (RemoteException e) {
18135            }
18136            if (ii == null) {
18137                reportStartInstrumentationFailureLocked(watcher, className,
18138                        "Unable to find instrumentation info for: " + className);
18139                return false;
18140            }
18141            if (ai == null) {
18142                reportStartInstrumentationFailureLocked(watcher, className,
18143                        "Unable to find instrumentation target package: " + ii.targetPackage);
18144                return false;
18145            }
18146            if (!ai.hasCode()) {
18147                reportStartInstrumentationFailureLocked(watcher, className,
18148                        "Instrumentation target has no code: " + ii.targetPackage);
18149                return false;
18150            }
18151
18152            int match = mContext.getPackageManager().checkSignatures(
18153                    ii.targetPackage, ii.packageName);
18154            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18155                String msg = "Permission Denial: starting instrumentation "
18156                        + className + " from pid="
18157                        + Binder.getCallingPid()
18158                        + ", uid=" + Binder.getCallingPid()
18159                        + " not allowed because package " + ii.packageName
18160                        + " does not have a signature matching the target "
18161                        + ii.targetPackage;
18162                reportStartInstrumentationFailureLocked(watcher, className, msg);
18163                throw new SecurityException(msg);
18164            }
18165
18166            final long origId = Binder.clearCallingIdentity();
18167            // Instrumentation can kill and relaunch even persistent processes
18168            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18169                    "start instr");
18170            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18171            app.instrumentationClass = className;
18172            app.instrumentationInfo = ai;
18173            app.instrumentationProfileFile = profileFile;
18174            app.instrumentationArguments = arguments;
18175            app.instrumentationWatcher = watcher;
18176            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18177            app.instrumentationResultClass = className;
18178            Binder.restoreCallingIdentity(origId);
18179        }
18180
18181        return true;
18182    }
18183
18184    /**
18185     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18186     * error to the logs, but if somebody is watching, send the report there too.  This enables
18187     * the "am" command to report errors with more information.
18188     *
18189     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18190     * @param cn The component name of the instrumentation.
18191     * @param report The error report.
18192     */
18193    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18194            ComponentName cn, String report) {
18195        Slog.w(TAG, report);
18196        if (watcher != null) {
18197            Bundle results = new Bundle();
18198            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18199            results.putString("Error", report);
18200            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18201        }
18202    }
18203
18204    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18205        if (app.instrumentationWatcher != null) {
18206            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18207                    app.instrumentationClass, resultCode, results);
18208        }
18209
18210        // Can't call out of the system process with a lock held, so post a message.
18211        if (app.instrumentationUiAutomationConnection != null) {
18212            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18213                    app.instrumentationUiAutomationConnection).sendToTarget();
18214        }
18215
18216        app.instrumentationWatcher = null;
18217        app.instrumentationUiAutomationConnection = null;
18218        app.instrumentationClass = null;
18219        app.instrumentationInfo = null;
18220        app.instrumentationProfileFile = null;
18221        app.instrumentationArguments = null;
18222
18223        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18224                "finished inst");
18225    }
18226
18227    public void finishInstrumentation(IApplicationThread target,
18228            int resultCode, Bundle results) {
18229        int userId = UserHandle.getCallingUserId();
18230        // Refuse possible leaked file descriptors
18231        if (results != null && results.hasFileDescriptors()) {
18232            throw new IllegalArgumentException("File descriptors passed in Intent");
18233        }
18234
18235        synchronized(this) {
18236            ProcessRecord app = getRecordForAppLocked(target);
18237            if (app == null) {
18238                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18239                return;
18240            }
18241            final long origId = Binder.clearCallingIdentity();
18242            finishInstrumentationLocked(app, resultCode, results);
18243            Binder.restoreCallingIdentity(origId);
18244        }
18245    }
18246
18247    // =========================================================
18248    // CONFIGURATION
18249    // =========================================================
18250
18251    public ConfigurationInfo getDeviceConfigurationInfo() {
18252        ConfigurationInfo config = new ConfigurationInfo();
18253        synchronized (this) {
18254            config.reqTouchScreen = mConfiguration.touchscreen;
18255            config.reqKeyboardType = mConfiguration.keyboard;
18256            config.reqNavigation = mConfiguration.navigation;
18257            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18258                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18259                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18260            }
18261            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18262                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18263                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18264            }
18265            config.reqGlEsVersion = GL_ES_VERSION;
18266        }
18267        return config;
18268    }
18269
18270    ActivityStack getFocusedStack() {
18271        return mStackSupervisor.getFocusedStack();
18272    }
18273
18274    @Override
18275    public int getFocusedStackId() throws RemoteException {
18276        ActivityStack focusedStack = getFocusedStack();
18277        if (focusedStack != null) {
18278            return focusedStack.getStackId();
18279        }
18280        return -1;
18281    }
18282
18283    public Configuration getConfiguration() {
18284        Configuration ci;
18285        synchronized(this) {
18286            ci = new Configuration(mConfiguration);
18287            ci.userSetLocale = false;
18288        }
18289        return ci;
18290    }
18291
18292    @Override
18293    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18294        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18295        synchronized (this) {
18296            mSuppressResizeConfigChanges = suppress;
18297        }
18298    }
18299
18300    @Override
18301    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18302        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18303        if (fromStackId == HOME_STACK_ID) {
18304            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18305        }
18306        synchronized (this) {
18307            final long origId = Binder.clearCallingIdentity();
18308            try {
18309                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18310            } finally {
18311                Binder.restoreCallingIdentity(origId);
18312            }
18313        }
18314    }
18315
18316    @Override
18317    public void updatePersistentConfiguration(Configuration values) {
18318        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319                "updateConfiguration()");
18320        enforceWriteSettingsPermission("updateConfiguration()");
18321        if (values == null) {
18322            throw new NullPointerException("Configuration must not be null");
18323        }
18324
18325        int userId = UserHandle.getCallingUserId();
18326
18327        synchronized(this) {
18328            final long origId = Binder.clearCallingIdentity();
18329            updateConfigurationLocked(values, null, false, true, userId);
18330            Binder.restoreCallingIdentity(origId);
18331        }
18332    }
18333
18334    private void updateFontScaleIfNeeded() {
18335        final int currentUserId;
18336        synchronized(this) {
18337            currentUserId = mUserController.getCurrentUserIdLocked();
18338        }
18339        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18340                FONT_SCALE, 1.0f, currentUserId);
18341        if (mConfiguration.fontScale != scaleFactor) {
18342            final Configuration configuration = mWindowManager.computeNewConfiguration();
18343            configuration.fontScale = scaleFactor;
18344            updatePersistentConfiguration(configuration);
18345        }
18346    }
18347
18348    private void enforceWriteSettingsPermission(String func) {
18349        int uid = Binder.getCallingUid();
18350        if (uid == Process.ROOT_UID) {
18351            return;
18352        }
18353
18354        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18355                Settings.getPackageNameForUid(mContext, uid), false)) {
18356            return;
18357        }
18358
18359        String msg = "Permission Denial: " + func + " from pid="
18360                + Binder.getCallingPid()
18361                + ", uid=" + uid
18362                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18363        Slog.w(TAG, msg);
18364        throw new SecurityException(msg);
18365    }
18366
18367    public void updateConfiguration(Configuration values) {
18368        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18369                "updateConfiguration()");
18370
18371        synchronized(this) {
18372            if (values == null && mWindowManager != null) {
18373                // sentinel: fetch the current configuration from the window manager
18374                values = mWindowManager.computeNewConfiguration();
18375            }
18376
18377            if (mWindowManager != null) {
18378                mProcessList.applyDisplaySize(mWindowManager);
18379            }
18380
18381            final long origId = Binder.clearCallingIdentity();
18382            if (values != null) {
18383                Settings.System.clearConfiguration(values);
18384            }
18385            updateConfigurationLocked(values, null, false);
18386            Binder.restoreCallingIdentity(origId);
18387        }
18388    }
18389
18390    void updateUserConfigurationLocked() {
18391        Configuration configuration = new Configuration(mConfiguration);
18392        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18393                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18394        updateConfigurationLocked(configuration, null, false);
18395    }
18396
18397    boolean updateConfigurationLocked(Configuration values,
18398            ActivityRecord starting, boolean initLocale) {
18399        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18400        return updateConfigurationLocked(values, starting, initLocale, false,
18401                UserHandle.USER_NULL);
18402    }
18403
18404    // To cache the list of supported system locales
18405    private String[] mSupportedSystemLocales = null;
18406
18407    /**
18408     * Do either or both things: (1) change the current configuration, and (2)
18409     * make sure the given activity is running with the (now) current
18410     * configuration.  Returns true if the activity has been left running, or
18411     * false if <var>starting</var> is being destroyed to match the new
18412     * configuration.
18413     *
18414     * @param userId is only used when persistent parameter is set to true to persist configuration
18415     *               for that particular user
18416     */
18417    private boolean updateConfigurationLocked(Configuration values,
18418            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18419        int changes = 0;
18420
18421        if (mWindowManager != null) {
18422            mWindowManager.deferSurfaceLayout();
18423        }
18424        if (values != null) {
18425            Configuration newConfig = new Configuration(mConfiguration);
18426            changes = newConfig.updateFrom(values);
18427            if (changes != 0) {
18428                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18429                        "Updating configuration to: " + values);
18430
18431                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18432
18433                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18434                    final LocaleList locales = values.getLocales();
18435                    int bestLocaleIndex = 0;
18436                    if (locales.size() > 1) {
18437                        if (mSupportedSystemLocales == null) {
18438                            mSupportedSystemLocales =
18439                                    Resources.getSystem().getAssets().getLocales();
18440                        }
18441                        bestLocaleIndex = Math.max(0,
18442                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18443                    }
18444                    SystemProperties.set("persist.sys.locale",
18445                            locales.get(bestLocaleIndex).toLanguageTag());
18446                    LocaleList.setDefault(locales, bestLocaleIndex);
18447                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18448                            locales.get(bestLocaleIndex)));
18449                }
18450
18451                mConfigurationSeq++;
18452                if (mConfigurationSeq <= 0) {
18453                    mConfigurationSeq = 1;
18454                }
18455                newConfig.seq = mConfigurationSeq;
18456                mConfiguration = newConfig;
18457                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18458                mUsageStatsService.reportConfigurationChange(newConfig,
18459                        mUserController.getCurrentUserIdLocked());
18460                //mUsageStatsService.noteStartConfig(newConfig);
18461
18462                final Configuration configCopy = new Configuration(mConfiguration);
18463
18464                // TODO: If our config changes, should we auto dismiss any currently
18465                // showing dialogs?
18466                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18467
18468                AttributeCache ac = AttributeCache.instance();
18469                if (ac != null) {
18470                    ac.updateConfiguration(configCopy);
18471                }
18472
18473                // Make sure all resources in our process are updated
18474                // right now, so that anyone who is going to retrieve
18475                // resource values after we return will be sure to get
18476                // the new ones.  This is especially important during
18477                // boot, where the first config change needs to guarantee
18478                // all resources have that config before following boot
18479                // code is executed.
18480                mSystemThread.applyConfigurationToResources(configCopy);
18481
18482                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18483                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18484                    msg.obj = new Configuration(configCopy);
18485                    msg.arg1 = userId;
18486                    mHandler.sendMessage(msg);
18487                }
18488
18489                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18490                if (isDensityChange) {
18491                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18492                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18493                }
18494
18495                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18496                    ProcessRecord app = mLruProcesses.get(i);
18497                    try {
18498                        if (app.thread != null) {
18499                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18500                                    + app.processName + " new config " + mConfiguration);
18501                            app.thread.scheduleConfigurationChanged(configCopy);
18502                        }
18503                    } catch (Exception e) {
18504                    }
18505                }
18506                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18507                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18508                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18509                        | Intent.FLAG_RECEIVER_FOREGROUND);
18510                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18511                        null, AppOpsManager.OP_NONE, null, false, false,
18512                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18513                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18514                    // Tell the shortcut manager that the system locale changed.  It needs to know
18515                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18516                    // we "push" from here, rather than having the service listen to the broadcast.
18517                    final ShortcutServiceInternal shortcutService =
18518                            LocalServices.getService(ShortcutServiceInternal.class);
18519                    if (shortcutService != null) {
18520                        shortcutService.onSystemLocaleChangedNoLock();
18521                    }
18522
18523                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18524                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18525                    if (!mProcessesReady) {
18526                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18527                    }
18528                    broadcastIntentLocked(null, null, intent,
18529                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18530                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18531                }
18532            }
18533            // Update the configuration with WM first and check if any of the stacks need to be
18534            // resized due to the configuration change. If so, resize the stacks now and do any
18535            // relaunches if necessary. This way we don't need to relaunch again below in
18536            // ensureActivityConfigurationLocked().
18537            if (mWindowManager != null) {
18538                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18539                if (resizedStacks != null) {
18540                    for (int stackId : resizedStacks) {
18541                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18542                        mStackSupervisor.resizeStackLocked(
18543                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18544                    }
18545                }
18546            }
18547        }
18548
18549        boolean kept = true;
18550        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18551        // mainStack is null during startup.
18552        if (mainStack != null) {
18553            if (changes != 0 && starting == null) {
18554                // If the configuration changed, and the caller is not already
18555                // in the process of starting an activity, then find the top
18556                // activity to check if its configuration needs to change.
18557                starting = mainStack.topRunningActivityLocked();
18558            }
18559
18560            if (starting != null) {
18561                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18562                // And we need to make sure at this point that all other activities
18563                // are made visible with the correct configuration.
18564                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18565                        !PRESERVE_WINDOWS);
18566            }
18567        }
18568        if (mWindowManager != null) {
18569            mWindowManager.continueSurfaceLayout();
18570        }
18571        return kept;
18572    }
18573
18574    /**
18575     * Decide based on the configuration whether we should shouw the ANR,
18576     * crash, etc dialogs.  The idea is that if there is no affordnace to
18577     * press the on-screen buttons, we shouldn't show the dialog.
18578     *
18579     * A thought: SystemUI might also want to get told about this, the Power
18580     * dialog / global actions also might want different behaviors.
18581     */
18582    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18583        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18584                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18585                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18586        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18587                                    == Configuration.UI_MODE_TYPE_CAR);
18588        return inputMethodExists && uiIsNotCarType && !inVrMode;
18589    }
18590
18591    @Override
18592    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18593        synchronized (this) {
18594            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18595            if (srec != null) {
18596                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18597            }
18598        }
18599        return false;
18600    }
18601
18602    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18603            Intent resultData) {
18604
18605        synchronized (this) {
18606            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18607            if (r != null) {
18608                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18609            }
18610            return false;
18611        }
18612    }
18613
18614    public int getLaunchedFromUid(IBinder activityToken) {
18615        ActivityRecord srec;
18616        synchronized (this) {
18617            srec = ActivityRecord.forTokenLocked(activityToken);
18618        }
18619        if (srec == null) {
18620            return -1;
18621        }
18622        return srec.launchedFromUid;
18623    }
18624
18625    public String getLaunchedFromPackage(IBinder activityToken) {
18626        ActivityRecord srec;
18627        synchronized (this) {
18628            srec = ActivityRecord.forTokenLocked(activityToken);
18629        }
18630        if (srec == null) {
18631            return null;
18632        }
18633        return srec.launchedFromPackage;
18634    }
18635
18636    // =========================================================
18637    // LIFETIME MANAGEMENT
18638    // =========================================================
18639
18640    // Returns which broadcast queue the app is the current [or imminent] receiver
18641    // on, or 'null' if the app is not an active broadcast recipient.
18642    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18643        BroadcastRecord r = app.curReceiver;
18644        if (r != null) {
18645            return r.queue;
18646        }
18647
18648        // It's not the current receiver, but it might be starting up to become one
18649        synchronized (this) {
18650            for (BroadcastQueue queue : mBroadcastQueues) {
18651                r = queue.mPendingBroadcast;
18652                if (r != null && r.curApp == app) {
18653                    // found it; report which queue it's in
18654                    return queue;
18655                }
18656            }
18657        }
18658
18659        return null;
18660    }
18661
18662    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18663            int targetUid, ComponentName targetComponent, String targetProcess) {
18664        if (!mTrackingAssociations) {
18665            return null;
18666        }
18667        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18668                = mAssociations.get(targetUid);
18669        if (components == null) {
18670            components = new ArrayMap<>();
18671            mAssociations.put(targetUid, components);
18672        }
18673        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18674        if (sourceUids == null) {
18675            sourceUids = new SparseArray<>();
18676            components.put(targetComponent, sourceUids);
18677        }
18678        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18679        if (sourceProcesses == null) {
18680            sourceProcesses = new ArrayMap<>();
18681            sourceUids.put(sourceUid, sourceProcesses);
18682        }
18683        Association ass = sourceProcesses.get(sourceProcess);
18684        if (ass == null) {
18685            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18686                    targetProcess);
18687            sourceProcesses.put(sourceProcess, ass);
18688        }
18689        ass.mCount++;
18690        ass.mNesting++;
18691        if (ass.mNesting == 1) {
18692            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18693            ass.mLastState = sourceState;
18694        }
18695        return ass;
18696    }
18697
18698    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18699            ComponentName targetComponent) {
18700        if (!mTrackingAssociations) {
18701            return;
18702        }
18703        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18704                = mAssociations.get(targetUid);
18705        if (components == null) {
18706            return;
18707        }
18708        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18709        if (sourceUids == null) {
18710            return;
18711        }
18712        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18713        if (sourceProcesses == null) {
18714            return;
18715        }
18716        Association ass = sourceProcesses.get(sourceProcess);
18717        if (ass == null || ass.mNesting <= 0) {
18718            return;
18719        }
18720        ass.mNesting--;
18721        if (ass.mNesting == 0) {
18722            long uptime = SystemClock.uptimeMillis();
18723            ass.mTime += uptime - ass.mStartTime;
18724            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18725                    += uptime - ass.mLastStateUptime;
18726            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18727        }
18728    }
18729
18730    private void noteUidProcessState(final int uid, final int state) {
18731        mBatteryStatsService.noteUidProcessState(uid, state);
18732        if (mTrackingAssociations) {
18733            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18734                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18735                        = mAssociations.valueAt(i1);
18736                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18737                    SparseArray<ArrayMap<String, Association>> sourceUids
18738                            = targetComponents.valueAt(i2);
18739                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18740                    if (sourceProcesses != null) {
18741                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18742                            Association ass = sourceProcesses.valueAt(i4);
18743                            if (ass.mNesting >= 1) {
18744                                // currently associated
18745                                long uptime = SystemClock.uptimeMillis();
18746                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18747                                        += uptime - ass.mLastStateUptime;
18748                                ass.mLastState = state;
18749                                ass.mLastStateUptime = uptime;
18750                            }
18751                        }
18752                    }
18753                }
18754            }
18755        }
18756    }
18757
18758    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18759            boolean doingAll, long now) {
18760        if (mAdjSeq == app.adjSeq) {
18761            // This adjustment has already been computed.
18762            return app.curRawAdj;
18763        }
18764
18765        if (app.thread == null) {
18766            app.adjSeq = mAdjSeq;
18767            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18768            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18769            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18770        }
18771
18772        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18773        app.adjSource = null;
18774        app.adjTarget = null;
18775        app.empty = false;
18776        app.cached = false;
18777
18778        final int activitiesSize = app.activities.size();
18779
18780        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18781            // The max adjustment doesn't allow this app to be anything
18782            // below foreground, so it is not worth doing work for it.
18783            app.adjType = "fixed";
18784            app.adjSeq = mAdjSeq;
18785            app.curRawAdj = app.maxAdj;
18786            app.foregroundActivities = false;
18787            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18788            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18789            // System processes can do UI, and when they do we want to have
18790            // them trim their memory after the user leaves the UI.  To
18791            // facilitate this, here we need to determine whether or not it
18792            // is currently showing UI.
18793            app.systemNoUi = true;
18794            if (app == TOP_APP) {
18795                app.systemNoUi = false;
18796                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18797                app.adjType = "pers-top-activity";
18798            } else if (activitiesSize > 0) {
18799                for (int j = 0; j < activitiesSize; j++) {
18800                    final ActivityRecord r = app.activities.get(j);
18801                    if (r.visible) {
18802                        app.systemNoUi = false;
18803                    }
18804                }
18805            }
18806            if (!app.systemNoUi) {
18807                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18808            }
18809            return (app.curAdj=app.maxAdj);
18810        }
18811
18812        app.systemNoUi = false;
18813
18814        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18815
18816        // Determine the importance of the process, starting with most
18817        // important to least, and assign an appropriate OOM adjustment.
18818        int adj;
18819        int schedGroup;
18820        int procState;
18821        boolean foregroundActivities = false;
18822        BroadcastQueue queue;
18823        if (app == TOP_APP) {
18824            // The last app on the list is the foreground app.
18825            adj = ProcessList.FOREGROUND_APP_ADJ;
18826            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18827            app.adjType = "top-activity";
18828            foregroundActivities = true;
18829            procState = PROCESS_STATE_CUR_TOP;
18830        } else if (app.instrumentationClass != null) {
18831            // Don't want to kill running instrumentation.
18832            adj = ProcessList.FOREGROUND_APP_ADJ;
18833            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18834            app.adjType = "instrumentation";
18835            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18836        } else if ((queue = isReceivingBroadcast(app)) != null) {
18837            // An app that is currently receiving a broadcast also
18838            // counts as being in the foreground for OOM killer purposes.
18839            // It's placed in a sched group based on the nature of the
18840            // broadcast as reflected by which queue it's active in.
18841            adj = ProcessList.FOREGROUND_APP_ADJ;
18842            schedGroup = (queue == mFgBroadcastQueue)
18843                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18844            app.adjType = "broadcast";
18845            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18846        } else if (app.executingServices.size() > 0) {
18847            // An app that is currently executing a service callback also
18848            // counts as being in the foreground.
18849            adj = ProcessList.FOREGROUND_APP_ADJ;
18850            schedGroup = app.execServicesFg ?
18851                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18852            app.adjType = "exec-service";
18853            procState = ActivityManager.PROCESS_STATE_SERVICE;
18854            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18855        } else {
18856            // As far as we know the process is empty.  We may change our mind later.
18857            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18858            // At this point we don't actually know the adjustment.  Use the cached adj
18859            // value that the caller wants us to.
18860            adj = cachedAdj;
18861            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18862            app.cached = true;
18863            app.empty = true;
18864            app.adjType = "cch-empty";
18865        }
18866
18867        // Examine all activities if not already foreground.
18868        if (!foregroundActivities && activitiesSize > 0) {
18869            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18870            for (int j = 0; j < activitiesSize; j++) {
18871                final ActivityRecord r = app.activities.get(j);
18872                if (r.app != app) {
18873                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
18874                            + " instead of expected " + app);
18875                    if (r.app == null || (r.app.uid == app.uid)) {
18876                        // Only fix things up when they look sane
18877                        r.app = app;
18878                    } else {
18879                        continue;
18880                    }
18881                }
18882                if (r.visible) {
18883                    // App has a visible activity; only upgrade adjustment.
18884                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18885                        adj = ProcessList.VISIBLE_APP_ADJ;
18886                        app.adjType = "visible";
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                    if (r.task != null && minLayer > 0) {
18896                        final int layer = r.task.mLayerRank;
18897                        if (layer >= 0 && minLayer > layer) {
18898                            minLayer = layer;
18899                        }
18900                    }
18901                    break;
18902                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18903                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18904                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18905                        app.adjType = "pausing";
18906                    }
18907                    if (procState > PROCESS_STATE_CUR_TOP) {
18908                        procState = PROCESS_STATE_CUR_TOP;
18909                    }
18910                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18911                    app.cached = false;
18912                    app.empty = false;
18913                    foregroundActivities = true;
18914                } else if (r.state == ActivityState.STOPPING) {
18915                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18916                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18917                        app.adjType = "stopping";
18918                    }
18919                    // For the process state, we will at this point consider the
18920                    // process to be cached.  It will be cached either as an activity
18921                    // or empty depending on whether the activity is finishing.  We do
18922                    // this so that we can treat the process as cached for purposes of
18923                    // memory trimming (determing current memory level, trim command to
18924                    // send to process) since there can be an arbitrary number of stopping
18925                    // processes and they should soon all go into the cached state.
18926                    if (!r.finishing) {
18927                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18928                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18929                        }
18930                    }
18931                    app.cached = false;
18932                    app.empty = false;
18933                    foregroundActivities = true;
18934                } else {
18935                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18936                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18937                        app.adjType = "cch-act";
18938                    }
18939                }
18940            }
18941            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18942                adj += minLayer;
18943            }
18944        }
18945
18946        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18947                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18948            if (app.foregroundServices) {
18949                // The user is aware of this app, so make it visible.
18950                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18951                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18952                app.cached = false;
18953                app.adjType = "fg-service";
18954                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18955            } else if (app.forcingToForeground != null) {
18956                // The user is aware of this app, so make it visible.
18957                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18958                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18959                app.cached = false;
18960                app.adjType = "force-fg";
18961                app.adjSource = app.forcingToForeground;
18962                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18963            }
18964        }
18965
18966        if (app == mHeavyWeightProcess) {
18967            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18968                // We don't want to kill the current heavy-weight process.
18969                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18970                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18971                app.cached = false;
18972                app.adjType = "heavy";
18973            }
18974            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18975                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18976            }
18977        }
18978
18979        if (app == mHomeProcess) {
18980            if (adj > ProcessList.HOME_APP_ADJ) {
18981                // This process is hosting what we currently consider to be the
18982                // home app, so we don't want to let it go into the background.
18983                adj = ProcessList.HOME_APP_ADJ;
18984                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18985                app.cached = false;
18986                app.adjType = "home";
18987            }
18988            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18989                procState = ActivityManager.PROCESS_STATE_HOME;
18990            }
18991        }
18992
18993        if (app == mPreviousProcess && app.activities.size() > 0) {
18994            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18995                // This was the previous process that showed UI to the user.
18996                // We want to try to keep it around more aggressively, to give
18997                // a good experience around switching between two apps.
18998                adj = ProcessList.PREVIOUS_APP_ADJ;
18999                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19000                app.cached = false;
19001                app.adjType = "previous";
19002            }
19003            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19004                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19005            }
19006        }
19007
19008        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19009                + " reason=" + app.adjType);
19010
19011        // By default, we use the computed adjustment.  It may be changed if
19012        // there are applications dependent on our services or providers, but
19013        // this gives us a baseline and makes sure we don't get into an
19014        // infinite recursion.
19015        app.adjSeq = mAdjSeq;
19016        app.curRawAdj = adj;
19017        app.hasStartedServices = false;
19018
19019        if (mBackupTarget != null && app == mBackupTarget.app) {
19020            // If possible we want to avoid killing apps while they're being backed up
19021            if (adj > ProcessList.BACKUP_APP_ADJ) {
19022                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19023                adj = ProcessList.BACKUP_APP_ADJ;
19024                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19025                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19026                }
19027                app.adjType = "backup";
19028                app.cached = false;
19029            }
19030            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19031                procState = ActivityManager.PROCESS_STATE_BACKUP;
19032            }
19033        }
19034
19035        boolean mayBeTop = false;
19036
19037        for (int is = app.services.size()-1;
19038                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19039                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19040                        || procState > ActivityManager.PROCESS_STATE_TOP);
19041                is--) {
19042            ServiceRecord s = app.services.valueAt(is);
19043            if (s.startRequested) {
19044                app.hasStartedServices = true;
19045                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19046                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19047                }
19048                if (app.hasShownUi && app != mHomeProcess) {
19049                    // If this process has shown some UI, let it immediately
19050                    // go to the LRU list because it may be pretty heavy with
19051                    // UI stuff.  We'll tag it with a label just to help
19052                    // debug and understand what is going on.
19053                    if (adj > ProcessList.SERVICE_ADJ) {
19054                        app.adjType = "cch-started-ui-services";
19055                    }
19056                } else {
19057                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19058                        // This service has seen some activity within
19059                        // recent memory, so we will keep its process ahead
19060                        // of the background processes.
19061                        if (adj > ProcessList.SERVICE_ADJ) {
19062                            adj = ProcessList.SERVICE_ADJ;
19063                            app.adjType = "started-services";
19064                            app.cached = false;
19065                        }
19066                    }
19067                    // If we have let the service slide into the background
19068                    // state, still have some text describing what it is doing
19069                    // even though the service no longer has an impact.
19070                    if (adj > ProcessList.SERVICE_ADJ) {
19071                        app.adjType = "cch-started-services";
19072                    }
19073                }
19074            }
19075
19076            app.whitelistManager = false;
19077
19078            for (int conni = s.connections.size()-1;
19079                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19080                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19081                            || procState > ActivityManager.PROCESS_STATE_TOP);
19082                    conni--) {
19083                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19084                for (int i = 0;
19085                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19086                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19087                                || procState > ActivityManager.PROCESS_STATE_TOP);
19088                        i++) {
19089                    // XXX should compute this based on the max of
19090                    // all connected clients.
19091                    ConnectionRecord cr = clist.get(i);
19092                    if (cr.binding.client == app) {
19093                        // Binding to ourself is not interesting.
19094                        continue;
19095                    }
19096                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19097                        app.whitelistManager = true;
19098                    }
19099
19100                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19101                        ProcessRecord client = cr.binding.client;
19102                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19103                                TOP_APP, doingAll, now);
19104                        int clientProcState = client.curProcState;
19105                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19106                            // If the other app is cached for any reason, for purposes here
19107                            // we are going to consider it empty.  The specific cached state
19108                            // doesn't propagate except under certain conditions.
19109                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19110                        }
19111                        String adjType = null;
19112                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19113                            // Not doing bind OOM management, so treat
19114                            // this guy more like a started service.
19115                            if (app.hasShownUi && app != mHomeProcess) {
19116                                // If this process has shown some UI, let it immediately
19117                                // go to the LRU list because it may be pretty heavy with
19118                                // UI stuff.  We'll tag it with a label just to help
19119                                // debug and understand what is going on.
19120                                if (adj > clientAdj) {
19121                                    adjType = "cch-bound-ui-services";
19122                                }
19123                                app.cached = false;
19124                                clientAdj = adj;
19125                                clientProcState = procState;
19126                            } else {
19127                                if (now >= (s.lastActivity
19128                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19129                                    // This service has not seen activity within
19130                                    // recent memory, so allow it to drop to the
19131                                    // LRU list if there is no other reason to keep
19132                                    // it around.  We'll also tag it with a label just
19133                                    // to help debug and undertand what is going on.
19134                                    if (adj > clientAdj) {
19135                                        adjType = "cch-bound-services";
19136                                    }
19137                                    clientAdj = adj;
19138                                }
19139                            }
19140                        }
19141                        if (adj > clientAdj) {
19142                            // If this process has recently shown UI, and
19143                            // the process that is binding to it is less
19144                            // important than being visible, then we don't
19145                            // care about the binding as much as we care
19146                            // about letting this process get into the LRU
19147                            // list to be killed and restarted if needed for
19148                            // memory.
19149                            if (app.hasShownUi && app != mHomeProcess
19150                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19151                                adjType = "cch-bound-ui-services";
19152                            } else {
19153                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19154                                        |Context.BIND_IMPORTANT)) != 0) {
19155                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19156                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19157                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19158                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19159                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19160                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19161                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19162                                    adj = clientAdj;
19163                                } else {
19164                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19165                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19166                                    }
19167                                }
19168                                if (!client.cached) {
19169                                    app.cached = false;
19170                                }
19171                                adjType = "service";
19172                            }
19173                        }
19174                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19175                            // This will treat important bound services identically to
19176                            // the top app, which may behave differently than generic
19177                            // foreground work.
19178                            if (client.curSchedGroup > schedGroup) {
19179                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19180                                    schedGroup = client.curSchedGroup;
19181                                } else {
19182                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19183                                }
19184                            }
19185                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19186                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19187                                    // Special handling of clients who are in the top state.
19188                                    // We *may* want to consider this process to be in the
19189                                    // top state as well, but only if there is not another
19190                                    // reason for it to be running.  Being on the top is a
19191                                    // special state, meaning you are specifically running
19192                                    // for the current top app.  If the process is already
19193                                    // running in the background for some other reason, it
19194                                    // is more important to continue considering it to be
19195                                    // in the background state.
19196                                    mayBeTop = true;
19197                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19198                                } else {
19199                                    // Special handling for above-top states (persistent
19200                                    // processes).  These should not bring the current process
19201                                    // into the top state, since they are not on top.  Instead
19202                                    // give them the best state after that.
19203                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19204                                        clientProcState =
19205                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19206                                    } else if (mWakefulness
19207                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19208                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19209                                                    != 0) {
19210                                        clientProcState =
19211                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19212                                    } else {
19213                                        clientProcState =
19214                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19215                                    }
19216                                }
19217                            }
19218                        } else {
19219                            if (clientProcState <
19220                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19221                                clientProcState =
19222                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19223                            }
19224                        }
19225                        if (procState > clientProcState) {
19226                            procState = clientProcState;
19227                        }
19228                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19229                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19230                            app.pendingUiClean = true;
19231                        }
19232                        if (adjType != null) {
19233                            app.adjType = adjType;
19234                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19235                                    .REASON_SERVICE_IN_USE;
19236                            app.adjSource = cr.binding.client;
19237                            app.adjSourceProcState = clientProcState;
19238                            app.adjTarget = s.name;
19239                        }
19240                    }
19241                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19242                        app.treatLikeActivity = true;
19243                    }
19244                    final ActivityRecord a = cr.activity;
19245                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19246                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19247                            (a.visible || a.state == ActivityState.RESUMED ||
19248                             a.state == ActivityState.PAUSING)) {
19249                            adj = ProcessList.FOREGROUND_APP_ADJ;
19250                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19251                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19252                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19253                                } else {
19254                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19255                                }
19256                            }
19257                            app.cached = false;
19258                            app.adjType = "service";
19259                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19260                                    .REASON_SERVICE_IN_USE;
19261                            app.adjSource = a;
19262                            app.adjSourceProcState = procState;
19263                            app.adjTarget = s.name;
19264                        }
19265                    }
19266                }
19267            }
19268        }
19269
19270        for (int provi = app.pubProviders.size()-1;
19271                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19272                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19273                        || procState > ActivityManager.PROCESS_STATE_TOP);
19274                provi--) {
19275            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19276            for (int i = cpr.connections.size()-1;
19277                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19278                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19279                            || procState > ActivityManager.PROCESS_STATE_TOP);
19280                    i--) {
19281                ContentProviderConnection conn = cpr.connections.get(i);
19282                ProcessRecord client = conn.client;
19283                if (client == app) {
19284                    // Being our own client is not interesting.
19285                    continue;
19286                }
19287                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19288                int clientProcState = client.curProcState;
19289                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19290                    // If the other app is cached for any reason, for purposes here
19291                    // we are going to consider it empty.
19292                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19293                }
19294                if (adj > clientAdj) {
19295                    if (app.hasShownUi && app != mHomeProcess
19296                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19297                        app.adjType = "cch-ui-provider";
19298                    } else {
19299                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19300                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19301                        app.adjType = "provider";
19302                    }
19303                    app.cached &= client.cached;
19304                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19305                            .REASON_PROVIDER_IN_USE;
19306                    app.adjSource = client;
19307                    app.adjSourceProcState = clientProcState;
19308                    app.adjTarget = cpr.name;
19309                }
19310                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19311                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19312                        // Special handling of clients who are in the top state.
19313                        // We *may* want to consider this process to be in the
19314                        // top state as well, but only if there is not another
19315                        // reason for it to be running.  Being on the top is a
19316                        // special state, meaning you are specifically running
19317                        // for the current top app.  If the process is already
19318                        // running in the background for some other reason, it
19319                        // is more important to continue considering it to be
19320                        // in the background state.
19321                        mayBeTop = true;
19322                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19323                    } else {
19324                        // Special handling for above-top states (persistent
19325                        // processes).  These should not bring the current process
19326                        // into the top state, since they are not on top.  Instead
19327                        // give them the best state after that.
19328                        clientProcState =
19329                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19330                    }
19331                }
19332                if (procState > clientProcState) {
19333                    procState = clientProcState;
19334                }
19335                if (client.curSchedGroup > schedGroup) {
19336                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19337                }
19338            }
19339            // If the provider has external (non-framework) process
19340            // dependencies, ensure that its adjustment is at least
19341            // FOREGROUND_APP_ADJ.
19342            if (cpr.hasExternalProcessHandles()) {
19343                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19344                    adj = ProcessList.FOREGROUND_APP_ADJ;
19345                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19346                    app.cached = false;
19347                    app.adjType = "provider";
19348                    app.adjTarget = cpr.name;
19349                }
19350                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19351                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19352                }
19353            }
19354        }
19355
19356        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19357            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19358                adj = ProcessList.PREVIOUS_APP_ADJ;
19359                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19360                app.cached = false;
19361                app.adjType = "provider";
19362            }
19363            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19364                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19365            }
19366        }
19367
19368        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19369            // A client of one of our services or providers is in the top state.  We
19370            // *may* want to be in the top state, but not if we are already running in
19371            // the background for some other reason.  For the decision here, we are going
19372            // to pick out a few specific states that we want to remain in when a client
19373            // is top (states that tend to be longer-term) and otherwise allow it to go
19374            // to the top state.
19375            switch (procState) {
19376                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19377                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19378                case ActivityManager.PROCESS_STATE_SERVICE:
19379                    // These all are longer-term states, so pull them up to the top
19380                    // of the background states, but not all the way to the top state.
19381                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19382                    break;
19383                default:
19384                    // Otherwise, top is a better choice, so take it.
19385                    procState = ActivityManager.PROCESS_STATE_TOP;
19386                    break;
19387            }
19388        }
19389
19390        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19391            if (app.hasClientActivities) {
19392                // This is a cached process, but with client activities.  Mark it so.
19393                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19394                app.adjType = "cch-client-act";
19395            } else if (app.treatLikeActivity) {
19396                // This is a cached process, but somebody wants us to treat it like it has
19397                // an activity, okay!
19398                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19399                app.adjType = "cch-as-act";
19400            }
19401        }
19402
19403        if (adj == ProcessList.SERVICE_ADJ) {
19404            if (doingAll) {
19405                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19406                mNewNumServiceProcs++;
19407                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19408                if (!app.serviceb) {
19409                    // This service isn't far enough down on the LRU list to
19410                    // normally be a B service, but if we are low on RAM and it
19411                    // is large we want to force it down since we would prefer to
19412                    // keep launcher over it.
19413                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19414                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19415                        app.serviceHighRam = true;
19416                        app.serviceb = true;
19417                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19418                    } else {
19419                        mNewNumAServiceProcs++;
19420                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19421                    }
19422                } else {
19423                    app.serviceHighRam = false;
19424                }
19425            }
19426            if (app.serviceb) {
19427                adj = ProcessList.SERVICE_B_ADJ;
19428            }
19429        }
19430
19431        app.curRawAdj = adj;
19432
19433        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19434        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19435        if (adj > app.maxAdj) {
19436            adj = app.maxAdj;
19437            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19438                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19439            }
19440        }
19441
19442        // Do final modification to adj.  Everything we do between here and applying
19443        // the final setAdj must be done in this function, because we will also use
19444        // it when computing the final cached adj later.  Note that we don't need to
19445        // worry about this for max adj above, since max adj will always be used to
19446        // keep it out of the cached vaues.
19447        app.curAdj = app.modifyRawOomAdj(adj);
19448        app.curSchedGroup = schedGroup;
19449        app.curProcState = procState;
19450        app.foregroundActivities = foregroundActivities;
19451
19452        return app.curRawAdj;
19453    }
19454
19455    /**
19456     * Record new PSS sample for a process.
19457     */
19458    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19459            long now) {
19460        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19461                swapPss * 1024);
19462        proc.lastPssTime = now;
19463        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19464        if (DEBUG_PSS) Slog.d(TAG_PSS,
19465                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19466                + " state=" + ProcessList.makeProcStateString(procState));
19467        if (proc.initialIdlePss == 0) {
19468            proc.initialIdlePss = pss;
19469        }
19470        proc.lastPss = pss;
19471        proc.lastSwapPss = swapPss;
19472        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19473            proc.lastCachedPss = pss;
19474            proc.lastCachedSwapPss = swapPss;
19475        }
19476
19477        final SparseArray<Pair<Long, String>> watchUids
19478                = mMemWatchProcesses.getMap().get(proc.processName);
19479        Long check = null;
19480        if (watchUids != null) {
19481            Pair<Long, String> val = watchUids.get(proc.uid);
19482            if (val == null) {
19483                val = watchUids.get(0);
19484            }
19485            if (val != null) {
19486                check = val.first;
19487            }
19488        }
19489        if (check != null) {
19490            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19491                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19492                if (!isDebuggable) {
19493                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19494                        isDebuggable = true;
19495                    }
19496                }
19497                if (isDebuggable) {
19498                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19499                    final ProcessRecord myProc = proc;
19500                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19501                    mMemWatchDumpProcName = proc.processName;
19502                    mMemWatchDumpFile = heapdumpFile.toString();
19503                    mMemWatchDumpPid = proc.pid;
19504                    mMemWatchDumpUid = proc.uid;
19505                    BackgroundThread.getHandler().post(new Runnable() {
19506                        @Override
19507                        public void run() {
19508                            revokeUriPermission(ActivityThread.currentActivityThread()
19509                                            .getApplicationThread(),
19510                                    DumpHeapActivity.JAVA_URI,
19511                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19512                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19513                                    UserHandle.myUserId());
19514                            ParcelFileDescriptor fd = null;
19515                            try {
19516                                heapdumpFile.delete();
19517                                fd = ParcelFileDescriptor.open(heapdumpFile,
19518                                        ParcelFileDescriptor.MODE_CREATE |
19519                                                ParcelFileDescriptor.MODE_TRUNCATE |
19520                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19521                                                ParcelFileDescriptor.MODE_APPEND);
19522                                IApplicationThread thread = myProc.thread;
19523                                if (thread != null) {
19524                                    try {
19525                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19526                                                "Requesting dump heap from "
19527                                                + myProc + " to " + heapdumpFile);
19528                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19529                                    } catch (RemoteException e) {
19530                                    }
19531                                }
19532                            } catch (FileNotFoundException e) {
19533                                e.printStackTrace();
19534                            } finally {
19535                                if (fd != null) {
19536                                    try {
19537                                        fd.close();
19538                                    } catch (IOException e) {
19539                                    }
19540                                }
19541                            }
19542                        }
19543                    });
19544                } else {
19545                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19546                            + ", but debugging not enabled");
19547                }
19548            }
19549        }
19550    }
19551
19552    /**
19553     * Schedule PSS collection of a process.
19554     */
19555    void requestPssLocked(ProcessRecord proc, int procState) {
19556        if (mPendingPssProcesses.contains(proc)) {
19557            return;
19558        }
19559        if (mPendingPssProcesses.size() == 0) {
19560            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19561        }
19562        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19563        proc.pssProcState = procState;
19564        mPendingPssProcesses.add(proc);
19565    }
19566
19567    /**
19568     * Schedule PSS collection of all processes.
19569     */
19570    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19571        if (!always) {
19572            if (now < (mLastFullPssTime +
19573                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19574                return;
19575            }
19576        }
19577        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19578        mLastFullPssTime = now;
19579        mFullPssPending = true;
19580        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19581        mPendingPssProcesses.clear();
19582        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19583            ProcessRecord app = mLruProcesses.get(i);
19584            if (app.thread == null
19585                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19586                continue;
19587            }
19588            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19589                app.pssProcState = app.setProcState;
19590                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19591                        mTestPssMode, isSleeping(), now);
19592                mPendingPssProcesses.add(app);
19593            }
19594        }
19595        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19596    }
19597
19598    public void setTestPssMode(boolean enabled) {
19599        synchronized (this) {
19600            mTestPssMode = enabled;
19601            if (enabled) {
19602                // Whenever we enable the mode, we want to take a snapshot all of current
19603                // process mem use.
19604                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19605            }
19606        }
19607    }
19608
19609    /**
19610     * Ask a given process to GC right now.
19611     */
19612    final void performAppGcLocked(ProcessRecord app) {
19613        try {
19614            app.lastRequestedGc = SystemClock.uptimeMillis();
19615            if (app.thread != null) {
19616                if (app.reportLowMemory) {
19617                    app.reportLowMemory = false;
19618                    app.thread.scheduleLowMemory();
19619                } else {
19620                    app.thread.processInBackground();
19621                }
19622            }
19623        } catch (Exception e) {
19624            // whatever.
19625        }
19626    }
19627
19628    /**
19629     * Returns true if things are idle enough to perform GCs.
19630     */
19631    private final boolean canGcNowLocked() {
19632        boolean processingBroadcasts = false;
19633        for (BroadcastQueue q : mBroadcastQueues) {
19634            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19635                processingBroadcasts = true;
19636            }
19637        }
19638        return !processingBroadcasts
19639                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19640    }
19641
19642    /**
19643     * Perform GCs on all processes that are waiting for it, but only
19644     * if things are idle.
19645     */
19646    final void performAppGcsLocked() {
19647        final int N = mProcessesToGc.size();
19648        if (N <= 0) {
19649            return;
19650        }
19651        if (canGcNowLocked()) {
19652            while (mProcessesToGc.size() > 0) {
19653                ProcessRecord proc = mProcessesToGc.remove(0);
19654                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19655                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19656                            <= SystemClock.uptimeMillis()) {
19657                        // To avoid spamming the system, we will GC processes one
19658                        // at a time, waiting a few seconds between each.
19659                        performAppGcLocked(proc);
19660                        scheduleAppGcsLocked();
19661                        return;
19662                    } else {
19663                        // It hasn't been long enough since we last GCed this
19664                        // process...  put it in the list to wait for its time.
19665                        addProcessToGcListLocked(proc);
19666                        break;
19667                    }
19668                }
19669            }
19670
19671            scheduleAppGcsLocked();
19672        }
19673    }
19674
19675    /**
19676     * If all looks good, perform GCs on all processes waiting for them.
19677     */
19678    final void performAppGcsIfAppropriateLocked() {
19679        if (canGcNowLocked()) {
19680            performAppGcsLocked();
19681            return;
19682        }
19683        // Still not idle, wait some more.
19684        scheduleAppGcsLocked();
19685    }
19686
19687    /**
19688     * Schedule the execution of all pending app GCs.
19689     */
19690    final void scheduleAppGcsLocked() {
19691        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19692
19693        if (mProcessesToGc.size() > 0) {
19694            // Schedule a GC for the time to the next process.
19695            ProcessRecord proc = mProcessesToGc.get(0);
19696            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19697
19698            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19699            long now = SystemClock.uptimeMillis();
19700            if (when < (now+GC_TIMEOUT)) {
19701                when = now + GC_TIMEOUT;
19702            }
19703            mHandler.sendMessageAtTime(msg, when);
19704        }
19705    }
19706
19707    /**
19708     * Add a process to the array of processes waiting to be GCed.  Keeps the
19709     * list in sorted order by the last GC time.  The process can't already be
19710     * on the list.
19711     */
19712    final void addProcessToGcListLocked(ProcessRecord proc) {
19713        boolean added = false;
19714        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19715            if (mProcessesToGc.get(i).lastRequestedGc <
19716                    proc.lastRequestedGc) {
19717                added = true;
19718                mProcessesToGc.add(i+1, proc);
19719                break;
19720            }
19721        }
19722        if (!added) {
19723            mProcessesToGc.add(0, proc);
19724        }
19725    }
19726
19727    /**
19728     * Set up to ask a process to GC itself.  This will either do it
19729     * immediately, or put it on the list of processes to gc the next
19730     * time things are idle.
19731     */
19732    final void scheduleAppGcLocked(ProcessRecord app) {
19733        long now = SystemClock.uptimeMillis();
19734        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19735            return;
19736        }
19737        if (!mProcessesToGc.contains(app)) {
19738            addProcessToGcListLocked(app);
19739            scheduleAppGcsLocked();
19740        }
19741    }
19742
19743    final void checkExcessivePowerUsageLocked(boolean doKills) {
19744        updateCpuStatsNow();
19745
19746        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19747        boolean doWakeKills = doKills;
19748        boolean doCpuKills = doKills;
19749        if (mLastPowerCheckRealtime == 0) {
19750            doWakeKills = false;
19751        }
19752        if (mLastPowerCheckUptime == 0) {
19753            doCpuKills = false;
19754        }
19755        if (stats.isScreenOn()) {
19756            doWakeKills = false;
19757        }
19758        final long curRealtime = SystemClock.elapsedRealtime();
19759        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19760        final long curUptime = SystemClock.uptimeMillis();
19761        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19762        mLastPowerCheckRealtime = curRealtime;
19763        mLastPowerCheckUptime = curUptime;
19764        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19765            doWakeKills = false;
19766        }
19767        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19768            doCpuKills = false;
19769        }
19770        int i = mLruProcesses.size();
19771        while (i > 0) {
19772            i--;
19773            ProcessRecord app = mLruProcesses.get(i);
19774            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19775                long wtime;
19776                synchronized (stats) {
19777                    wtime = stats.getProcessWakeTime(app.info.uid,
19778                            app.pid, curRealtime);
19779                }
19780                long wtimeUsed = wtime - app.lastWakeTime;
19781                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19782                if (DEBUG_POWER) {
19783                    StringBuilder sb = new StringBuilder(128);
19784                    sb.append("Wake for ");
19785                    app.toShortString(sb);
19786                    sb.append(": over ");
19787                    TimeUtils.formatDuration(realtimeSince, sb);
19788                    sb.append(" used ");
19789                    TimeUtils.formatDuration(wtimeUsed, sb);
19790                    sb.append(" (");
19791                    sb.append((wtimeUsed*100)/realtimeSince);
19792                    sb.append("%)");
19793                    Slog.i(TAG_POWER, sb.toString());
19794                    sb.setLength(0);
19795                    sb.append("CPU for ");
19796                    app.toShortString(sb);
19797                    sb.append(": over ");
19798                    TimeUtils.formatDuration(uptimeSince, sb);
19799                    sb.append(" used ");
19800                    TimeUtils.formatDuration(cputimeUsed, sb);
19801                    sb.append(" (");
19802                    sb.append((cputimeUsed*100)/uptimeSince);
19803                    sb.append("%)");
19804                    Slog.i(TAG_POWER, sb.toString());
19805                }
19806                // If a process has held a wake lock for more
19807                // than 50% of the time during this period,
19808                // that sounds bad.  Kill!
19809                if (doWakeKills && realtimeSince > 0
19810                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19811                    synchronized (stats) {
19812                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19813                                realtimeSince, wtimeUsed);
19814                    }
19815                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19816                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19817                } else if (doCpuKills && uptimeSince > 0
19818                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19819                    synchronized (stats) {
19820                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19821                                uptimeSince, cputimeUsed);
19822                    }
19823                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19824                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19825                } else {
19826                    app.lastWakeTime = wtime;
19827                    app.lastCpuTime = app.curCpuTime;
19828                }
19829            }
19830        }
19831    }
19832
19833    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19834            long nowElapsed) {
19835        boolean success = true;
19836
19837        if (app.curRawAdj != app.setRawAdj) {
19838            app.setRawAdj = app.curRawAdj;
19839        }
19840
19841        int changes = 0;
19842
19843        if (app.curAdj != app.setAdj) {
19844            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19845            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19846                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19847                    + app.adjType);
19848            app.setAdj = app.curAdj;
19849        }
19850
19851        if (app.setSchedGroup != app.curSchedGroup) {
19852            app.setSchedGroup = app.curSchedGroup;
19853            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19854                    "Setting sched group of " + app.processName
19855                    + " to " + app.curSchedGroup);
19856            if (app.waitingToKill != null && app.curReceiver == null
19857                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19858                app.kill(app.waitingToKill, true);
19859                success = false;
19860            } else {
19861                int processGroup;
19862                switch (app.curSchedGroup) {
19863                    case ProcessList.SCHED_GROUP_BACKGROUND:
19864                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19865                        break;
19866                    case ProcessList.SCHED_GROUP_TOP_APP:
19867                        processGroup = Process.THREAD_GROUP_TOP_APP;
19868                        break;
19869                    default:
19870                        processGroup = Process.THREAD_GROUP_DEFAULT;
19871                        break;
19872                }
19873                if (true) {
19874                    long oldId = Binder.clearCallingIdentity();
19875                    try {
19876                        Process.setProcessGroup(app.pid, processGroup);
19877                    } catch (Exception e) {
19878                        Slog.w(TAG, "Failed setting process group of " + app.pid
19879                                + " to " + app.curSchedGroup);
19880                        e.printStackTrace();
19881                    } finally {
19882                        Binder.restoreCallingIdentity(oldId);
19883                    }
19884                } else {
19885                    if (app.thread != null) {
19886                        try {
19887                            app.thread.setSchedulingGroup(processGroup);
19888                        } catch (RemoteException e) {
19889                        }
19890                    }
19891                }
19892            }
19893        }
19894        if (app.repForegroundActivities != app.foregroundActivities) {
19895            app.repForegroundActivities = app.foregroundActivities;
19896            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19897        }
19898        if (app.repProcState != app.curProcState) {
19899            app.repProcState = app.curProcState;
19900            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19901            if (app.thread != null) {
19902                try {
19903                    if (false) {
19904                        //RuntimeException h = new RuntimeException("here");
19905                        Slog.i(TAG, "Sending new process state " + app.repProcState
19906                                + " to " + app /*, h*/);
19907                    }
19908                    app.thread.setProcessState(app.repProcState);
19909                } catch (RemoteException e) {
19910                }
19911            }
19912        }
19913        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19914                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19915            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19916                // Experimental code to more aggressively collect pss while
19917                // running test...  the problem is that this tends to collect
19918                // the data right when a process is transitioning between process
19919                // states, which well tend to give noisy data.
19920                long start = SystemClock.uptimeMillis();
19921                long pss = Debug.getPss(app.pid, mTmpLong, null);
19922                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19923                mPendingPssProcesses.remove(app);
19924                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19925                        + " to " + app.curProcState + ": "
19926                        + (SystemClock.uptimeMillis()-start) + "ms");
19927            }
19928            app.lastStateTime = now;
19929            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19930                    mTestPssMode, isSleeping(), now);
19931            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19932                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19933                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19934                    + (app.nextPssTime-now) + ": " + app);
19935        } else {
19936            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19937                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19938                    mTestPssMode)))) {
19939                requestPssLocked(app, app.setProcState);
19940                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19941                        mTestPssMode, isSleeping(), now);
19942            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19943                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19944        }
19945        if (app.setProcState != app.curProcState) {
19946            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19947                    "Proc state change of " + app.processName
19948                            + " to " + app.curProcState);
19949            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19950            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19951            if (setImportant && !curImportant) {
19952                // This app is no longer something we consider important enough to allow to
19953                // use arbitrary amounts of battery power.  Note
19954                // its current wake lock time to later know to kill it if
19955                // it is not behaving well.
19956                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19957                synchronized (stats) {
19958                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19959                            app.pid, nowElapsed);
19960                }
19961                app.lastCpuTime = app.curCpuTime;
19962
19963            }
19964            // Inform UsageStats of important process state change
19965            // Must be called before updating setProcState
19966            maybeUpdateUsageStatsLocked(app, nowElapsed);
19967
19968            app.setProcState = app.curProcState;
19969            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19970                app.notCachedSinceIdle = false;
19971            }
19972            if (!doingAll) {
19973                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19974            } else {
19975                app.procStateChanged = true;
19976            }
19977        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19978                > USAGE_STATS_INTERACTION_INTERVAL) {
19979            // For apps that sit around for a long time in the interactive state, we need
19980            // to report this at least once a day so they don't go idle.
19981            maybeUpdateUsageStatsLocked(app, nowElapsed);
19982        }
19983
19984        if (changes != 0) {
19985            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19986                    "Changes in " + app + ": " + changes);
19987            int i = mPendingProcessChanges.size()-1;
19988            ProcessChangeItem item = null;
19989            while (i >= 0) {
19990                item = mPendingProcessChanges.get(i);
19991                if (item.pid == app.pid) {
19992                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19993                            "Re-using existing item: " + item);
19994                    break;
19995                }
19996                i--;
19997            }
19998            if (i < 0) {
19999                // No existing item in pending changes; need a new one.
20000                final int NA = mAvailProcessChanges.size();
20001                if (NA > 0) {
20002                    item = mAvailProcessChanges.remove(NA-1);
20003                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20004                            "Retrieving available item: " + item);
20005                } else {
20006                    item = new ProcessChangeItem();
20007                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20008                            "Allocating new item: " + item);
20009                }
20010                item.changes = 0;
20011                item.pid = app.pid;
20012                item.uid = app.info.uid;
20013                if (mPendingProcessChanges.size() == 0) {
20014                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20015                            "*** Enqueueing dispatch processes changed!");
20016                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20017                }
20018                mPendingProcessChanges.add(item);
20019            }
20020            item.changes |= changes;
20021            item.processState = app.repProcState;
20022            item.foregroundActivities = app.repForegroundActivities;
20023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20024                    "Item " + Integer.toHexString(System.identityHashCode(item))
20025                    + " " + app.toShortString() + ": changes=" + item.changes
20026                    + " procState=" + item.processState
20027                    + " foreground=" + item.foregroundActivities
20028                    + " type=" + app.adjType + " source=" + app.adjSource
20029                    + " target=" + app.adjTarget);
20030        }
20031
20032        return success;
20033    }
20034
20035    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20036        final UidRecord.ChangeItem pendingChange;
20037        if (uidRec == null || uidRec.pendingChange == null) {
20038            if (mPendingUidChanges.size() == 0) {
20039                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20040                        "*** Enqueueing dispatch uid changed!");
20041                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20042            }
20043            final int NA = mAvailUidChanges.size();
20044            if (NA > 0) {
20045                pendingChange = mAvailUidChanges.remove(NA-1);
20046                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20047                        "Retrieving available item: " + pendingChange);
20048            } else {
20049                pendingChange = new UidRecord.ChangeItem();
20050                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20051                        "Allocating new item: " + pendingChange);
20052            }
20053            if (uidRec != null) {
20054                uidRec.pendingChange = pendingChange;
20055                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20056                    // If this uid is going away, and we haven't yet reported it is gone,
20057                    // then do so now.
20058                    change = UidRecord.CHANGE_GONE_IDLE;
20059                }
20060            } else if (uid < 0) {
20061                throw new IllegalArgumentException("No UidRecord or uid");
20062            }
20063            pendingChange.uidRecord = uidRec;
20064            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20065            mPendingUidChanges.add(pendingChange);
20066        } else {
20067            pendingChange = uidRec.pendingChange;
20068            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20069                change = UidRecord.CHANGE_GONE_IDLE;
20070            }
20071        }
20072        pendingChange.change = change;
20073        pendingChange.processState = uidRec != null
20074                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20075    }
20076
20077    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20078            String authority) {
20079        if (app == null) return;
20080        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20081            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20082            if (userState == null) return;
20083            final long now = SystemClock.elapsedRealtime();
20084            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20085            if (lastReported == null || lastReported < now - 60 * 1000L) {
20086                mUsageStatsService.reportContentProviderUsage(
20087                        authority, providerPkgName, app.userId);
20088                userState.mProviderLastReportedFg.put(authority, now);
20089            }
20090        }
20091    }
20092
20093    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20094        if (DEBUG_USAGE_STATS) {
20095            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20096                    + "] state changes: old = " + app.setProcState + ", new = "
20097                    + app.curProcState);
20098        }
20099        if (mUsageStatsService == null) {
20100            return;
20101        }
20102        boolean isInteraction;
20103        // To avoid some abuse patterns, we are going to be careful about what we consider
20104        // to be an app interaction.  Being the top activity doesn't count while the display
20105        // is sleeping, nor do short foreground services.
20106        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20107            isInteraction = true;
20108            app.fgInteractionTime = 0;
20109        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20110            if (app.fgInteractionTime == 0) {
20111                app.fgInteractionTime = nowElapsed;
20112                isInteraction = false;
20113            } else {
20114                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20115            }
20116        } else {
20117            isInteraction = app.curProcState
20118                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20119            app.fgInteractionTime = 0;
20120        }
20121        if (isInteraction && (!app.reportedInteraction
20122                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20123            app.interactionEventTime = nowElapsed;
20124            String[] packages = app.getPackageList();
20125            if (packages != null) {
20126                for (int i = 0; i < packages.length; i++) {
20127                    mUsageStatsService.reportEvent(packages[i], app.userId,
20128                            UsageEvents.Event.SYSTEM_INTERACTION);
20129                }
20130            }
20131        }
20132        app.reportedInteraction = isInteraction;
20133        if (!isInteraction) {
20134            app.interactionEventTime = 0;
20135        }
20136    }
20137
20138    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20139        if (proc.thread != null) {
20140            if (proc.baseProcessTracker != null) {
20141                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20142            }
20143        }
20144    }
20145
20146    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20147            ProcessRecord TOP_APP, boolean doingAll, long now) {
20148        if (app.thread == null) {
20149            return false;
20150        }
20151
20152        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20153
20154        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20155    }
20156
20157    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20158            boolean oomAdj) {
20159        if (isForeground != proc.foregroundServices) {
20160            proc.foregroundServices = isForeground;
20161            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20162                    proc.info.uid);
20163            if (isForeground) {
20164                if (curProcs == null) {
20165                    curProcs = new ArrayList<ProcessRecord>();
20166                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20167                }
20168                if (!curProcs.contains(proc)) {
20169                    curProcs.add(proc);
20170                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20171                            proc.info.packageName, proc.info.uid);
20172                }
20173            } else {
20174                if (curProcs != null) {
20175                    if (curProcs.remove(proc)) {
20176                        mBatteryStatsService.noteEvent(
20177                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20178                                proc.info.packageName, proc.info.uid);
20179                        if (curProcs.size() <= 0) {
20180                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20181                        }
20182                    }
20183                }
20184            }
20185            if (oomAdj) {
20186                updateOomAdjLocked();
20187            }
20188        }
20189    }
20190
20191    private final ActivityRecord resumedAppLocked() {
20192        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20193        String pkg;
20194        int uid;
20195        if (act != null) {
20196            pkg = act.packageName;
20197            uid = act.info.applicationInfo.uid;
20198        } else {
20199            pkg = null;
20200            uid = -1;
20201        }
20202        // Has the UID or resumed package name changed?
20203        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20204                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20205            if (mCurResumedPackage != null) {
20206                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20207                        mCurResumedPackage, mCurResumedUid);
20208            }
20209            mCurResumedPackage = pkg;
20210            mCurResumedUid = uid;
20211            if (mCurResumedPackage != null) {
20212                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20213                        mCurResumedPackage, mCurResumedUid);
20214            }
20215        }
20216        return act;
20217    }
20218
20219    final boolean updateOomAdjLocked(ProcessRecord app) {
20220        final ActivityRecord TOP_ACT = resumedAppLocked();
20221        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20222        final boolean wasCached = app.cached;
20223
20224        mAdjSeq++;
20225
20226        // This is the desired cached adjusment we want to tell it to use.
20227        // If our app is currently cached, we know it, and that is it.  Otherwise,
20228        // we don't know it yet, and it needs to now be cached we will then
20229        // need to do a complete oom adj.
20230        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20231                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20232        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20233                SystemClock.uptimeMillis());
20234        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20235            // Changed to/from cached state, so apps after it in the LRU
20236            // list may also be changed.
20237            updateOomAdjLocked();
20238        }
20239        return success;
20240    }
20241
20242    final void updateOomAdjLocked() {
20243        final ActivityRecord TOP_ACT = resumedAppLocked();
20244        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20245        final long now = SystemClock.uptimeMillis();
20246        final long nowElapsed = SystemClock.elapsedRealtime();
20247        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20248        final int N = mLruProcesses.size();
20249
20250        if (false) {
20251            RuntimeException e = new RuntimeException();
20252            e.fillInStackTrace();
20253            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20254        }
20255
20256        // Reset state in all uid records.
20257        for (int i=mActiveUids.size()-1; i>=0; i--) {
20258            final UidRecord uidRec = mActiveUids.valueAt(i);
20259            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20260                    "Starting update of " + uidRec);
20261            uidRec.reset();
20262        }
20263
20264        mStackSupervisor.rankTaskLayersIfNeeded();
20265
20266        mAdjSeq++;
20267        mNewNumServiceProcs = 0;
20268        mNewNumAServiceProcs = 0;
20269
20270        final int emptyProcessLimit;
20271        final int cachedProcessLimit;
20272        if (mProcessLimit <= 0) {
20273            emptyProcessLimit = cachedProcessLimit = 0;
20274        } else if (mProcessLimit == 1) {
20275            emptyProcessLimit = 1;
20276            cachedProcessLimit = 0;
20277        } else {
20278            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20279            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20280        }
20281
20282        // Let's determine how many processes we have running vs.
20283        // how many slots we have for background processes; we may want
20284        // to put multiple processes in a slot of there are enough of
20285        // them.
20286        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20287                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20288        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20289        if (numEmptyProcs > cachedProcessLimit) {
20290            // If there are more empty processes than our limit on cached
20291            // processes, then use the cached process limit for the factor.
20292            // This ensures that the really old empty processes get pushed
20293            // down to the bottom, so if we are running low on memory we will
20294            // have a better chance at keeping around more cached processes
20295            // instead of a gazillion empty processes.
20296            numEmptyProcs = cachedProcessLimit;
20297        }
20298        int emptyFactor = numEmptyProcs/numSlots;
20299        if (emptyFactor < 1) emptyFactor = 1;
20300        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20301        if (cachedFactor < 1) cachedFactor = 1;
20302        int stepCached = 0;
20303        int stepEmpty = 0;
20304        int numCached = 0;
20305        int numEmpty = 0;
20306        int numTrimming = 0;
20307
20308        mNumNonCachedProcs = 0;
20309        mNumCachedHiddenProcs = 0;
20310
20311        // First update the OOM adjustment for each of the
20312        // application processes based on their current state.
20313        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20314        int nextCachedAdj = curCachedAdj+1;
20315        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20316        int nextEmptyAdj = curEmptyAdj+2;
20317        for (int i=N-1; i>=0; i--) {
20318            ProcessRecord app = mLruProcesses.get(i);
20319            if (!app.killedByAm && app.thread != null) {
20320                app.procStateChanged = false;
20321                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20322
20323                // If we haven't yet assigned the final cached adj
20324                // to the process, do that now.
20325                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20326                    switch (app.curProcState) {
20327                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20328                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20329                            // This process is a cached process holding activities...
20330                            // assign it the next cached value for that type, and then
20331                            // step that cached level.
20332                            app.curRawAdj = curCachedAdj;
20333                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20334                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20335                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20336                                    + ")");
20337                            if (curCachedAdj != nextCachedAdj) {
20338                                stepCached++;
20339                                if (stepCached >= cachedFactor) {
20340                                    stepCached = 0;
20341                                    curCachedAdj = nextCachedAdj;
20342                                    nextCachedAdj += 2;
20343                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20344                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20345                                    }
20346                                }
20347                            }
20348                            break;
20349                        default:
20350                            // For everything else, assign next empty cached process
20351                            // level and bump that up.  Note that this means that
20352                            // long-running services that have dropped down to the
20353                            // cached level will be treated as empty (since their process
20354                            // state is still as a service), which is what we want.
20355                            app.curRawAdj = curEmptyAdj;
20356                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20357                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20358                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20359                                    + ")");
20360                            if (curEmptyAdj != nextEmptyAdj) {
20361                                stepEmpty++;
20362                                if (stepEmpty >= emptyFactor) {
20363                                    stepEmpty = 0;
20364                                    curEmptyAdj = nextEmptyAdj;
20365                                    nextEmptyAdj += 2;
20366                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20367                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20368                                    }
20369                                }
20370                            }
20371                            break;
20372                    }
20373                }
20374
20375                applyOomAdjLocked(app, true, now, nowElapsed);
20376
20377                // Count the number of process types.
20378                switch (app.curProcState) {
20379                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20380                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20381                        mNumCachedHiddenProcs++;
20382                        numCached++;
20383                        if (numCached > cachedProcessLimit) {
20384                            app.kill("cached #" + numCached, true);
20385                        }
20386                        break;
20387                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20388                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20389                                && app.lastActivityTime < oldTime) {
20390                            app.kill("empty for "
20391                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20392                                    / 1000) + "s", true);
20393                        } else {
20394                            numEmpty++;
20395                            if (numEmpty > emptyProcessLimit) {
20396                                app.kill("empty #" + numEmpty, true);
20397                            }
20398                        }
20399                        break;
20400                    default:
20401                        mNumNonCachedProcs++;
20402                        break;
20403                }
20404
20405                if (app.isolated && app.services.size() <= 0) {
20406                    // If this is an isolated process, and there are no
20407                    // services running in it, then the process is no longer
20408                    // needed.  We agressively kill these because we can by
20409                    // definition not re-use the same process again, and it is
20410                    // good to avoid having whatever code was running in them
20411                    // left sitting around after no longer needed.
20412                    app.kill("isolated not needed", true);
20413                } else {
20414                    // Keeping this process, update its uid.
20415                    final UidRecord uidRec = app.uidRecord;
20416                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20417                        uidRec.curProcState = app.curProcState;
20418                    }
20419                }
20420
20421                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20422                        && !app.killedByAm) {
20423                    numTrimming++;
20424                }
20425            }
20426        }
20427
20428        mNumServiceProcs = mNewNumServiceProcs;
20429
20430        // Now determine the memory trimming level of background processes.
20431        // Unfortunately we need to start at the back of the list to do this
20432        // properly.  We only do this if the number of background apps we
20433        // are managing to keep around is less than half the maximum we desire;
20434        // if we are keeping a good number around, we'll let them use whatever
20435        // memory they want.
20436        final int numCachedAndEmpty = numCached + numEmpty;
20437        int memFactor;
20438        if (numCached <= ProcessList.TRIM_CACHED_APPS
20439                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20440            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20441                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20442            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20443                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20444            } else {
20445                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20446            }
20447        } else {
20448            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20449        }
20450        // We always allow the memory level to go up (better).  We only allow it to go
20451        // down if we are in a state where that is allowed, *and* the total number of processes
20452        // has gone down since last time.
20453        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20454                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20455                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20456        if (memFactor > mLastMemoryLevel) {
20457            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20458                memFactor = mLastMemoryLevel;
20459                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20460            }
20461        }
20462        if (memFactor != mLastMemoryLevel) {
20463            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20464        }
20465        mLastMemoryLevel = memFactor;
20466        mLastNumProcesses = mLruProcesses.size();
20467        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20468        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20469        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20470            if (mLowRamStartTime == 0) {
20471                mLowRamStartTime = now;
20472            }
20473            int step = 0;
20474            int fgTrimLevel;
20475            switch (memFactor) {
20476                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20477                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20478                    break;
20479                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20480                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20481                    break;
20482                default:
20483                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20484                    break;
20485            }
20486            int factor = numTrimming/3;
20487            int minFactor = 2;
20488            if (mHomeProcess != null) minFactor++;
20489            if (mPreviousProcess != null) minFactor++;
20490            if (factor < minFactor) factor = minFactor;
20491            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20492            for (int i=N-1; i>=0; i--) {
20493                ProcessRecord app = mLruProcesses.get(i);
20494                if (allChanged || app.procStateChanged) {
20495                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20496                    app.procStateChanged = false;
20497                }
20498                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20499                        && !app.killedByAm) {
20500                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20501                        try {
20502                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20503                                    "Trimming memory of " + app.processName + " to " + curLevel);
20504                            app.thread.scheduleTrimMemory(curLevel);
20505                        } catch (RemoteException e) {
20506                        }
20507                        if (false) {
20508                            // For now we won't do this; our memory trimming seems
20509                            // to be good enough at this point that destroying
20510                            // activities causes more harm than good.
20511                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20512                                    && app != mHomeProcess && app != mPreviousProcess) {
20513                                // Need to do this on its own message because the stack may not
20514                                // be in a consistent state at this point.
20515                                // For these apps we will also finish their activities
20516                                // to help them free memory.
20517                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20518                            }
20519                        }
20520                    }
20521                    app.trimMemoryLevel = curLevel;
20522                    step++;
20523                    if (step >= factor) {
20524                        step = 0;
20525                        switch (curLevel) {
20526                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20527                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20528                                break;
20529                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20530                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20531                                break;
20532                        }
20533                    }
20534                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20535                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20536                            && app.thread != null) {
20537                        try {
20538                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20539                                    "Trimming memory of heavy-weight " + app.processName
20540                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20541                            app.thread.scheduleTrimMemory(
20542                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20543                        } catch (RemoteException e) {
20544                        }
20545                    }
20546                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20547                } else {
20548                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20549                            || app.systemNoUi) && app.pendingUiClean) {
20550                        // If this application is now in the background and it
20551                        // had done UI, then give it the special trim level to
20552                        // have it free UI resources.
20553                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20554                        if (app.trimMemoryLevel < level && app.thread != null) {
20555                            try {
20556                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20557                                        "Trimming memory of bg-ui " + app.processName
20558                                        + " to " + level);
20559                                app.thread.scheduleTrimMemory(level);
20560                            } catch (RemoteException e) {
20561                            }
20562                        }
20563                        app.pendingUiClean = false;
20564                    }
20565                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20566                        try {
20567                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20568                                    "Trimming memory of fg " + app.processName
20569                                    + " to " + fgTrimLevel);
20570                            app.thread.scheduleTrimMemory(fgTrimLevel);
20571                        } catch (RemoteException e) {
20572                        }
20573                    }
20574                    app.trimMemoryLevel = fgTrimLevel;
20575                }
20576            }
20577        } else {
20578            if (mLowRamStartTime != 0) {
20579                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20580                mLowRamStartTime = 0;
20581            }
20582            for (int i=N-1; i>=0; i--) {
20583                ProcessRecord app = mLruProcesses.get(i);
20584                if (allChanged || app.procStateChanged) {
20585                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20586                    app.procStateChanged = false;
20587                }
20588                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20589                        || app.systemNoUi) && app.pendingUiClean) {
20590                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20591                            && app.thread != null) {
20592                        try {
20593                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20594                                    "Trimming memory of ui hidden " + app.processName
20595                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20596                            app.thread.scheduleTrimMemory(
20597                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20598                        } catch (RemoteException e) {
20599                        }
20600                    }
20601                    app.pendingUiClean = false;
20602                }
20603                app.trimMemoryLevel = 0;
20604            }
20605        }
20606
20607        if (mAlwaysFinishActivities) {
20608            // Need to do this on its own message because the stack may not
20609            // be in a consistent state at this point.
20610            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20611        }
20612
20613        if (allChanged) {
20614            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20615        }
20616
20617        // Update from any uid changes.
20618        for (int i=mActiveUids.size()-1; i>=0; i--) {
20619            final UidRecord uidRec = mActiveUids.valueAt(i);
20620            int uidChange = UidRecord.CHANGE_PROCSTATE;
20621            if (uidRec.setProcState != uidRec.curProcState) {
20622                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20623                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20624                        + " to " + uidRec.curProcState);
20625                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20626                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20627                        uidRec.lastBackgroundTime = nowElapsed;
20628                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20629                            // Note: the background settle time is in elapsed realtime, while
20630                            // the handler time base is uptime.  All this means is that we may
20631                            // stop background uids later than we had intended, but that only
20632                            // happens because the device was sleeping so we are okay anyway.
20633                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20634                        }
20635                    }
20636                } else {
20637                    if (uidRec.idle) {
20638                        uidChange = UidRecord.CHANGE_ACTIVE;
20639                        uidRec.idle = false;
20640                    }
20641                    uidRec.lastBackgroundTime = 0;
20642                }
20643                uidRec.setProcState = uidRec.curProcState;
20644                enqueueUidChangeLocked(uidRec, -1, uidChange);
20645                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20646            }
20647        }
20648
20649        if (mProcessStats.shouldWriteNowLocked(now)) {
20650            mHandler.post(new Runnable() {
20651                @Override public void run() {
20652                    synchronized (ActivityManagerService.this) {
20653                        mProcessStats.writeStateAsyncLocked();
20654                    }
20655                }
20656            });
20657        }
20658
20659        if (DEBUG_OOM_ADJ) {
20660            final long duration = SystemClock.uptimeMillis() - now;
20661            if (false) {
20662                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20663                        new RuntimeException("here").fillInStackTrace());
20664            } else {
20665                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20666            }
20667        }
20668    }
20669
20670    final void idleUids() {
20671        synchronized (this) {
20672            final long nowElapsed = SystemClock.elapsedRealtime();
20673            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20674            long nextTime = 0;
20675            for (int i=mActiveUids.size()-1; i>=0; i--) {
20676                final UidRecord uidRec = mActiveUids.valueAt(i);
20677                final long bgTime = uidRec.lastBackgroundTime;
20678                if (bgTime > 0 && !uidRec.idle) {
20679                    if (bgTime <= maxBgTime) {
20680                        uidRec.idle = true;
20681                        doStopUidLocked(uidRec.uid, uidRec);
20682                    } else {
20683                        if (nextTime == 0 || nextTime > bgTime) {
20684                            nextTime = bgTime;
20685                        }
20686                    }
20687                }
20688            }
20689            if (nextTime > 0) {
20690                mHandler.removeMessages(IDLE_UIDS_MSG);
20691                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20692                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20693            }
20694        }
20695    }
20696
20697    final void runInBackgroundDisabled(int uid) {
20698        synchronized (this) {
20699            UidRecord uidRec = mActiveUids.get(uid);
20700            if (uidRec != null) {
20701                // This uid is actually running...  should it be considered background now?
20702                if (uidRec.idle) {
20703                    doStopUidLocked(uidRec.uid, uidRec);
20704                }
20705            } else {
20706                // This uid isn't actually running...  still send a report about it being "stopped".
20707                doStopUidLocked(uid, null);
20708            }
20709        }
20710    }
20711
20712    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20713        mServices.stopInBackgroundLocked(uid);
20714        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20715    }
20716
20717    final void trimApplications() {
20718        synchronized (this) {
20719            int i;
20720
20721            // First remove any unused application processes whose package
20722            // has been removed.
20723            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20724                final ProcessRecord app = mRemovedProcesses.get(i);
20725                if (app.activities.size() == 0
20726                        && app.curReceiver == null && app.services.size() == 0) {
20727                    Slog.i(
20728                        TAG, "Exiting empty application process "
20729                        + app.toShortString() + " ("
20730                        + (app.thread != null ? app.thread.asBinder() : null)
20731                        + ")\n");
20732                    if (app.pid > 0 && app.pid != MY_PID) {
20733                        app.kill("empty", false);
20734                    } else {
20735                        try {
20736                            app.thread.scheduleExit();
20737                        } catch (Exception e) {
20738                            // Ignore exceptions.
20739                        }
20740                    }
20741                    cleanUpApplicationRecordLocked(app, false, true, -1);
20742                    mRemovedProcesses.remove(i);
20743
20744                    if (app.persistent) {
20745                        addAppLocked(app.info, false, null /* ABI override */);
20746                    }
20747                }
20748            }
20749
20750            // Now update the oom adj for all processes.
20751            updateOomAdjLocked();
20752        }
20753    }
20754
20755    /** This method sends the specified signal to each of the persistent apps */
20756    public void signalPersistentProcesses(int sig) throws RemoteException {
20757        if (sig != Process.SIGNAL_USR1) {
20758            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20759        }
20760
20761        synchronized (this) {
20762            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20763                    != PackageManager.PERMISSION_GRANTED) {
20764                throw new SecurityException("Requires permission "
20765                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20766            }
20767
20768            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20769                ProcessRecord r = mLruProcesses.get(i);
20770                if (r.thread != null && r.persistent) {
20771                    Process.sendSignal(r.pid, sig);
20772                }
20773            }
20774        }
20775    }
20776
20777    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20778        if (proc == null || proc == mProfileProc) {
20779            proc = mProfileProc;
20780            profileType = mProfileType;
20781            clearProfilerLocked();
20782        }
20783        if (proc == null) {
20784            return;
20785        }
20786        try {
20787            proc.thread.profilerControl(false, null, profileType);
20788        } catch (RemoteException e) {
20789            throw new IllegalStateException("Process disappeared");
20790        }
20791    }
20792
20793    private void clearProfilerLocked() {
20794        if (mProfileFd != null) {
20795            try {
20796                mProfileFd.close();
20797            } catch (IOException e) {
20798            }
20799        }
20800        mProfileApp = null;
20801        mProfileProc = null;
20802        mProfileFile = null;
20803        mProfileType = 0;
20804        mAutoStopProfiler = false;
20805        mSamplingInterval = 0;
20806    }
20807
20808    public boolean profileControl(String process, int userId, boolean start,
20809            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20810
20811        try {
20812            synchronized (this) {
20813                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20814                // its own permission.
20815                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20816                        != PackageManager.PERMISSION_GRANTED) {
20817                    throw new SecurityException("Requires permission "
20818                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20819                }
20820
20821                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20822                    throw new IllegalArgumentException("null profile info or fd");
20823                }
20824
20825                ProcessRecord proc = null;
20826                if (process != null) {
20827                    proc = findProcessLocked(process, userId, "profileControl");
20828                }
20829
20830                if (start && (proc == null || proc.thread == null)) {
20831                    throw new IllegalArgumentException("Unknown process: " + process);
20832                }
20833
20834                if (start) {
20835                    stopProfilerLocked(null, 0);
20836                    setProfileApp(proc.info, proc.processName, profilerInfo);
20837                    mProfileProc = proc;
20838                    mProfileType = profileType;
20839                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20840                    try {
20841                        fd = fd.dup();
20842                    } catch (IOException e) {
20843                        fd = null;
20844                    }
20845                    profilerInfo.profileFd = fd;
20846                    proc.thread.profilerControl(start, profilerInfo, profileType);
20847                    fd = null;
20848                    mProfileFd = null;
20849                } else {
20850                    stopProfilerLocked(proc, profileType);
20851                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20852                        try {
20853                            profilerInfo.profileFd.close();
20854                        } catch (IOException e) {
20855                        }
20856                    }
20857                }
20858
20859                return true;
20860            }
20861        } catch (RemoteException e) {
20862            throw new IllegalStateException("Process disappeared");
20863        } finally {
20864            if (profilerInfo != null && profilerInfo.profileFd != null) {
20865                try {
20866                    profilerInfo.profileFd.close();
20867                } catch (IOException e) {
20868                }
20869            }
20870        }
20871    }
20872
20873    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20874        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20875                userId, true, ALLOW_FULL_ONLY, callName, null);
20876        ProcessRecord proc = null;
20877        try {
20878            int pid = Integer.parseInt(process);
20879            synchronized (mPidsSelfLocked) {
20880                proc = mPidsSelfLocked.get(pid);
20881            }
20882        } catch (NumberFormatException e) {
20883        }
20884
20885        if (proc == null) {
20886            ArrayMap<String, SparseArray<ProcessRecord>> all
20887                    = mProcessNames.getMap();
20888            SparseArray<ProcessRecord> procs = all.get(process);
20889            if (procs != null && procs.size() > 0) {
20890                proc = procs.valueAt(0);
20891                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20892                    for (int i=1; i<procs.size(); i++) {
20893                        ProcessRecord thisProc = procs.valueAt(i);
20894                        if (thisProc.userId == userId) {
20895                            proc = thisProc;
20896                            break;
20897                        }
20898                    }
20899                }
20900            }
20901        }
20902
20903        return proc;
20904    }
20905
20906    public boolean dumpHeap(String process, int userId, boolean managed,
20907            String path, ParcelFileDescriptor fd) throws RemoteException {
20908
20909        try {
20910            synchronized (this) {
20911                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20912                // its own permission (same as profileControl).
20913                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20914                        != PackageManager.PERMISSION_GRANTED) {
20915                    throw new SecurityException("Requires permission "
20916                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20917                }
20918
20919                if (fd == null) {
20920                    throw new IllegalArgumentException("null fd");
20921                }
20922
20923                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20924                if (proc == null || proc.thread == null) {
20925                    throw new IllegalArgumentException("Unknown process: " + process);
20926                }
20927
20928                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20929                if (!isDebuggable) {
20930                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20931                        throw new SecurityException("Process not debuggable: " + proc);
20932                    }
20933                }
20934
20935                proc.thread.dumpHeap(managed, path, fd);
20936                fd = null;
20937                return true;
20938            }
20939        } catch (RemoteException e) {
20940            throw new IllegalStateException("Process disappeared");
20941        } finally {
20942            if (fd != null) {
20943                try {
20944                    fd.close();
20945                } catch (IOException e) {
20946                }
20947            }
20948        }
20949    }
20950
20951    @Override
20952    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20953            String reportPackage) {
20954        if (processName != null) {
20955            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20956                    "setDumpHeapDebugLimit()");
20957        } else {
20958            synchronized (mPidsSelfLocked) {
20959                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20960                if (proc == null) {
20961                    throw new SecurityException("No process found for calling pid "
20962                            + Binder.getCallingPid());
20963                }
20964                if (!Build.IS_DEBUGGABLE
20965                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20966                    throw new SecurityException("Not running a debuggable build");
20967                }
20968                processName = proc.processName;
20969                uid = proc.uid;
20970                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20971                    throw new SecurityException("Package " + reportPackage + " is not running in "
20972                            + proc);
20973                }
20974            }
20975        }
20976        synchronized (this) {
20977            if (maxMemSize > 0) {
20978                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20979            } else {
20980                if (uid != 0) {
20981                    mMemWatchProcesses.remove(processName, uid);
20982                } else {
20983                    mMemWatchProcesses.getMap().remove(processName);
20984                }
20985            }
20986        }
20987    }
20988
20989    @Override
20990    public void dumpHeapFinished(String path) {
20991        synchronized (this) {
20992            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20993                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20994                        + " does not match last pid " + mMemWatchDumpPid);
20995                return;
20996            }
20997            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20998                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20999                        + " does not match last path " + mMemWatchDumpFile);
21000                return;
21001            }
21002            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21003            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21004        }
21005    }
21006
21007    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21008    public void monitor() {
21009        synchronized (this) { }
21010    }
21011
21012    void onCoreSettingsChange(Bundle settings) {
21013        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21014            ProcessRecord processRecord = mLruProcesses.get(i);
21015            try {
21016                if (processRecord.thread != null) {
21017                    processRecord.thread.setCoreSettings(settings);
21018                }
21019            } catch (RemoteException re) {
21020                /* ignore */
21021            }
21022        }
21023    }
21024
21025    // Multi-user methods
21026
21027    /**
21028     * Start user, if its not already running, but don't bring it to foreground.
21029     */
21030    @Override
21031    public boolean startUserInBackground(final int userId) {
21032        return mUserController.startUser(userId, /* foreground */ false);
21033    }
21034
21035    @Override
21036    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21037        return mUserController.unlockUser(userId, token, secret, listener);
21038    }
21039
21040    @Override
21041    public boolean switchUser(final int targetUserId) {
21042        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21043        UserInfo currentUserInfo;
21044        UserInfo targetUserInfo;
21045        synchronized (this) {
21046            int currentUserId = mUserController.getCurrentUserIdLocked();
21047            currentUserInfo = mUserController.getUserInfo(currentUserId);
21048            targetUserInfo = mUserController.getUserInfo(targetUserId);
21049            if (targetUserInfo == null) {
21050                Slog.w(TAG, "No user info for user #" + targetUserId);
21051                return false;
21052            }
21053            if (!targetUserInfo.supportsSwitchTo()) {
21054                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21055                return false;
21056            }
21057            if (targetUserInfo.isManagedProfile()) {
21058                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21059                return false;
21060            }
21061            mUserController.setTargetUserIdLocked(targetUserId);
21062        }
21063        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21064        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21065        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21066        return true;
21067    }
21068
21069    void scheduleStartProfilesLocked() {
21070        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21071            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21072                    DateUtils.SECOND_IN_MILLIS);
21073        }
21074    }
21075
21076    @Override
21077    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21078        return mUserController.stopUser(userId, force, callback);
21079    }
21080
21081    @Override
21082    public UserInfo getCurrentUser() {
21083        return mUserController.getCurrentUser();
21084    }
21085
21086    @Override
21087    public boolean isUserRunning(int userId, int flags) {
21088        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21089                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21090            String msg = "Permission Denial: isUserRunning() from pid="
21091                    + Binder.getCallingPid()
21092                    + ", uid=" + Binder.getCallingUid()
21093                    + " requires " + INTERACT_ACROSS_USERS;
21094            Slog.w(TAG, msg);
21095            throw new SecurityException(msg);
21096        }
21097        synchronized (this) {
21098            return mUserController.isUserRunningLocked(userId, flags);
21099        }
21100    }
21101
21102    @Override
21103    public int[] getRunningUserIds() {
21104        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21105                != PackageManager.PERMISSION_GRANTED) {
21106            String msg = "Permission Denial: isUserRunning() from pid="
21107                    + Binder.getCallingPid()
21108                    + ", uid=" + Binder.getCallingUid()
21109                    + " requires " + INTERACT_ACROSS_USERS;
21110            Slog.w(TAG, msg);
21111            throw new SecurityException(msg);
21112        }
21113        synchronized (this) {
21114            return mUserController.getStartedUserArrayLocked();
21115        }
21116    }
21117
21118    @Override
21119    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21120        mUserController.registerUserSwitchObserver(observer);
21121    }
21122
21123    @Override
21124    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21125        mUserController.unregisterUserSwitchObserver(observer);
21126    }
21127
21128    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21129        if (info == null) return null;
21130        ApplicationInfo newInfo = new ApplicationInfo(info);
21131        newInfo.initForUser(userId);
21132        return newInfo;
21133    }
21134
21135    public boolean isUserStopped(int userId) {
21136        synchronized (this) {
21137            return mUserController.getStartedUserStateLocked(userId) == null;
21138        }
21139    }
21140
21141    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21142        if (aInfo == null
21143                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21144            return aInfo;
21145        }
21146
21147        ActivityInfo info = new ActivityInfo(aInfo);
21148        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21149        return info;
21150    }
21151
21152    private boolean processSanityChecksLocked(ProcessRecord process) {
21153        if (process == null || process.thread == null) {
21154            return false;
21155        }
21156
21157        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21158        if (!isDebuggable) {
21159            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21160                return false;
21161            }
21162        }
21163
21164        return true;
21165    }
21166
21167    public boolean startBinderTracking() throws RemoteException {
21168        synchronized (this) {
21169            mBinderTransactionTrackingEnabled = true;
21170            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21171            // permission (same as profileControl).
21172            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21173                    != PackageManager.PERMISSION_GRANTED) {
21174                throw new SecurityException("Requires permission "
21175                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21176            }
21177
21178            for (int i = 0; i < mLruProcesses.size(); i++) {
21179                ProcessRecord process = mLruProcesses.get(i);
21180                if (!processSanityChecksLocked(process)) {
21181                    continue;
21182                }
21183                try {
21184                    process.thread.startBinderTracking();
21185                } catch (RemoteException e) {
21186                    Log.v(TAG, "Process disappared");
21187                }
21188            }
21189            return true;
21190        }
21191    }
21192
21193    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21194        try {
21195            synchronized (this) {
21196                mBinderTransactionTrackingEnabled = false;
21197                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21198                // permission (same as profileControl).
21199                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21200                        != PackageManager.PERMISSION_GRANTED) {
21201                    throw new SecurityException("Requires permission "
21202                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21203                }
21204
21205                if (fd == null) {
21206                    throw new IllegalArgumentException("null fd");
21207                }
21208
21209                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21210                pw.println("Binder transaction traces for all processes.\n");
21211                for (ProcessRecord process : mLruProcesses) {
21212                    if (!processSanityChecksLocked(process)) {
21213                        continue;
21214                    }
21215
21216                    pw.println("Traces for process: " + process.processName);
21217                    pw.flush();
21218                    try {
21219                        TransferPipe tp = new TransferPipe();
21220                        try {
21221                            process.thread.stopBinderTrackingAndDump(
21222                                    tp.getWriteFd().getFileDescriptor());
21223                            tp.go(fd.getFileDescriptor());
21224                        } finally {
21225                            tp.kill();
21226                        }
21227                    } catch (IOException e) {
21228                        pw.println("Failure while dumping IPC traces from " + process +
21229                                ".  Exception: " + e);
21230                        pw.flush();
21231                    } catch (RemoteException e) {
21232                        pw.println("Got a RemoteException while dumping IPC traces from " +
21233                                process + ".  Exception: " + e);
21234                        pw.flush();
21235                    }
21236                }
21237                fd = null;
21238                return true;
21239            }
21240        } finally {
21241            if (fd != null) {
21242                try {
21243                    fd.close();
21244                } catch (IOException e) {
21245                }
21246            }
21247        }
21248    }
21249
21250    private final class LocalService extends ActivityManagerInternal {
21251        @Override
21252        public void onWakefulnessChanged(int wakefulness) {
21253            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21254        }
21255
21256        @Override
21257        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21258                String processName, String abiOverride, int uid, Runnable crashHandler) {
21259            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21260                    processName, abiOverride, uid, crashHandler);
21261        }
21262
21263        @Override
21264        public SleepToken acquireSleepToken(String tag) {
21265            Preconditions.checkNotNull(tag);
21266
21267            synchronized (ActivityManagerService.this) {
21268                SleepTokenImpl token = new SleepTokenImpl(tag);
21269                mSleepTokens.add(token);
21270                updateSleepIfNeededLocked();
21271                applyVrModeIfNeededLocked(mFocusedActivity, false);
21272                return token;
21273            }
21274        }
21275
21276        @Override
21277        public ComponentName getHomeActivityForUser(int userId) {
21278            synchronized (ActivityManagerService.this) {
21279                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21280                return homeActivity == null ? null : homeActivity.realActivity;
21281            }
21282        }
21283
21284        @Override
21285        public void onUserRemoved(int userId) {
21286            synchronized (ActivityManagerService.this) {
21287                ActivityManagerService.this.onUserStoppedLocked(userId);
21288            }
21289        }
21290
21291        @Override
21292        public void onLocalVoiceInteractionStarted(IBinder activity,
21293                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21294            synchronized (ActivityManagerService.this) {
21295                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21296                        voiceSession, voiceInteractor);
21297            }
21298        }
21299
21300        @Override
21301        public void notifyStartingWindowDrawn() {
21302            synchronized (ActivityManagerService.this) {
21303                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21304            }
21305        }
21306
21307        @Override
21308        public void notifyAppTransitionStarting(int reason) {
21309            synchronized (ActivityManagerService.this) {
21310                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21311            }
21312        }
21313
21314        @Override
21315        public void notifyAppTransitionFinished() {
21316            synchronized (ActivityManagerService.this) {
21317                mStackSupervisor.notifyAppTransitionDone();
21318            }
21319        }
21320
21321        @Override
21322        public void notifyAppTransitionCancelled() {
21323            synchronized (ActivityManagerService.this) {
21324                mStackSupervisor.notifyAppTransitionDone();
21325            }
21326        }
21327
21328        @Override
21329        public List<IBinder> getTopVisibleActivities() {
21330            synchronized (ActivityManagerService.this) {
21331                return mStackSupervisor.getTopVisibleActivities();
21332            }
21333        }
21334
21335        @Override
21336        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21337            synchronized (ActivityManagerService.this) {
21338                mStackSupervisor.setDockedStackMinimized(minimized);
21339            }
21340        }
21341
21342        @Override
21343        public void killForegroundAppsForUser(int userHandle) {
21344            synchronized (ActivityManagerService.this) {
21345                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21346                final int NP = mProcessNames.getMap().size();
21347                for (int ip = 0; ip < NP; ip++) {
21348                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21349                    final int NA = apps.size();
21350                    for (int ia = 0; ia < NA; ia++) {
21351                        final ProcessRecord app = apps.valueAt(ia);
21352                        if (app.persistent) {
21353                            // We don't kill persistent processes.
21354                            continue;
21355                        }
21356                        if (app.removed) {
21357                            procs.add(app);
21358                        } else if (app.userId == userHandle && app.foregroundActivities) {
21359                            app.removed = true;
21360                            procs.add(app);
21361                        }
21362                    }
21363                }
21364
21365                final int N = procs.size();
21366                for (int i = 0; i < N; i++) {
21367                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21368                }
21369            }
21370        }
21371
21372        @Override
21373        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21374            if (!(target instanceof PendingIntentRecord)) {
21375                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21376                return;
21377            }
21378            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21379        }
21380    }
21381
21382    private final class SleepTokenImpl extends SleepToken {
21383        private final String mTag;
21384        private final long mAcquireTime;
21385
21386        public SleepTokenImpl(String tag) {
21387            mTag = tag;
21388            mAcquireTime = SystemClock.uptimeMillis();
21389        }
21390
21391        @Override
21392        public void release() {
21393            synchronized (ActivityManagerService.this) {
21394                if (mSleepTokens.remove(this)) {
21395                    updateSleepIfNeededLocked();
21396                }
21397            }
21398        }
21399
21400        @Override
21401        public String toString() {
21402            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21403        }
21404    }
21405
21406    /**
21407     * An implementation of IAppTask, that allows an app to manage its own tasks via
21408     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21409     * only the process that calls getAppTasks() can call the AppTask methods.
21410     */
21411    class AppTaskImpl extends IAppTask.Stub {
21412        private int mTaskId;
21413        private int mCallingUid;
21414
21415        public AppTaskImpl(int taskId, int callingUid) {
21416            mTaskId = taskId;
21417            mCallingUid = callingUid;
21418        }
21419
21420        private void checkCaller() {
21421            if (mCallingUid != Binder.getCallingUid()) {
21422                throw new SecurityException("Caller " + mCallingUid
21423                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21424            }
21425        }
21426
21427        @Override
21428        public void finishAndRemoveTask() {
21429            checkCaller();
21430
21431            synchronized (ActivityManagerService.this) {
21432                long origId = Binder.clearCallingIdentity();
21433                try {
21434                    // We remove the task from recents to preserve backwards
21435                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21436                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21437                    }
21438                } finally {
21439                    Binder.restoreCallingIdentity(origId);
21440                }
21441            }
21442        }
21443
21444        @Override
21445        public ActivityManager.RecentTaskInfo getTaskInfo() {
21446            checkCaller();
21447
21448            synchronized (ActivityManagerService.this) {
21449                long origId = Binder.clearCallingIdentity();
21450                try {
21451                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21452                    if (tr == null) {
21453                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21454                    }
21455                    return createRecentTaskInfoFromTaskRecord(tr);
21456                } finally {
21457                    Binder.restoreCallingIdentity(origId);
21458                }
21459            }
21460        }
21461
21462        @Override
21463        public void moveToFront() {
21464            checkCaller();
21465            // Will bring task to front if it already has a root activity.
21466            final long origId = Binder.clearCallingIdentity();
21467            try {
21468                synchronized (this) {
21469                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21470                }
21471            } finally {
21472                Binder.restoreCallingIdentity(origId);
21473            }
21474        }
21475
21476        @Override
21477        public int startActivity(IBinder whoThread, String callingPackage,
21478                Intent intent, String resolvedType, Bundle bOptions) {
21479            checkCaller();
21480
21481            int callingUser = UserHandle.getCallingUserId();
21482            TaskRecord tr;
21483            IApplicationThread appThread;
21484            synchronized (ActivityManagerService.this) {
21485                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21486                if (tr == null) {
21487                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21488                }
21489                appThread = ApplicationThreadNative.asInterface(whoThread);
21490                if (appThread == null) {
21491                    throw new IllegalArgumentException("Bad app thread " + appThread);
21492                }
21493            }
21494            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21495                    resolvedType, null, null, null, null, 0, 0, null, null,
21496                    null, bOptions, false, callingUser, null, tr);
21497        }
21498
21499        @Override
21500        public void setExcludeFromRecents(boolean exclude) {
21501            checkCaller();
21502
21503            synchronized (ActivityManagerService.this) {
21504                long origId = Binder.clearCallingIdentity();
21505                try {
21506                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21507                    if (tr == null) {
21508                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21509                    }
21510                    Intent intent = tr.getBaseIntent();
21511                    if (exclude) {
21512                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21513                    } else {
21514                        intent.setFlags(intent.getFlags()
21515                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21516                    }
21517                } finally {
21518                    Binder.restoreCallingIdentity(origId);
21519                }
21520            }
21521        }
21522    }
21523
21524    /**
21525     * Kill processes for the user with id userId and that depend on the package named packageName
21526     */
21527    @Override
21528    public void killPackageDependents(String packageName, int userId) {
21529        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21530        if (packageName == null) {
21531            throw new NullPointerException(
21532                    "Cannot kill the dependents of a package without its name.");
21533        }
21534
21535        long callingId = Binder.clearCallingIdentity();
21536        IPackageManager pm = AppGlobals.getPackageManager();
21537        int pkgUid = -1;
21538        try {
21539            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21540        } catch (RemoteException e) {
21541        }
21542        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21543            throw new IllegalArgumentException(
21544                    "Cannot kill dependents of non-existing package " + packageName);
21545        }
21546        try {
21547            synchronized(this) {
21548                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21549                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21550                        "dep: " + packageName);
21551            }
21552        } finally {
21553            Binder.restoreCallingIdentity(callingId);
21554        }
21555    }
21556}
21557