ActivityManagerService.java revision 4670d3efe26e500b4c06b2e436bff11e7b9200ae
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.LocaleList;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PersistableBundle;
179import android.os.PowerManager;
180import android.os.PowerManagerInternal;
181import android.os.Process;
182import android.os.RemoteCallbackList;
183import android.os.RemoteException;
184import android.os.ResultReceiver;
185import android.os.ServiceManager;
186import android.os.StrictMode;
187import android.os.SystemClock;
188import android.os.SystemProperties;
189import android.os.Trace;
190import android.os.TransactionTooLargeException;
191import android.os.UpdateLock;
192import android.os.UserHandle;
193import android.os.UserManager;
194import android.os.WorkSource;
195import android.os.storage.IMountService;
196import android.os.storage.MountServiceInternal;
197import android.os.storage.StorageManager;
198import android.provider.Settings;
199import android.service.voice.IVoiceInteractionSession;
200import android.service.voice.VoiceInteractionManagerInternal;
201import android.service.voice.VoiceInteractionSession;
202import android.text.format.DateUtils;
203import android.text.format.Time;
204import android.text.style.SuggestionSpan;
205import android.util.ArrayMap;
206import android.util.ArraySet;
207import android.util.AtomicFile;
208import android.util.DebugUtils;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
267import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
268import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
269import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270import static android.content.pm.PackageManager.GET_PROVIDERS;
271import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
278import static android.provider.Settings.Global.DEBUG_APP;
279import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
281import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
282import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
283import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
284import static android.provider.Settings.System.FONT_SCALE;
285import static com.android.internal.util.XmlUtils.readBooleanAttribute;
286import static com.android.internal.util.XmlUtils.readIntAttribute;
287import static com.android.internal.util.XmlUtils.readLongAttribute;
288import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
289import static com.android.internal.util.XmlUtils.writeIntAttribute;
290import static com.android.internal.util.XmlUtils.writeLongAttribute;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
347import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
348import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
349import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
350import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
351import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
352import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
353import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
354import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
355import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
356import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
357import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
358import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
359import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
360import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
362import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
363import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
364import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
365import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
366import static org.xmlpull.v1.XmlPullParser.START_TAG;
367
368public final class ActivityManagerService extends ActivityManagerNative
369        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
370
371    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
372    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
373    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
374    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
375    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
376    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
377    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
378    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
379    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
380    private static final String TAG_LRU = TAG + POSTFIX_LRU;
381    private static final String TAG_MU = TAG + POSTFIX_MU;
382    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
383    private static final String TAG_POWER = TAG + POSTFIX_POWER;
384    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
385    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
386    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
387    private static final String TAG_PSS = TAG + POSTFIX_PSS;
388    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
389    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
390    private static final String TAG_STACK = TAG + POSTFIX_STACK;
391    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
392    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
393    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
394    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
395    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396
397    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
398    // here so that while the job scheduler can depend on AMS, the other way around
399    // need not be the case.
400    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
401
402    /** Control over CPU and battery monitoring */
403    // write battery stats every 30 minutes.
404    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
405    static final boolean MONITOR_CPU_USAGE = true;
406    // don't sample cpu less than every 5 seconds.
407    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
408    // wait possibly forever for next cpu sample.
409    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
410    static final boolean MONITOR_THREAD_CPU_USAGE = false;
411
412    // The flags that are set for all calls we make to the package manager.
413    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
414
415    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
416
417    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
418
419    // Amount of time after a call to stopAppSwitches() during which we will
420    // prevent further untrusted switches from happening.
421    static final long APP_SWITCH_DELAY_TIME = 5*1000;
422
423    // How long we wait for a launched process to attach to the activity manager
424    // before we decide it's never going to come up for real.
425    static final int PROC_START_TIMEOUT = 10*1000;
426    // How long we wait for an attached process to publish its content providers
427    // before we decide it must be hung.
428    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
429
430    // How long we will retain processes hosting content providers in the "last activity"
431    // state before allowing them to drop down to the regular cached LRU list.  This is
432    // to avoid thrashing of provider processes under low memory situations.
433    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
434
435    // How long we wait for a launched process to attach to the activity manager
436    // before we decide it's never going to come up for real, when the process was
437    // started with a wrapper for instrumentation (such as Valgrind) because it
438    // could take much longer than usual.
439    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
440
441    // How long to wait after going idle before forcing apps to GC.
442    static final int GC_TIMEOUT = 5*1000;
443
444    // The minimum amount of time between successive GC requests for a process.
445    static final int GC_MIN_INTERVAL = 60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process.
448    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
449
450    // The minimum amount of time between successive PSS requests for a process
451    // when the request is due to the memory state being lowered.
452    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
453
454    // The rate at which we check for apps using excessive power -- 15 mins.
455    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on wake locks to start killing things.
459    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on CPU usage to start killing things.
463    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // How long we allow a receiver to run before giving up on it.
466    static final int BROADCAST_FG_TIMEOUT = 10*1000;
467    static final int BROADCAST_BG_TIMEOUT = 60*1000;
468
469    // How long we wait until we timeout on key dispatching.
470    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
471
472    // How long we wait until we timeout on key dispatching during instrumentation.
473    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
474
475    // This is the amount of time an app needs to be running a foreground service before
476    // we will consider it to be doing interaction for usage stats.
477    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
478
479    // Maximum amount of time we will allow to elapse before re-reporting usage stats
480    // interaction with foreground processes.
481    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
482
483    // This is the amount of time we allow an app to settle after it goes into the background,
484    // before we start restricting what it can do.
485    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
486
487    // How long to wait in getAssistContextExtras for the activity and foreground services
488    // to respond with the result.
489    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
490
491    // How long top wait when going through the modern assist (which doesn't need to block
492    // on getting this result before starting to launch its UI).
493    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
494
495    // Maximum number of persisted Uri grants a package is allowed
496    static final int MAX_PERSISTED_URI_GRANTS = 128;
497
498    static final int MY_PID = Process.myPid();
499
500    static final String[] EMPTY_STRING_ARRAY = new String[0];
501
502    // How many bytes to write into the dropbox log before truncating
503    static final int DROPBOX_MAX_SIZE = 256 * 1024;
504
505    // Access modes for handleIncomingUser.
506    static final int ALLOW_NON_FULL = 0;
507    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
508    static final int ALLOW_FULL_ONLY = 2;
509
510    // Delay in notifying task stack change listeners (in millis)
511    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
512
513    // Necessary ApplicationInfo flags to mark an app as persistent
514    private static final int PERSISTENT_MASK =
515            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
516
517    // Intent sent when remote bugreport collection has been completed
518    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
519            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
520
521    // Delay to disable app launch boost
522    static final int APP_BOOST_MESSAGE_DELAY = 3000;
523    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
524    static final int APP_BOOST_TIMEOUT = 2500;
525
526    // Used to indicate that a task is removed it should also be removed from recents.
527    private static final boolean REMOVE_FROM_RECENTS = true;
528    // Used to indicate that an app transition should be animated.
529    static final boolean ANIMATE = true;
530
531    // Determines whether to take full screen screenshots
532    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
533    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
534
535    private static native int nativeMigrateToBoost();
536    private static native int nativeMigrateFromBoost();
537    private boolean mIsBoosted = false;
538    private long mBoostStartTime = 0;
539
540    /** All system services */
541    SystemServiceManager mSystemServiceManager;
542
543    private Installer mInstaller;
544
545    /** Run all ActivityStacks through this */
546    final ActivityStackSupervisor mStackSupervisor;
547
548    final ActivityStarter mActivityStarter;
549
550    /** Task stack change listeners. */
551    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
552            new RemoteCallbackList<ITaskStackListener>();
553
554    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
555
556    public IntentFirewall mIntentFirewall;
557
558    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
559    // default actuion automatically.  Important for devices without direct input
560    // devices.
561    private boolean mShowDialogs = true;
562    private boolean mInVrMode = false;
563
564    BroadcastQueue mFgBroadcastQueue;
565    BroadcastQueue mBgBroadcastQueue;
566    // Convenient for easy iteration over the queues. Foreground is first
567    // so that dispatch of foreground broadcasts gets precedence.
568    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
569
570    BroadcastQueue broadcastQueueForIntent(Intent intent) {
571        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
572        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
573                "Broadcast intent " + intent + " on "
574                + (isFg ? "foreground" : "background") + " queue");
575        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
576    }
577
578    /**
579     * Activity we have told the window manager to have key focus.
580     */
581    ActivityRecord mFocusedActivity = null;
582
583    /**
584     * User id of the last activity mFocusedActivity was set to.
585     */
586    private int mLastFocusedUserId;
587
588    /**
589     * If non-null, we are tracking the time the user spends in the currently focused app.
590     */
591    private AppTimeTracker mCurAppTimeTracker;
592
593    /**
594     * List of intents that were used to start the most recent tasks.
595     */
596    final RecentTasks mRecentTasks;
597
598    /**
599     * For addAppTask: cached of the last activity component that was added.
600     */
601    ComponentName mLastAddedTaskComponent;
602
603    /**
604     * For addAppTask: cached of the last activity uid that was added.
605     */
606    int mLastAddedTaskUid;
607
608    /**
609     * For addAppTask: cached of the last ActivityInfo that was added.
610     */
611    ActivityInfo mLastAddedTaskActivity;
612
613    /**
614     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
615     */
616    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
617
618    /**
619     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
620     */
621    String mDeviceOwnerName;
622
623    final UserController mUserController;
624
625    final AppErrors mAppErrors;
626
627    boolean mDoingSetFocusedActivity;
628
629    public boolean canShowErrorDialogs() {
630        return mShowDialogs && !mSleeping && !mShuttingDown;
631    }
632
633    // it's a semaphore; boost when 0->1, reset when 1->0
634    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
635        @Override protected Integer initialValue() {
636            return 0;
637        }
638    };
639
640    static void boostPriorityForLockedSection() {
641        if (sIsBoosted.get() == 0) {
642            // boost to prio 118 while holding a global lock
643            Process.setThreadPriority(Process.myTid(), -2);
644            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
645        }
646        int cur = sIsBoosted.get();
647        sIsBoosted.set(cur + 1);
648    }
649
650    static void resetPriorityAfterLockedSection() {
651        sIsBoosted.set(sIsBoosted.get() - 1);
652        if (sIsBoosted.get() == 0) {
653            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
654            Process.setThreadPriority(Process.myTid(), 0);
655        }
656    }
657    public class PendingAssistExtras extends Binder implements Runnable {
658        public final ActivityRecord activity;
659        public final Bundle extras;
660        public final Intent intent;
661        public final String hint;
662        public final IResultReceiver receiver;
663        public final int userHandle;
664        public boolean haveResult = false;
665        public Bundle result = null;
666        public AssistStructure structure = null;
667        public AssistContent content = null;
668        public Bundle receiverExtras;
669
670        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
671                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
672            activity = _activity;
673            extras = _extras;
674            intent = _intent;
675            hint = _hint;
676            receiver = _receiver;
677            receiverExtras = _receiverExtras;
678            userHandle = _userHandle;
679        }
680        @Override
681        public void run() {
682            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
683            synchronized (this) {
684                haveResult = true;
685                notifyAll();
686            }
687            pendingAssistExtrasTimedOut(this);
688        }
689    }
690
691    final ArrayList<PendingAssistExtras> mPendingAssistExtras
692            = new ArrayList<PendingAssistExtras>();
693
694    /**
695     * Process management.
696     */
697    final ProcessList mProcessList = new ProcessList();
698
699    /**
700     * All of the applications we currently have running organized by name.
701     * The keys are strings of the application package name (as
702     * returned by the package manager), and the keys are ApplicationRecord
703     * objects.
704     */
705    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
706
707    /**
708     * Tracking long-term execution of processes to look for abuse and other
709     * bad app behavior.
710     */
711    final ProcessStatsService mProcessStats;
712
713    /**
714     * The currently running isolated processes.
715     */
716    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
717
718    /**
719     * Counter for assigning isolated process uids, to avoid frequently reusing the
720     * same ones.
721     */
722    int mNextIsolatedProcessUid = 0;
723
724    /**
725     * The currently running heavy-weight process, if any.
726     */
727    ProcessRecord mHeavyWeightProcess = null;
728
729    /**
730     * All of the processes we currently have running organized by pid.
731     * The keys are the pid running the application.
732     *
733     * <p>NOTE: This object is protected by its own lock, NOT the global
734     * activity manager lock!
735     */
736    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
737
738    /**
739     * All of the processes that have been forced to be foreground.  The key
740     * is the pid of the caller who requested it (we hold a death
741     * link on it).
742     */
743    abstract class ForegroundToken implements IBinder.DeathRecipient {
744        int pid;
745        IBinder token;
746    }
747    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
748
749    /**
750     * List of records for processes that someone had tried to start before the
751     * system was ready.  We don't start them at that point, but ensure they
752     * are started by the time booting is complete.
753     */
754    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
755
756    /**
757     * List of persistent applications that are in the process
758     * of being started.
759     */
760    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes that are being forcibly torn down.
764     */
765    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
766
767    /**
768     * List of running applications, sorted by recent usage.
769     * The first entry in the list is the least recently used.
770     */
771    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * Where in mLruProcesses that the processes hosting activities start.
775     */
776    int mLruProcessActivityStart = 0;
777
778    /**
779     * Where in mLruProcesses that the processes hosting services start.
780     * This is after (lower index) than mLruProcessesActivityStart.
781     */
782    int mLruProcessServiceStart = 0;
783
784    /**
785     * List of processes that should gc as soon as things are idle.
786     */
787    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
788
789    /**
790     * Processes we want to collect PSS data from.
791     */
792    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
793
794    private boolean mBinderTransactionTrackingEnabled = false;
795
796    /**
797     * Last time we requested PSS data of all processes.
798     */
799    long mLastFullPssTime = SystemClock.uptimeMillis();
800
801    /**
802     * If set, the next time we collect PSS data we should do a full collection
803     * with data from native processes and the kernel.
804     */
805    boolean mFullPssPending = false;
806
807    /**
808     * This is the process holding what we currently consider to be
809     * the "home" activity.
810     */
811    ProcessRecord mHomeProcess;
812
813    /**
814     * This is the process holding the activity the user last visited that
815     * is in a different process from the one they are currently in.
816     */
817    ProcessRecord mPreviousProcess;
818
819    /**
820     * The time at which the previous process was last visible.
821     */
822    long mPreviousProcessVisibleTime;
823
824    /**
825     * Track all uids that have actively running processes.
826     */
827    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
828
829    /**
830     * This is for verifying the UID report flow.
831     */
832    static final boolean VALIDATE_UID_STATES = true;
833    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
834
835    /**
836     * Packages that the user has asked to have run in screen size
837     * compatibility mode instead of filling the screen.
838     */
839    final CompatModePackages mCompatModePackages;
840
841    /**
842     * Set of IntentSenderRecord objects that are currently active.
843     */
844    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
845            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
846
847    /**
848     * Fingerprints (hashCode()) of stack traces that we've
849     * already logged DropBox entries for.  Guarded by itself.  If
850     * something (rogue user app) forces this over
851     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
852     */
853    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
854    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
855
856    /**
857     * Strict Mode background batched logging state.
858     *
859     * The string buffer is guarded by itself, and its lock is also
860     * used to determine if another batched write is already
861     * in-flight.
862     */
863    private final StringBuilder mStrictModeBuffer = new StringBuilder();
864
865    /**
866     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
867     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
868     */
869    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
870
871    /**
872     * Resolver for broadcast intents to registered receivers.
873     * Holds BroadcastFilter (subclass of IntentFilter).
874     */
875    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
876            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
877        @Override
878        protected boolean allowFilterResult(
879                BroadcastFilter filter, List<BroadcastFilter> dest) {
880            IBinder target = filter.receiverList.receiver.asBinder();
881            for (int i = dest.size() - 1; i >= 0; i--) {
882                if (dest.get(i).receiverList.receiver.asBinder() == target) {
883                    return false;
884                }
885            }
886            return true;
887        }
888
889        @Override
890        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
891            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
892                    || userId == filter.owningUserId) {
893                return super.newResult(filter, match, userId);
894            }
895            return null;
896        }
897
898        @Override
899        protected BroadcastFilter[] newArray(int size) {
900            return new BroadcastFilter[size];
901        }
902
903        @Override
904        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
905            return packageName.equals(filter.packageName);
906        }
907    };
908
909    /**
910     * State of all active sticky broadcasts per user.  Keys are the action of the
911     * sticky Intent, values are an ArrayList of all broadcasted intents with
912     * that action (which should usually be one).  The SparseArray is keyed
913     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
914     * for stickies that are sent to all users.
915     */
916    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
917            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
918
919    final ActiveServices mServices;
920
921    final static class Association {
922        final int mSourceUid;
923        final String mSourceProcess;
924        final int mTargetUid;
925        final ComponentName mTargetComponent;
926        final String mTargetProcess;
927
928        int mCount;
929        long mTime;
930
931        int mNesting;
932        long mStartTime;
933
934        // states of the source process when the bind occurred.
935        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
936        long mLastStateUptime;
937        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
938                - ActivityManager.MIN_PROCESS_STATE+1];
939
940        Association(int sourceUid, String sourceProcess, int targetUid,
941                ComponentName targetComponent, String targetProcess) {
942            mSourceUid = sourceUid;
943            mSourceProcess = sourceProcess;
944            mTargetUid = targetUid;
945            mTargetComponent = targetComponent;
946            mTargetProcess = targetProcess;
947        }
948    }
949
950    /**
951     * When service association tracking is enabled, this is all of the associations we
952     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
953     * -> association data.
954     */
955    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
956            mAssociations = new SparseArray<>();
957    boolean mTrackingAssociations;
958
959    /**
960     * Backup/restore process management
961     */
962    String mBackupAppName = null;
963    BackupRecord mBackupTarget = null;
964
965    final ProviderMap mProviderMap;
966
967    /**
968     * List of content providers who have clients waiting for them.  The
969     * application is currently being launched and the provider will be
970     * removed from this list once it is published.
971     */
972    final ArrayList<ContentProviderRecord> mLaunchingProviders
973            = new ArrayList<ContentProviderRecord>();
974
975    /**
976     * File storing persisted {@link #mGrantedUriPermissions}.
977     */
978    private final AtomicFile mGrantFile;
979
980    /** XML constants used in {@link #mGrantFile} */
981    private static final String TAG_URI_GRANTS = "uri-grants";
982    private static final String TAG_URI_GRANT = "uri-grant";
983    private static final String ATTR_USER_HANDLE = "userHandle";
984    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
985    private static final String ATTR_TARGET_USER_ID = "targetUserId";
986    private static final String ATTR_SOURCE_PKG = "sourcePkg";
987    private static final String ATTR_TARGET_PKG = "targetPkg";
988    private static final String ATTR_URI = "uri";
989    private static final String ATTR_MODE_FLAGS = "modeFlags";
990    private static final String ATTR_CREATED_TIME = "createdTime";
991    private static final String ATTR_PREFIX = "prefix";
992
993    /**
994     * Global set of specific {@link Uri} permissions that have been granted.
995     * This optimized lookup structure maps from {@link UriPermission#targetUid}
996     * to {@link UriPermission#uri} to {@link UriPermission}.
997     */
998    @GuardedBy("this")
999    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1000            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1001
1002    public static class GrantUri {
1003        public final int sourceUserId;
1004        public final Uri uri;
1005        public boolean prefix;
1006
1007        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1008            this.sourceUserId = sourceUserId;
1009            this.uri = uri;
1010            this.prefix = prefix;
1011        }
1012
1013        @Override
1014        public int hashCode() {
1015            int hashCode = 1;
1016            hashCode = 31 * hashCode + sourceUserId;
1017            hashCode = 31 * hashCode + uri.hashCode();
1018            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1019            return hashCode;
1020        }
1021
1022        @Override
1023        public boolean equals(Object o) {
1024            if (o instanceof GrantUri) {
1025                GrantUri other = (GrantUri) o;
1026                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1027                        && prefix == other.prefix;
1028            }
1029            return false;
1030        }
1031
1032        @Override
1033        public String toString() {
1034            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1035            if (prefix) result += " [prefix]";
1036            return result;
1037        }
1038
1039        public String toSafeString() {
1040            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1041            if (prefix) result += " [prefix]";
1042            return result;
1043        }
1044
1045        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1046            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1047                    ContentProvider.getUriWithoutUserId(uri), false);
1048        }
1049    }
1050
1051    CoreSettingsObserver mCoreSettingsObserver;
1052
1053    FontScaleSettingObserver mFontScaleSettingObserver;
1054
1055    private final class FontScaleSettingObserver extends ContentObserver {
1056        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1057
1058        public FontScaleSettingObserver() {
1059            super(mHandler);
1060            ContentResolver resolver = mContext.getContentResolver();
1061            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1062        }
1063
1064        @Override
1065        public void onChange(boolean selfChange, Uri uri) {
1066            if (mFontScaleUri.equals(uri)) {
1067                updateFontScaleIfNeeded();
1068            }
1069        }
1070    }
1071
1072    /**
1073     * Thread-local storage used to carry caller permissions over through
1074     * indirect content-provider access.
1075     */
1076    private class Identity {
1077        public final IBinder token;
1078        public final int pid;
1079        public final int uid;
1080
1081        Identity(IBinder _token, int _pid, int _uid) {
1082            token = _token;
1083            pid = _pid;
1084            uid = _uid;
1085        }
1086    }
1087
1088    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1089
1090    /**
1091     * All information we have collected about the runtime performance of
1092     * any user id that can impact battery performance.
1093     */
1094    final BatteryStatsService mBatteryStatsService;
1095
1096    /**
1097     * Information about component usage
1098     */
1099    UsageStatsManagerInternal mUsageStatsService;
1100
1101    /**
1102     * Access to DeviceIdleController service.
1103     */
1104    DeviceIdleController.LocalService mLocalDeviceIdleController;
1105
1106    /**
1107     * Information about and control over application operations
1108     */
1109    final AppOpsService mAppOpsService;
1110
1111    /**
1112     * Current configuration information.  HistoryRecord objects are given
1113     * a reference to this object to indicate which configuration they are
1114     * currently running in, so this object must be kept immutable.
1115     */
1116    Configuration mConfiguration = new Configuration();
1117
1118    /**
1119     * Current sequencing integer of the configuration, for skipping old
1120     * configurations.
1121     */
1122    int mConfigurationSeq = 0;
1123
1124    boolean mSuppressResizeConfigChanges = false;
1125
1126    /**
1127     * Hardware-reported OpenGLES version.
1128     */
1129    final int GL_ES_VERSION;
1130
1131    /**
1132     * List of initialization arguments to pass to all processes when binding applications to them.
1133     * For example, references to the commonly used services.
1134     */
1135    HashMap<String, IBinder> mAppBindArgs;
1136
1137    /**
1138     * Temporary to avoid allocations.  Protected by main lock.
1139     */
1140    final StringBuilder mStringBuilder = new StringBuilder(256);
1141
1142    /**
1143     * Used to control how we initialize the service.
1144     */
1145    ComponentName mTopComponent;
1146    String mTopAction = Intent.ACTION_MAIN;
1147    String mTopData;
1148
1149    volatile boolean mProcessesReady = false;
1150    volatile boolean mSystemReady = false;
1151    volatile boolean mOnBattery = false;
1152    volatile int mFactoryTest;
1153
1154    @GuardedBy("this") boolean mBooting = false;
1155    @GuardedBy("this") boolean mCallFinishBooting = false;
1156    @GuardedBy("this") boolean mBootAnimationComplete = false;
1157    @GuardedBy("this") boolean mLaunchWarningShown = false;
1158    @GuardedBy("this") boolean mCheckedForSetup = false;
1159
1160    Context mContext;
1161
1162    /**
1163     * The time at which we will allow normal application switches again,
1164     * after a call to {@link #stopAppSwitches()}.
1165     */
1166    long mAppSwitchesAllowedTime;
1167
1168    /**
1169     * This is set to true after the first switch after mAppSwitchesAllowedTime
1170     * is set; any switches after that will clear the time.
1171     */
1172    boolean mDidAppSwitch;
1173
1174    /**
1175     * Last time (in realtime) at which we checked for power usage.
1176     */
1177    long mLastPowerCheckRealtime;
1178
1179    /**
1180     * Last time (in uptime) at which we checked for power usage.
1181     */
1182    long mLastPowerCheckUptime;
1183
1184    /**
1185     * Set while we are wanting to sleep, to prevent any
1186     * activities from being started/resumed.
1187     */
1188    private boolean mSleeping = false;
1189
1190    /**
1191     * The process state used for processes that are running the top activities.
1192     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1193     */
1194    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1195
1196    /**
1197     * Set while we are running a voice interaction.  This overrides
1198     * sleeping while it is active.
1199     */
1200    private IVoiceInteractionSession mRunningVoice;
1201
1202    /**
1203     * For some direct access we need to power manager.
1204     */
1205    PowerManagerInternal mLocalPowerManager;
1206
1207    /**
1208     * We want to hold a wake lock while running a voice interaction session, since
1209     * this may happen with the screen off and we need to keep the CPU running to
1210     * be able to continue to interact with the user.
1211     */
1212    PowerManager.WakeLock mVoiceWakeLock;
1213
1214    /**
1215     * State of external calls telling us if the device is awake or asleep.
1216     */
1217    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1218
1219    /**
1220     * A list of tokens that cause the top activity to be put to sleep.
1221     * They are used by components that may hide and block interaction with underlying
1222     * activities.
1223     */
1224    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1225
1226    static final int LOCK_SCREEN_HIDDEN = 0;
1227    static final int LOCK_SCREEN_LEAVING = 1;
1228    static final int LOCK_SCREEN_SHOWN = 2;
1229    /**
1230     * State of external call telling us if the lock screen is shown.
1231     */
1232    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1233
1234    /**
1235     * Set if we are shutting down the system, similar to sleeping.
1236     */
1237    boolean mShuttingDown = false;
1238
1239    /**
1240     * Current sequence id for oom_adj computation traversal.
1241     */
1242    int mAdjSeq = 0;
1243
1244    /**
1245     * Current sequence id for process LRU updating.
1246     */
1247    int mLruSeq = 0;
1248
1249    /**
1250     * Keep track of the non-cached/empty process we last found, to help
1251     * determine how to distribute cached/empty processes next time.
1252     */
1253    int mNumNonCachedProcs = 0;
1254
1255    /**
1256     * Keep track of the number of cached hidden procs, to balance oom adj
1257     * distribution between those and empty procs.
1258     */
1259    int mNumCachedHiddenProcs = 0;
1260
1261    /**
1262     * Keep track of the number of service processes we last found, to
1263     * determine on the next iteration which should be B services.
1264     */
1265    int mNumServiceProcs = 0;
1266    int mNewNumAServiceProcs = 0;
1267    int mNewNumServiceProcs = 0;
1268
1269    /**
1270     * Allow the current computed overall memory level of the system to go down?
1271     * This is set to false when we are killing processes for reasons other than
1272     * memory management, so that the now smaller process list will not be taken as
1273     * an indication that memory is tighter.
1274     */
1275    boolean mAllowLowerMemLevel = false;
1276
1277    /**
1278     * The last computed memory level, for holding when we are in a state that
1279     * processes are going away for other reasons.
1280     */
1281    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1282
1283    /**
1284     * The last total number of process we have, to determine if changes actually look
1285     * like a shrinking number of process due to lower RAM.
1286     */
1287    int mLastNumProcesses;
1288
1289    /**
1290     * The uptime of the last time we performed idle maintenance.
1291     */
1292    long mLastIdleTime = SystemClock.uptimeMillis();
1293
1294    /**
1295     * Total time spent with RAM that has been added in the past since the last idle time.
1296     */
1297    long mLowRamTimeSinceLastIdle = 0;
1298
1299    /**
1300     * If RAM is currently low, when that horrible situation started.
1301     */
1302    long mLowRamStartTime = 0;
1303
1304    /**
1305     * For reporting to battery stats the current top application.
1306     */
1307    private String mCurResumedPackage = null;
1308    private int mCurResumedUid = -1;
1309
1310    /**
1311     * For reporting to battery stats the apps currently running foreground
1312     * service.  The ProcessMap is package/uid tuples; each of these contain
1313     * an array of the currently foreground processes.
1314     */
1315    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1316            = new ProcessMap<ArrayList<ProcessRecord>>();
1317
1318    /**
1319     * This is set if we had to do a delayed dexopt of an app before launching
1320     * it, to increase the ANR timeouts in that case.
1321     */
1322    boolean mDidDexOpt;
1323
1324    /**
1325     * Set if the systemServer made a call to enterSafeMode.
1326     */
1327    boolean mSafeMode;
1328
1329    /**
1330     * If true, we are running under a test environment so will sample PSS from processes
1331     * much more rapidly to try to collect better data when the tests are rapidly
1332     * running through apps.
1333     */
1334    boolean mTestPssMode = false;
1335
1336    String mDebugApp = null;
1337    boolean mWaitForDebugger = false;
1338    boolean mDebugTransient = false;
1339    String mOrigDebugApp = null;
1340    boolean mOrigWaitForDebugger = false;
1341    boolean mAlwaysFinishActivities = false;
1342    boolean mLenientBackgroundCheck = false;
1343    boolean mForceResizableActivities;
1344    boolean mSupportsMultiWindow;
1345    boolean mSupportsFreeformWindowManagement;
1346    boolean mSupportsPictureInPicture;
1347    Rect mDefaultPinnedStackBounds;
1348    IActivityController mController = null;
1349    boolean mControllerIsAMonkey = false;
1350    String mProfileApp = null;
1351    ProcessRecord mProfileProc = null;
1352    String mProfileFile;
1353    ParcelFileDescriptor mProfileFd;
1354    int mSamplingInterval = 0;
1355    boolean mAutoStopProfiler = false;
1356    int mProfileType = 0;
1357    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1358    String mMemWatchDumpProcName;
1359    String mMemWatchDumpFile;
1360    int mMemWatchDumpPid;
1361    int mMemWatchDumpUid;
1362    String mTrackAllocationApp = null;
1363    String mNativeDebuggingApp = null;
1364
1365    final long[] mTmpLong = new long[2];
1366
1367    static final class ProcessChangeItem {
1368        static final int CHANGE_ACTIVITIES = 1<<0;
1369        static final int CHANGE_PROCESS_STATE = 1<<1;
1370        int changes;
1371        int uid;
1372        int pid;
1373        int processState;
1374        boolean foregroundActivities;
1375    }
1376
1377    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1378    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1379
1380    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1381    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1382
1383    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1384    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1385
1386    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1387    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1388
1389    /**
1390     * Runtime CPU use collection thread.  This object's lock is used to
1391     * perform synchronization with the thread (notifying it to run).
1392     */
1393    final Thread mProcessCpuThread;
1394
1395    /**
1396     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1397     * Must acquire this object's lock when accessing it.
1398     * NOTE: this lock will be held while doing long operations (trawling
1399     * through all processes in /proc), so it should never be acquired by
1400     * any critical paths such as when holding the main activity manager lock.
1401     */
1402    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1403            MONITOR_THREAD_CPU_USAGE);
1404    final AtomicLong mLastCpuTime = new AtomicLong(0);
1405    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1406
1407    long mLastWriteTime = 0;
1408
1409    /**
1410     * Used to retain an update lock when the foreground activity is in
1411     * immersive mode.
1412     */
1413    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1414
1415    /**
1416     * Set to true after the system has finished booting.
1417     */
1418    boolean mBooted = false;
1419
1420    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1421    int mProcessLimitOverride = -1;
1422
1423    WindowManagerService mWindowManager;
1424    final ActivityThread mSystemThread;
1425
1426    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1427        final ProcessRecord mApp;
1428        final int mPid;
1429        final IApplicationThread mAppThread;
1430
1431        AppDeathRecipient(ProcessRecord app, int pid,
1432                IApplicationThread thread) {
1433            if (DEBUG_ALL) Slog.v(
1434                TAG, "New death recipient " + this
1435                + " for thread " + thread.asBinder());
1436            mApp = app;
1437            mPid = pid;
1438            mAppThread = thread;
1439        }
1440
1441        @Override
1442        public void binderDied() {
1443            if (DEBUG_ALL) Slog.v(
1444                TAG, "Death received in " + this
1445                + " for thread " + mAppThread.asBinder());
1446            synchronized(ActivityManagerService.this) {
1447                appDiedLocked(mApp, mPid, mAppThread, true);
1448            }
1449        }
1450    }
1451
1452    static final int SHOW_ERROR_UI_MSG = 1;
1453    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1454    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1455    static final int UPDATE_CONFIGURATION_MSG = 4;
1456    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1457    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1458    static final int SERVICE_TIMEOUT_MSG = 12;
1459    static final int UPDATE_TIME_ZONE = 13;
1460    static final int SHOW_UID_ERROR_UI_MSG = 14;
1461    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1462    static final int PROC_START_TIMEOUT_MSG = 20;
1463    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1464    static final int KILL_APPLICATION_MSG = 22;
1465    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1466    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1467    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1468    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1469    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1470    static final int CLEAR_DNS_CACHE_MSG = 28;
1471    static final int UPDATE_HTTP_PROXY_MSG = 29;
1472    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1473    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1474    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1475    static final int REPORT_MEM_USAGE_MSG = 33;
1476    static final int REPORT_USER_SWITCH_MSG = 34;
1477    static final int CONTINUE_USER_SWITCH_MSG = 35;
1478    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1479    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1480    static final int PERSIST_URI_GRANTS_MSG = 38;
1481    static final int REQUEST_ALL_PSS_MSG = 39;
1482    static final int START_PROFILES_MSG = 40;
1483    static final int UPDATE_TIME = 41;
1484    static final int SYSTEM_USER_START_MSG = 42;
1485    static final int SYSTEM_USER_CURRENT_MSG = 43;
1486    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1487    static final int FINISH_BOOTING_MSG = 45;
1488    static final int START_USER_SWITCH_UI_MSG = 46;
1489    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1490    static final int DISMISS_DIALOG_UI_MSG = 48;
1491    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1492    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1493    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1494    static final int DELETE_DUMPHEAP_MSG = 52;
1495    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1496    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1497    static final int REPORT_TIME_TRACKER_MSG = 55;
1498    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1499    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1500    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1501    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1502    static final int IDLE_UIDS_MSG = 60;
1503    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1504    static final int LOG_STACK_STATE = 62;
1505    static final int VR_MODE_CHANGE_MSG = 63;
1506    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1507    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1508    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1509    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1510    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1511    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1512
1513    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1514    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1515    static final int FIRST_COMPAT_MODE_MSG = 300;
1516    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1517
1518    static ServiceThread sKillThread = null;
1519    static KillHandler sKillHandler = null;
1520
1521    CompatModeDialog mCompatModeDialog;
1522    long mLastMemUsageReportTime = 0;
1523
1524    /**
1525     * Flag whether the current user is a "monkey", i.e. whether
1526     * the UI is driven by a UI automation tool.
1527     */
1528    private boolean mUserIsMonkey;
1529
1530    /** Flag whether the device has a Recents UI */
1531    boolean mHasRecents;
1532
1533    /** The dimensions of the thumbnails in the Recents UI. */
1534    int mThumbnailWidth;
1535    int mThumbnailHeight;
1536    float mFullscreenThumbnailScale;
1537
1538    final ServiceThread mHandlerThread;
1539    final MainHandler mHandler;
1540    final UiHandler mUiHandler;
1541
1542    PackageManagerInternal mPackageManagerInt;
1543
1544    // VoiceInteraction session ID that changes for each new request except when
1545    // being called for multiwindow assist in a single session.
1546    private int mViSessionId = 1000;
1547
1548    final class KillHandler extends Handler {
1549        static final int KILL_PROCESS_GROUP_MSG = 4000;
1550
1551        public KillHandler(Looper looper) {
1552            super(looper, null, true);
1553        }
1554
1555        @Override
1556        public void handleMessage(Message msg) {
1557            switch (msg.what) {
1558                case KILL_PROCESS_GROUP_MSG:
1559                {
1560                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1561                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1562                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1563                }
1564                break;
1565
1566                default:
1567                    super.handleMessage(msg);
1568            }
1569        }
1570    }
1571
1572    final class UiHandler extends Handler {
1573        public UiHandler() {
1574            super(com.android.server.UiThread.get().getLooper(), null, true);
1575        }
1576
1577        @Override
1578        public void handleMessage(Message msg) {
1579            switch (msg.what) {
1580            case SHOW_ERROR_UI_MSG: {
1581                mAppErrors.handleShowAppErrorUi(msg);
1582                ensureBootCompleted();
1583            } break;
1584            case SHOW_NOT_RESPONDING_UI_MSG: {
1585                mAppErrors.handleShowAnrUi(msg);
1586                ensureBootCompleted();
1587            } break;
1588            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1589                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1590                synchronized (ActivityManagerService.this) {
1591                    ProcessRecord proc = (ProcessRecord) data.get("app");
1592                    if (proc == null) {
1593                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1594                        break;
1595                    }
1596                    if (proc.crashDialog != null) {
1597                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1598                        return;
1599                    }
1600                    AppErrorResult res = (AppErrorResult) data.get("result");
1601                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1602                        Dialog d = new StrictModeViolationDialog(mContext,
1603                                ActivityManagerService.this, res, proc);
1604                        d.show();
1605                        proc.crashDialog = d;
1606                    } else {
1607                        // The device is asleep, so just pretend that the user
1608                        // saw a crash dialog and hit "force quit".
1609                        res.set(0);
1610                    }
1611                }
1612                ensureBootCompleted();
1613            } break;
1614            case SHOW_FACTORY_ERROR_UI_MSG: {
1615                Dialog d = new FactoryErrorDialog(
1616                    mContext, msg.getData().getCharSequence("msg"));
1617                d.show();
1618                ensureBootCompleted();
1619            } break;
1620            case WAIT_FOR_DEBUGGER_UI_MSG: {
1621                synchronized (ActivityManagerService.this) {
1622                    ProcessRecord app = (ProcessRecord)msg.obj;
1623                    if (msg.arg1 != 0) {
1624                        if (!app.waitedForDebugger) {
1625                            Dialog d = new AppWaitingForDebuggerDialog(
1626                                    ActivityManagerService.this,
1627                                    mContext, app);
1628                            app.waitDialog = d;
1629                            app.waitedForDebugger = true;
1630                            d.show();
1631                        }
1632                    } else {
1633                        if (app.waitDialog != null) {
1634                            app.waitDialog.dismiss();
1635                            app.waitDialog = null;
1636                        }
1637                    }
1638                }
1639            } break;
1640            case SHOW_UID_ERROR_UI_MSG: {
1641                if (mShowDialogs) {
1642                    AlertDialog d = new BaseErrorDialog(mContext);
1643                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1644                    d.setCancelable(false);
1645                    d.setTitle(mContext.getText(R.string.android_system_label));
1646                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1647                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1648                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1649                    d.show();
1650                }
1651            } break;
1652            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1653                if (mShowDialogs) {
1654                    AlertDialog d = new BaseErrorDialog(mContext);
1655                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1656                    d.setCancelable(false);
1657                    d.setTitle(mContext.getText(R.string.android_system_label));
1658                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1659                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1660                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1661                    d.show();
1662                }
1663            } break;
1664            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1665                synchronized (ActivityManagerService.this) {
1666                    ActivityRecord ar = (ActivityRecord) msg.obj;
1667                    if (mCompatModeDialog != null) {
1668                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1669                                ar.info.applicationInfo.packageName)) {
1670                            return;
1671                        }
1672                        mCompatModeDialog.dismiss();
1673                        mCompatModeDialog = null;
1674                    }
1675                    if (ar != null && false) {
1676                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1677                                ar.packageName)) {
1678                            int mode = mCompatModePackages.computeCompatModeLocked(
1679                                    ar.info.applicationInfo);
1680                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1681                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1682                                mCompatModeDialog = new CompatModeDialog(
1683                                        ActivityManagerService.this, mContext,
1684                                        ar.info.applicationInfo);
1685                                mCompatModeDialog.show();
1686                            }
1687                        }
1688                    }
1689                }
1690                break;
1691            }
1692            case START_USER_SWITCH_UI_MSG: {
1693                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1694                break;
1695            }
1696            case DISMISS_DIALOG_UI_MSG: {
1697                final Dialog d = (Dialog) msg.obj;
1698                d.dismiss();
1699                break;
1700            }
1701            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1702                dispatchProcessesChanged();
1703                break;
1704            }
1705            case DISPATCH_PROCESS_DIED_UI_MSG: {
1706                final int pid = msg.arg1;
1707                final int uid = msg.arg2;
1708                dispatchProcessDied(pid, uid);
1709                break;
1710            }
1711            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1712                dispatchUidsChanged();
1713            } break;
1714            }
1715        }
1716    }
1717
1718    final class MainHandler extends Handler {
1719        public MainHandler(Looper looper) {
1720            super(looper, null, true);
1721        }
1722
1723        @Override
1724        public void handleMessage(Message msg) {
1725            switch (msg.what) {
1726            case UPDATE_CONFIGURATION_MSG: {
1727                final ContentResolver resolver = mContext.getContentResolver();
1728                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1729                        msg.arg1);
1730            } break;
1731            case GC_BACKGROUND_PROCESSES_MSG: {
1732                synchronized (ActivityManagerService.this) {
1733                    performAppGcsIfAppropriateLocked();
1734                }
1735            } break;
1736            case SERVICE_TIMEOUT_MSG: {
1737                if (mDidDexOpt) {
1738                    mDidDexOpt = false;
1739                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1740                    nmsg.obj = msg.obj;
1741                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1742                    return;
1743                }
1744                mServices.serviceTimeout((ProcessRecord)msg.obj);
1745            } break;
1746            case UPDATE_TIME_ZONE: {
1747                synchronized (ActivityManagerService.this) {
1748                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1749                        ProcessRecord r = mLruProcesses.get(i);
1750                        if (r.thread != null) {
1751                            try {
1752                                r.thread.updateTimeZone();
1753                            } catch (RemoteException ex) {
1754                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1755                            }
1756                        }
1757                    }
1758                }
1759            } break;
1760            case CLEAR_DNS_CACHE_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1763                        ProcessRecord r = mLruProcesses.get(i);
1764                        if (r.thread != null) {
1765                            try {
1766                                r.thread.clearDnsCache();
1767                            } catch (RemoteException ex) {
1768                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1769                            }
1770                        }
1771                    }
1772                }
1773            } break;
1774            case UPDATE_HTTP_PROXY_MSG: {
1775                ProxyInfo proxy = (ProxyInfo)msg.obj;
1776                String host = "";
1777                String port = "";
1778                String exclList = "";
1779                Uri pacFileUrl = Uri.EMPTY;
1780                if (proxy != null) {
1781                    host = proxy.getHost();
1782                    port = Integer.toString(proxy.getPort());
1783                    exclList = proxy.getExclusionListAsString();
1784                    pacFileUrl = proxy.getPacFileUrl();
1785                }
1786                synchronized (ActivityManagerService.this) {
1787                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1788                        ProcessRecord r = mLruProcesses.get(i);
1789                        if (r.thread != null) {
1790                            try {
1791                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1792                            } catch (RemoteException ex) {
1793                                Slog.w(TAG, "Failed to update http proxy for: " +
1794                                        r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799            } break;
1800            case PROC_START_TIMEOUT_MSG: {
1801                if (mDidDexOpt) {
1802                    mDidDexOpt = false;
1803                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1804                    nmsg.obj = msg.obj;
1805                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1806                    return;
1807                }
1808                ProcessRecord app = (ProcessRecord)msg.obj;
1809                synchronized (ActivityManagerService.this) {
1810                    processStartTimedOutLocked(app);
1811                }
1812            } break;
1813            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1814                ProcessRecord app = (ProcessRecord)msg.obj;
1815                synchronized (ActivityManagerService.this) {
1816                    processContentProviderPublishTimedOutLocked(app);
1817                }
1818            } break;
1819            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1820                synchronized (ActivityManagerService.this) {
1821                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1822                }
1823            } break;
1824            case KILL_APPLICATION_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    int appid = msg.arg1;
1827                    boolean restart = (msg.arg2 == 1);
1828                    Bundle bundle = (Bundle)msg.obj;
1829                    String pkg = bundle.getString("pkg");
1830                    String reason = bundle.getString("reason");
1831                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1832                            false, UserHandle.USER_ALL, reason);
1833                }
1834            } break;
1835            case FINALIZE_PENDING_INTENT_MSG: {
1836                ((PendingIntentRecord)msg.obj).completeFinalize();
1837            } break;
1838            case POST_HEAVY_NOTIFICATION_MSG: {
1839                INotificationManager inm = NotificationManager.getService();
1840                if (inm == null) {
1841                    return;
1842                }
1843
1844                ActivityRecord root = (ActivityRecord)msg.obj;
1845                ProcessRecord process = root.app;
1846                if (process == null) {
1847                    return;
1848                }
1849
1850                try {
1851                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1852                    String text = mContext.getString(R.string.heavy_weight_notification,
1853                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1854                    Notification notification = new Notification.Builder(context)
1855                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1856                            .setWhen(0)
1857                            .setOngoing(true)
1858                            .setTicker(text)
1859                            .setColor(mContext.getColor(
1860                                    com.android.internal.R.color.system_notification_accent_color))
1861                            .setContentTitle(text)
1862                            .setContentText(
1863                                    mContext.getText(R.string.heavy_weight_notification_detail))
1864                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1865                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1866                                    new UserHandle(root.userId)))
1867                            .build();
1868                    try {
1869                        int[] outId = new int[1];
1870                        inm.enqueueNotificationWithTag("android", "android", null,
1871                                R.string.heavy_weight_notification,
1872                                notification, outId, root.userId);
1873                    } catch (RuntimeException e) {
1874                        Slog.w(ActivityManagerService.TAG,
1875                                "Error showing notification for heavy-weight app", e);
1876                    } catch (RemoteException e) {
1877                    }
1878                } catch (NameNotFoundException e) {
1879                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1880                }
1881            } break;
1882            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1883                INotificationManager inm = NotificationManager.getService();
1884                if (inm == null) {
1885                    return;
1886                }
1887                try {
1888                    inm.cancelNotificationWithTag("android", null,
1889                            R.string.heavy_weight_notification,  msg.arg1);
1890                } catch (RuntimeException e) {
1891                    Slog.w(ActivityManagerService.TAG,
1892                            "Error canceling notification for service", e);
1893                } catch (RemoteException e) {
1894                }
1895            } break;
1896            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1897                synchronized (ActivityManagerService.this) {
1898                    checkExcessivePowerUsageLocked(true);
1899                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1900                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1902                }
1903            } break;
1904            case REPORT_MEM_USAGE_MSG: {
1905                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1906                Thread thread = new Thread() {
1907                    @Override public void run() {
1908                        reportMemUsage(memInfos);
1909                    }
1910                };
1911                thread.start();
1912                break;
1913            }
1914            case REPORT_USER_SWITCH_MSG: {
1915                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1916                break;
1917            }
1918            case CONTINUE_USER_SWITCH_MSG: {
1919                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1920                break;
1921            }
1922            case USER_SWITCH_TIMEOUT_MSG: {
1923                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1924                break;
1925            }
1926            case IMMERSIVE_MODE_LOCK_MSG: {
1927                final boolean nextState = (msg.arg1 != 0);
1928                if (mUpdateLock.isHeld() != nextState) {
1929                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1930                            "Applying new update lock state '" + nextState
1931                            + "' for " + (ActivityRecord)msg.obj);
1932                    if (nextState) {
1933                        mUpdateLock.acquire();
1934                    } else {
1935                        mUpdateLock.release();
1936                    }
1937                }
1938                break;
1939            }
1940            case PERSIST_URI_GRANTS_MSG: {
1941                writeGrantedUriPermissions();
1942                break;
1943            }
1944            case REQUEST_ALL_PSS_MSG: {
1945                synchronized (ActivityManagerService.this) {
1946                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1947                }
1948                break;
1949            }
1950            case START_PROFILES_MSG: {
1951                synchronized (ActivityManagerService.this) {
1952                    mUserController.startProfilesLocked();
1953                }
1954                break;
1955            }
1956            case UPDATE_TIME: {
1957                synchronized (ActivityManagerService.this) {
1958                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1959                        ProcessRecord r = mLruProcesses.get(i);
1960                        if (r.thread != null) {
1961                            try {
1962                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1963                            } catch (RemoteException ex) {
1964                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1965                            }
1966                        }
1967                    }
1968                }
1969                break;
1970            }
1971            case SYSTEM_USER_START_MSG: {
1972                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1973                        Integer.toString(msg.arg1), msg.arg1);
1974                mSystemServiceManager.startUser(msg.arg1);
1975                break;
1976            }
1977            case SYSTEM_USER_UNLOCK_MSG: {
1978                final int userId = msg.arg1;
1979                mSystemServiceManager.unlockUser(userId);
1980                synchronized (ActivityManagerService.this) {
1981                    mRecentTasks.loadUserRecentsLocked(userId);
1982                }
1983                if (userId == UserHandle.USER_SYSTEM) {
1984                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1985                }
1986                installEncryptionUnawareProviders(userId);
1987                mUserController.finishUserUnlocked((UserState) msg.obj);
1988                break;
1989            }
1990            case SYSTEM_USER_CURRENT_MSG: {
1991                mBatteryStatsService.noteEvent(
1992                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1993                        Integer.toString(msg.arg2), msg.arg2);
1994                mBatteryStatsService.noteEvent(
1995                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1996                        Integer.toString(msg.arg1), msg.arg1);
1997                mSystemServiceManager.switchUser(msg.arg1);
1998                break;
1999            }
2000            case ENTER_ANIMATION_COMPLETE_MSG: {
2001                synchronized (ActivityManagerService.this) {
2002                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2003                    if (r != null && r.app != null && r.app.thread != null) {
2004                        try {
2005                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2006                        } catch (RemoteException e) {
2007                        }
2008                    }
2009                }
2010                break;
2011            }
2012            case FINISH_BOOTING_MSG: {
2013                if (msg.arg1 != 0) {
2014                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2015                    finishBooting();
2016                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2017                }
2018                if (msg.arg2 != 0) {
2019                    enableScreenAfterBoot();
2020                }
2021                break;
2022            }
2023            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2024                try {
2025                    Locale l = (Locale) msg.obj;
2026                    IBinder service = ServiceManager.getService("mount");
2027                    IMountService mountService = IMountService.Stub.asInterface(service);
2028                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2029                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2030                } catch (RemoteException e) {
2031                    Log.e(TAG, "Error storing locale for decryption UI", e);
2032                }
2033                break;
2034            }
2035            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                        try {
2067                            // Make a one-way callback to the listener
2068                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2069                        } catch (RemoteException e){
2070                            // Handled by the RemoteCallbackList
2071                        }
2072                    }
2073                    mTaskStackListeners.finishBroadcast();
2074                }
2075                break;
2076            }
2077            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2078                synchronized (ActivityManagerService.this) {
2079                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2080                        try {
2081                            // Make a one-way callback to the listener
2082                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2083                        } catch (RemoteException e){
2084                            // Handled by the RemoteCallbackList
2085                        }
2086                    }
2087                    mTaskStackListeners.finishBroadcast();
2088                }
2089                break;
2090            }
2091            case NOTIFY_FORCED_RESIZABLE_MSG: {
2092                synchronized (ActivityManagerService.this) {
2093                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2094                        try {
2095                            // Make a one-way callback to the listener
2096                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2097                                    (String) msg.obj, msg.arg1);
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2107                    synchronized (ActivityManagerService.this) {
2108                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                            try {
2110                                // Make a one-way callback to the listener
2111                                mTaskStackListeners.getBroadcastItem(i)
2112                                        .onActivityDismissingDockedStack();
2113                            } catch (RemoteException e){
2114                                // Handled by the RemoteCallbackList
2115                            }
2116                        }
2117                        mTaskStackListeners.finishBroadcast();
2118                    }
2119                    break;
2120                }
2121            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2122                final int uid = msg.arg1;
2123                final byte[] firstPacket = (byte[]) msg.obj;
2124
2125                synchronized (mPidsSelfLocked) {
2126                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2127                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2128                        if (p.uid == uid) {
2129                            try {
2130                                p.thread.notifyCleartextNetwork(firstPacket);
2131                            } catch (RemoteException ignored) {
2132                            }
2133                        }
2134                    }
2135                }
2136                break;
2137            }
2138            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2139                final String procName;
2140                final int uid;
2141                final long memLimit;
2142                final String reportPackage;
2143                synchronized (ActivityManagerService.this) {
2144                    procName = mMemWatchDumpProcName;
2145                    uid = mMemWatchDumpUid;
2146                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2147                    if (val == null) {
2148                        val = mMemWatchProcesses.get(procName, 0);
2149                    }
2150                    if (val != null) {
2151                        memLimit = val.first;
2152                        reportPackage = val.second;
2153                    } else {
2154                        memLimit = 0;
2155                        reportPackage = null;
2156                    }
2157                }
2158                if (procName == null) {
2159                    return;
2160                }
2161
2162                if (DEBUG_PSS) Slog.d(TAG_PSS,
2163                        "Showing dump heap notification from " + procName + "/" + uid);
2164
2165                INotificationManager inm = NotificationManager.getService();
2166                if (inm == null) {
2167                    return;
2168                }
2169
2170                String text = mContext.getString(R.string.dump_heap_notification, procName);
2171
2172
2173                Intent deleteIntent = new Intent();
2174                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2175                Intent intent = new Intent();
2176                intent.setClassName("android", DumpHeapActivity.class.getName());
2177                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2178                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2179                if (reportPackage != null) {
2180                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2181                }
2182                int userId = UserHandle.getUserId(uid);
2183                Notification notification = new Notification.Builder(mContext)
2184                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2185                        .setWhen(0)
2186                        .setOngoing(true)
2187                        .setAutoCancel(true)
2188                        .setTicker(text)
2189                        .setColor(mContext.getColor(
2190                                com.android.internal.R.color.system_notification_accent_color))
2191                        .setContentTitle(text)
2192                        .setContentText(
2193                                mContext.getText(R.string.dump_heap_notification_detail))
2194                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2195                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2196                                new UserHandle(userId)))
2197                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2198                                deleteIntent, 0, UserHandle.SYSTEM))
2199                        .build();
2200
2201                try {
2202                    int[] outId = new int[1];
2203                    inm.enqueueNotificationWithTag("android", "android", null,
2204                            R.string.dump_heap_notification,
2205                            notification, outId, userId);
2206                } catch (RuntimeException e) {
2207                    Slog.w(ActivityManagerService.TAG,
2208                            "Error showing notification for dump heap", e);
2209                } catch (RemoteException e) {
2210                }
2211            } break;
2212            case DELETE_DUMPHEAP_MSG: {
2213                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2214                        DumpHeapActivity.JAVA_URI,
2215                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2216                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2217                        UserHandle.myUserId());
2218                synchronized (ActivityManagerService.this) {
2219                    mMemWatchDumpFile = null;
2220                    mMemWatchDumpProcName = null;
2221                    mMemWatchDumpPid = -1;
2222                    mMemWatchDumpUid = -1;
2223                }
2224            } break;
2225            case FOREGROUND_PROFILE_CHANGED_MSG: {
2226                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2227            } break;
2228            case REPORT_TIME_TRACKER_MSG: {
2229                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2230                tracker.deliverResult(mContext);
2231            } break;
2232            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2233                mUserController.dispatchUserSwitchComplete(msg.arg1);
2234            } break;
2235            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2236                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2237                try {
2238                    connection.shutdown();
2239                } catch (RemoteException e) {
2240                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2241                }
2242                // Only a UiAutomation can set this flag and now that
2243                // it is finished we make sure it is reset to its default.
2244                mUserIsMonkey = false;
2245            } break;
2246            case APP_BOOST_DEACTIVATE_MSG: {
2247                synchronized(ActivityManagerService.this) {
2248                    if (mIsBoosted) {
2249                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2250                            nativeMigrateFromBoost();
2251                            mIsBoosted = false;
2252                            mBoostStartTime = 0;
2253                        } else {
2254                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2255                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2256                        }
2257                    }
2258                }
2259            } break;
2260            case IDLE_UIDS_MSG: {
2261                idleUids();
2262            } break;
2263            case LOG_STACK_STATE: {
2264                synchronized (ActivityManagerService.this) {
2265                    mStackSupervisor.logStackState();
2266                }
2267            } break;
2268            case VR_MODE_CHANGE_MSG: {
2269                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2270                final ActivityRecord r = (ActivityRecord) msg.obj;
2271                boolean vrMode;
2272                ComponentName requestedPackage;
2273                ComponentName callingPackage;
2274                int userId;
2275                synchronized (ActivityManagerService.this) {
2276                    vrMode = r.requestedVrComponent != null;
2277                    requestedPackage = r.requestedVrComponent;
2278                    userId = r.userId;
2279                    callingPackage = r.info.getComponentName();
2280                    if (mInVrMode != vrMode) {
2281                        mInVrMode = vrMode;
2282                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2283                    }
2284                }
2285                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2286            } break;
2287            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2288                final ActivityRecord r = (ActivityRecord) msg.obj;
2289                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2290                if (needsVrMode) {
2291                    VrManagerInternal vrService =
2292                            LocalServices.getService(VrManagerInternal.class);
2293                    boolean enable = msg.arg1 == 1;
2294                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2295                            r.info.getComponentName());
2296                }
2297            } break;
2298            }
2299        }
2300    };
2301
2302    static final int COLLECT_PSS_BG_MSG = 1;
2303
2304    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2305        @Override
2306        public void handleMessage(Message msg) {
2307            switch (msg.what) {
2308            case COLLECT_PSS_BG_MSG: {
2309                long start = SystemClock.uptimeMillis();
2310                MemInfoReader memInfo = null;
2311                synchronized (ActivityManagerService.this) {
2312                    if (mFullPssPending) {
2313                        mFullPssPending = false;
2314                        memInfo = new MemInfoReader();
2315                    }
2316                }
2317                if (memInfo != null) {
2318                    updateCpuStatsNow();
2319                    long nativeTotalPss = 0;
2320                    synchronized (mProcessCpuTracker) {
2321                        final int N = mProcessCpuTracker.countStats();
2322                        for (int j=0; j<N; j++) {
2323                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2324                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2325                                // This is definitely an application process; skip it.
2326                                continue;
2327                            }
2328                            synchronized (mPidsSelfLocked) {
2329                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2330                                    // This is one of our own processes; skip it.
2331                                    continue;
2332                                }
2333                            }
2334                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2335                        }
2336                    }
2337                    memInfo.readMemInfo();
2338                    synchronized (ActivityManagerService.this) {
2339                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2340                                + (SystemClock.uptimeMillis()-start) + "ms");
2341                        final long cachedKb = memInfo.getCachedSizeKb();
2342                        final long freeKb = memInfo.getFreeSizeKb();
2343                        final long zramKb = memInfo.getZramTotalSizeKb();
2344                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2345                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2346                                kernelKb*1024, nativeTotalPss*1024);
2347                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2348                                nativeTotalPss);
2349                    }
2350                }
2351
2352                int num = 0;
2353                long[] tmp = new long[2];
2354                do {
2355                    ProcessRecord proc;
2356                    int procState;
2357                    int pid;
2358                    long lastPssTime;
2359                    synchronized (ActivityManagerService.this) {
2360                        if (mPendingPssProcesses.size() <= 0) {
2361                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2362                                    "Collected PSS of " + num + " processes in "
2363                                    + (SystemClock.uptimeMillis() - start) + "ms");
2364                            mPendingPssProcesses.clear();
2365                            return;
2366                        }
2367                        proc = mPendingPssProcesses.remove(0);
2368                        procState = proc.pssProcState;
2369                        lastPssTime = proc.lastPssTime;
2370                        if (proc.thread != null && procState == proc.setProcState
2371                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2372                                        < SystemClock.uptimeMillis()) {
2373                            pid = proc.pid;
2374                        } else {
2375                            proc = null;
2376                            pid = 0;
2377                        }
2378                    }
2379                    if (proc != null) {
2380                        long pss = Debug.getPss(pid, tmp, null);
2381                        synchronized (ActivityManagerService.this) {
2382                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2383                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2384                                num++;
2385                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2386                                        SystemClock.uptimeMillis());
2387                            }
2388                        }
2389                    }
2390                } while (true);
2391            }
2392            }
2393        }
2394    };
2395
2396    public void setSystemProcess() {
2397        try {
2398            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2399            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2400            ServiceManager.addService("meminfo", new MemBinder(this));
2401            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2402            ServiceManager.addService("dbinfo", new DbBinder(this));
2403            if (MONITOR_CPU_USAGE) {
2404                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2405            }
2406            ServiceManager.addService("permission", new PermissionController(this));
2407            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2408
2409            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2410                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2411            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2412
2413            synchronized (this) {
2414                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2415                app.persistent = true;
2416                app.pid = MY_PID;
2417                app.maxAdj = ProcessList.SYSTEM_ADJ;
2418                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2419                synchronized (mPidsSelfLocked) {
2420                    mPidsSelfLocked.put(app.pid, app);
2421                }
2422                updateLruProcessLocked(app, false, null);
2423                updateOomAdjLocked();
2424            }
2425        } catch (PackageManager.NameNotFoundException e) {
2426            throw new RuntimeException(
2427                    "Unable to find android system package", e);
2428        }
2429    }
2430
2431    public void setWindowManager(WindowManagerService wm) {
2432        mWindowManager = wm;
2433        mStackSupervisor.setWindowManager(wm);
2434        mActivityStarter.setWindowManager(wm);
2435    }
2436
2437    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2438        mUsageStatsService = usageStatsManager;
2439    }
2440
2441    public void startObservingNativeCrashes() {
2442        final NativeCrashListener ncl = new NativeCrashListener(this);
2443        ncl.start();
2444    }
2445
2446    public IAppOpsService getAppOpsService() {
2447        return mAppOpsService;
2448    }
2449
2450    static class MemBinder extends Binder {
2451        ActivityManagerService mActivityManagerService;
2452        MemBinder(ActivityManagerService activityManagerService) {
2453            mActivityManagerService = activityManagerService;
2454        }
2455
2456        @Override
2457        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2458            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2459                    != PackageManager.PERMISSION_GRANTED) {
2460                pw.println("Permission Denial: can't dump meminfo from from pid="
2461                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2462                        + " without permission " + android.Manifest.permission.DUMP);
2463                return;
2464            }
2465
2466            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2467        }
2468    }
2469
2470    static class GraphicsBinder extends Binder {
2471        ActivityManagerService mActivityManagerService;
2472        GraphicsBinder(ActivityManagerService activityManagerService) {
2473            mActivityManagerService = activityManagerService;
2474        }
2475
2476        @Override
2477        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2478            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2479                    != PackageManager.PERMISSION_GRANTED) {
2480                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2481                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2482                        + " without permission " + android.Manifest.permission.DUMP);
2483                return;
2484            }
2485
2486            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2487        }
2488    }
2489
2490    static class DbBinder extends Binder {
2491        ActivityManagerService mActivityManagerService;
2492        DbBinder(ActivityManagerService activityManagerService) {
2493            mActivityManagerService = activityManagerService;
2494        }
2495
2496        @Override
2497        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2498            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2499                    != PackageManager.PERMISSION_GRANTED) {
2500                pw.println("Permission Denial: can't dump dbinfo from from pid="
2501                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2502                        + " without permission " + android.Manifest.permission.DUMP);
2503                return;
2504            }
2505
2506            mActivityManagerService.dumpDbInfo(fd, pw, args);
2507        }
2508    }
2509
2510    static class CpuBinder extends Binder {
2511        ActivityManagerService mActivityManagerService;
2512        CpuBinder(ActivityManagerService activityManagerService) {
2513            mActivityManagerService = activityManagerService;
2514        }
2515
2516        @Override
2517        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2518            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2519                    != PackageManager.PERMISSION_GRANTED) {
2520                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2521                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2522                        + " without permission " + android.Manifest.permission.DUMP);
2523                return;
2524            }
2525
2526            synchronized (mActivityManagerService.mProcessCpuTracker) {
2527                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2528                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2529                        SystemClock.uptimeMillis()));
2530            }
2531        }
2532    }
2533
2534    public static final class Lifecycle extends SystemService {
2535        private final ActivityManagerService mService;
2536
2537        public Lifecycle(Context context) {
2538            super(context);
2539            mService = new ActivityManagerService(context);
2540        }
2541
2542        @Override
2543        public void onStart() {
2544            mService.start();
2545        }
2546
2547        public ActivityManagerService getService() {
2548            return mService;
2549        }
2550    }
2551
2552    // Note: This method is invoked on the main thread but may need to attach various
2553    // handlers to other threads.  So take care to be explicit about the looper.
2554    public ActivityManagerService(Context systemContext) {
2555        mContext = systemContext;
2556        mFactoryTest = FactoryTest.getMode();
2557        mSystemThread = ActivityThread.currentActivityThread();
2558
2559        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2560
2561        mHandlerThread = new ServiceThread(TAG,
2562                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2563        mHandlerThread.start();
2564        mHandler = new MainHandler(mHandlerThread.getLooper());
2565        mUiHandler = new UiHandler();
2566
2567        /* static; one-time init here */
2568        if (sKillHandler == null) {
2569            sKillThread = new ServiceThread(TAG + ":kill",
2570                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2571            sKillThread.start();
2572            sKillHandler = new KillHandler(sKillThread.getLooper());
2573        }
2574
2575        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2576                "foreground", BROADCAST_FG_TIMEOUT, false);
2577        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2578                "background", BROADCAST_BG_TIMEOUT, true);
2579        mBroadcastQueues[0] = mFgBroadcastQueue;
2580        mBroadcastQueues[1] = mBgBroadcastQueue;
2581
2582        mServices = new ActiveServices(this);
2583        mProviderMap = new ProviderMap(this);
2584        mAppErrors = new AppErrors(mContext, this);
2585
2586        // TODO: Move creation of battery stats service outside of activity manager service.
2587        File dataDir = Environment.getDataDirectory();
2588        File systemDir = new File(dataDir, "system");
2589        systemDir.mkdirs();
2590        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2591        mBatteryStatsService.getActiveStatistics().readLocked();
2592        mBatteryStatsService.scheduleWriteToDisk();
2593        mOnBattery = DEBUG_POWER ? true
2594                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2595        mBatteryStatsService.getActiveStatistics().setCallback(this);
2596
2597        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2598
2599        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2600        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2601                new IAppOpsCallback.Stub() {
2602                    @Override public void opChanged(int op, int uid, String packageName) {
2603                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2604                            if (mAppOpsService.checkOperation(op, uid, packageName)
2605                                    != AppOpsManager.MODE_ALLOWED) {
2606                                runInBackgroundDisabled(uid);
2607                            }
2608                        }
2609                    }
2610                });
2611
2612        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2613
2614        mUserController = new UserController(this);
2615
2616        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2617            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2618
2619        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2620
2621        mConfiguration.setToDefaults();
2622        mConfiguration.setLocales(LocaleList.getDefault());
2623
2624        mConfigurationSeq = mConfiguration.seq = 1;
2625        mProcessCpuTracker.init();
2626
2627        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2628        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2629        mStackSupervisor = new ActivityStackSupervisor(this);
2630        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2631        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2632
2633        mProcessCpuThread = new Thread("CpuTracker") {
2634            @Override
2635            public void run() {
2636                while (true) {
2637                    try {
2638                        try {
2639                            synchronized(this) {
2640                                final long now = SystemClock.uptimeMillis();
2641                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2642                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2643                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2644                                //        + ", write delay=" + nextWriteDelay);
2645                                if (nextWriteDelay < nextCpuDelay) {
2646                                    nextCpuDelay = nextWriteDelay;
2647                                }
2648                                if (nextCpuDelay > 0) {
2649                                    mProcessCpuMutexFree.set(true);
2650                                    this.wait(nextCpuDelay);
2651                                }
2652                            }
2653                        } catch (InterruptedException e) {
2654                        }
2655                        updateCpuStatsNow();
2656                    } catch (Exception e) {
2657                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2658                    }
2659                }
2660            }
2661        };
2662
2663        Watchdog.getInstance().addMonitor(this);
2664        Watchdog.getInstance().addThread(mHandler);
2665    }
2666
2667    public void setSystemServiceManager(SystemServiceManager mgr) {
2668        mSystemServiceManager = mgr;
2669    }
2670
2671    public void setInstaller(Installer installer) {
2672        mInstaller = installer;
2673    }
2674
2675    private void start() {
2676        Process.removeAllProcessGroups();
2677        mProcessCpuThread.start();
2678
2679        mBatteryStatsService.publish(mContext);
2680        mAppOpsService.publish(mContext);
2681        Slog.d("AppOps", "AppOpsService published");
2682        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2683    }
2684
2685    void onUserStoppedLocked(int userId) {
2686        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2687    }
2688
2689    public void initPowerManagement() {
2690        mStackSupervisor.initPowerManagement();
2691        mBatteryStatsService.initPowerManagement();
2692        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2693        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2694        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2695        mVoiceWakeLock.setReferenceCounted(false);
2696    }
2697
2698    @Override
2699    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2700            throws RemoteException {
2701        if (code == SYSPROPS_TRANSACTION) {
2702            // We need to tell all apps about the system property change.
2703            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2704            synchronized(this) {
2705                final int NP = mProcessNames.getMap().size();
2706                for (int ip=0; ip<NP; ip++) {
2707                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2708                    final int NA = apps.size();
2709                    for (int ia=0; ia<NA; ia++) {
2710                        ProcessRecord app = apps.valueAt(ia);
2711                        if (app.thread != null) {
2712                            procs.add(app.thread.asBinder());
2713                        }
2714                    }
2715                }
2716            }
2717
2718            int N = procs.size();
2719            for (int i=0; i<N; i++) {
2720                Parcel data2 = Parcel.obtain();
2721                try {
2722                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2723                } catch (RemoteException e) {
2724                }
2725                data2.recycle();
2726            }
2727        }
2728        try {
2729            return super.onTransact(code, data, reply, flags);
2730        } catch (RuntimeException e) {
2731            // The activity manager only throws security exceptions, so let's
2732            // log all others.
2733            if (!(e instanceof SecurityException)) {
2734                Slog.wtf(TAG, "Activity Manager Crash", e);
2735            }
2736            throw e;
2737        }
2738    }
2739
2740    void updateCpuStats() {
2741        final long now = SystemClock.uptimeMillis();
2742        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2743            return;
2744        }
2745        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2746            synchronized (mProcessCpuThread) {
2747                mProcessCpuThread.notify();
2748            }
2749        }
2750    }
2751
2752    void updateCpuStatsNow() {
2753        synchronized (mProcessCpuTracker) {
2754            mProcessCpuMutexFree.set(false);
2755            final long now = SystemClock.uptimeMillis();
2756            boolean haveNewCpuStats = false;
2757
2758            if (MONITOR_CPU_USAGE &&
2759                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2760                mLastCpuTime.set(now);
2761                mProcessCpuTracker.update();
2762                if (mProcessCpuTracker.hasGoodLastStats()) {
2763                    haveNewCpuStats = true;
2764                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2765                    //Slog.i(TAG, "Total CPU usage: "
2766                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2767
2768                    // Slog the cpu usage if the property is set.
2769                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2770                        int user = mProcessCpuTracker.getLastUserTime();
2771                        int system = mProcessCpuTracker.getLastSystemTime();
2772                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2773                        int irq = mProcessCpuTracker.getLastIrqTime();
2774                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2775                        int idle = mProcessCpuTracker.getLastIdleTime();
2776
2777                        int total = user + system + iowait + irq + softIrq + idle;
2778                        if (total == 0) total = 1;
2779
2780                        EventLog.writeEvent(EventLogTags.CPU,
2781                                ((user+system+iowait+irq+softIrq) * 100) / total,
2782                                (user * 100) / total,
2783                                (system * 100) / total,
2784                                (iowait * 100) / total,
2785                                (irq * 100) / total,
2786                                (softIrq * 100) / total);
2787                    }
2788                }
2789            }
2790
2791            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2792            synchronized(bstats) {
2793                synchronized(mPidsSelfLocked) {
2794                    if (haveNewCpuStats) {
2795                        if (bstats.startAddingCpuLocked()) {
2796                            int totalUTime = 0;
2797                            int totalSTime = 0;
2798                            final int N = mProcessCpuTracker.countStats();
2799                            for (int i=0; i<N; i++) {
2800                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2801                                if (!st.working) {
2802                                    continue;
2803                                }
2804                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2805                                totalUTime += st.rel_utime;
2806                                totalSTime += st.rel_stime;
2807                                if (pr != null) {
2808                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2809                                    if (ps == null || !ps.isActive()) {
2810                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2811                                                pr.info.uid, pr.processName);
2812                                    }
2813                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2814                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2815                                } else {
2816                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2817                                    if (ps == null || !ps.isActive()) {
2818                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2819                                                bstats.mapUid(st.uid), st.name);
2820                                    }
2821                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2822                                }
2823                            }
2824                            final int userTime = mProcessCpuTracker.getLastUserTime();
2825                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2826                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2827                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2828                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2829                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2830                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2831                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2832                        }
2833                    }
2834                }
2835
2836                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2837                    mLastWriteTime = now;
2838                    mBatteryStatsService.scheduleWriteToDisk();
2839                }
2840            }
2841        }
2842    }
2843
2844    @Override
2845    public void batteryNeedsCpuUpdate() {
2846        updateCpuStatsNow();
2847    }
2848
2849    @Override
2850    public void batteryPowerChanged(boolean onBattery) {
2851        // When plugging in, update the CPU stats first before changing
2852        // the plug state.
2853        updateCpuStatsNow();
2854        synchronized (this) {
2855            synchronized(mPidsSelfLocked) {
2856                mOnBattery = DEBUG_POWER ? true : onBattery;
2857            }
2858        }
2859    }
2860
2861    @Override
2862    public void batterySendBroadcast(Intent intent) {
2863        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2864                AppOpsManager.OP_NONE, null, false, false,
2865                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2866    }
2867
2868    /**
2869     * Initialize the application bind args. These are passed to each
2870     * process when the bindApplication() IPC is sent to the process. They're
2871     * lazily setup to make sure the services are running when they're asked for.
2872     */
2873    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2874        if (mAppBindArgs == null) {
2875            mAppBindArgs = new HashMap<>();
2876
2877            // Isolated processes won't get this optimization, so that we don't
2878            // violate the rules about which services they have access to.
2879            if (!isolated) {
2880                // Setup the application init args
2881                mAppBindArgs.put("package", ServiceManager.getService("package"));
2882                mAppBindArgs.put("window", ServiceManager.getService("window"));
2883                mAppBindArgs.put(Context.ALARM_SERVICE,
2884                        ServiceManager.getService(Context.ALARM_SERVICE));
2885            }
2886        }
2887        return mAppBindArgs;
2888    }
2889
2890    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2891        if (r == null || mFocusedActivity == r) {
2892            return false;
2893        }
2894
2895        if (!r.isFocusable()) {
2896            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2897            return false;
2898        }
2899
2900        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2901
2902        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2903        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2904                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2905        mDoingSetFocusedActivity = true;
2906
2907        final ActivityRecord last = mFocusedActivity;
2908        mFocusedActivity = r;
2909        if (r.task.isApplicationTask()) {
2910            if (mCurAppTimeTracker != r.appTimeTracker) {
2911                // We are switching app tracking.  Complete the current one.
2912                if (mCurAppTimeTracker != null) {
2913                    mCurAppTimeTracker.stop();
2914                    mHandler.obtainMessage(
2915                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2916                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2917                    mCurAppTimeTracker = null;
2918                }
2919                if (r.appTimeTracker != null) {
2920                    mCurAppTimeTracker = r.appTimeTracker;
2921                    startTimeTrackingFocusedActivityLocked();
2922                }
2923            } else {
2924                startTimeTrackingFocusedActivityLocked();
2925            }
2926        } else {
2927            r.appTimeTracker = null;
2928        }
2929        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2930        // TODO: Probably not, because we don't want to resume voice on switching
2931        // back to this activity
2932        if (r.task.voiceInteractor != null) {
2933            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2934        } else {
2935            finishRunningVoiceLocked();
2936            IVoiceInteractionSession session;
2937            if (last != null && ((session = last.task.voiceSession) != null
2938                    || (session = last.voiceSession) != null)) {
2939                // We had been in a voice interaction session, but now focused has
2940                // move to something different.  Just finish the session, we can't
2941                // return to it and retain the proper state and synchronization with
2942                // the voice interaction service.
2943                finishVoiceTask(session);
2944            }
2945        }
2946        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2947            mWindowManager.setFocusedApp(r.appToken, true);
2948        }
2949        applyUpdateLockStateLocked(r);
2950        applyUpdateVrModeLocked(r);
2951        if (mFocusedActivity.userId != mLastFocusedUserId) {
2952            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2953            mHandler.obtainMessage(
2954                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2955            mLastFocusedUserId = mFocusedActivity.userId;
2956        }
2957
2958        // Log a warning if the focused app is changed during the process. This could
2959        // indicate a problem of the focus setting logic!
2960        if (mFocusedActivity != r) Slog.w(TAG,
2961                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2962        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2963
2964        EventLogTags.writeAmFocusedActivity(
2965                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2966                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2967                reason);
2968        return true;
2969    }
2970
2971    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2972        if (mFocusedActivity != goingAway) {
2973            return;
2974        }
2975
2976        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2977        if (focusedStack != null) {
2978            final ActivityRecord top = focusedStack.topActivity();
2979            if (top != null && top.userId != mLastFocusedUserId) {
2980                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2981                mHandler.sendMessage(
2982                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2983                mLastFocusedUserId = top.userId;
2984            }
2985        }
2986
2987        // Try to move focus to another activity if possible.
2988        if (setFocusedActivityLocked(
2989                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2990            return;
2991        }
2992
2993        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2994                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2995        mFocusedActivity = null;
2996        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2997    }
2998
2999    @Override
3000    public void setFocusedStack(int stackId) {
3001        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3002        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3003        final long callingId = Binder.clearCallingIdentity();
3004        try {
3005            synchronized (this) {
3006                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3007                if (stack == null) {
3008                    return;
3009                }
3010                final ActivityRecord r = stack.topRunningActivityLocked();
3011                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3012                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3013                }
3014            }
3015        } finally {
3016            Binder.restoreCallingIdentity(callingId);
3017        }
3018    }
3019
3020    @Override
3021    public void setFocusedTask(int taskId) {
3022        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3023        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3024        final long callingId = Binder.clearCallingIdentity();
3025        try {
3026            synchronized (this) {
3027                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3028                if (task == null) {
3029                    return;
3030                }
3031                final ActivityRecord r = task.topRunningActivityLocked();
3032                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3033                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3034                }
3035            }
3036        } finally {
3037            Binder.restoreCallingIdentity(callingId);
3038        }
3039    }
3040
3041    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3042    @Override
3043    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3044        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3045        synchronized (this) {
3046            if (listener != null) {
3047                mTaskStackListeners.register(listener);
3048            }
3049        }
3050    }
3051
3052    @Override
3053    public void notifyActivityDrawn(IBinder token) {
3054        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3055        synchronized (this) {
3056            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3057            if (r != null) {
3058                r.task.stack.notifyActivityDrawnLocked(r);
3059            }
3060        }
3061    }
3062
3063    final void applyUpdateLockStateLocked(ActivityRecord r) {
3064        // Modifications to the UpdateLock state are done on our handler, outside
3065        // the activity manager's locks.  The new state is determined based on the
3066        // state *now* of the relevant activity record.  The object is passed to
3067        // the handler solely for logging detail, not to be consulted/modified.
3068        final boolean nextState = r != null && r.immersive;
3069        mHandler.sendMessage(
3070                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3071    }
3072
3073    final void applyUpdateVrModeLocked(ActivityRecord r) {
3074        mHandler.sendMessage(
3075                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3076    }
3077
3078    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3079        mHandler.sendMessage(
3080                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3081    }
3082
3083    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3084        Message msg = Message.obtain();
3085        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3086        msg.obj = r.task.askedCompatMode ? null : r;
3087        mUiHandler.sendMessage(msg);
3088    }
3089
3090    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3091            String what, Object obj, ProcessRecord srcApp) {
3092        app.lastActivityTime = now;
3093
3094        if (app.activities.size() > 0) {
3095            // Don't want to touch dependent processes that are hosting activities.
3096            return index;
3097        }
3098
3099        int lrui = mLruProcesses.lastIndexOf(app);
3100        if (lrui < 0) {
3101            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3102                    + what + " " + obj + " from " + srcApp);
3103            return index;
3104        }
3105
3106        if (lrui >= index) {
3107            // Don't want to cause this to move dependent processes *back* in the
3108            // list as if they were less frequently used.
3109            return index;
3110        }
3111
3112        if (lrui >= mLruProcessActivityStart) {
3113            // Don't want to touch dependent processes that are hosting activities.
3114            return index;
3115        }
3116
3117        mLruProcesses.remove(lrui);
3118        if (index > 0) {
3119            index--;
3120        }
3121        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3122                + " in LRU list: " + app);
3123        mLruProcesses.add(index, app);
3124        return index;
3125    }
3126
3127    static void killProcessGroup(int uid, int pid) {
3128        if (sKillHandler != null) {
3129            sKillHandler.sendMessage(
3130                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3131        } else {
3132            Slog.w(TAG, "Asked to kill process group before system bringup!");
3133            Process.killProcessGroup(uid, pid);
3134        }
3135    }
3136
3137    final void removeLruProcessLocked(ProcessRecord app) {
3138        int lrui = mLruProcesses.lastIndexOf(app);
3139        if (lrui >= 0) {
3140            if (!app.killed) {
3141                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3142                Process.killProcessQuiet(app.pid);
3143                killProcessGroup(app.uid, app.pid);
3144            }
3145            if (lrui <= mLruProcessActivityStart) {
3146                mLruProcessActivityStart--;
3147            }
3148            if (lrui <= mLruProcessServiceStart) {
3149                mLruProcessServiceStart--;
3150            }
3151            mLruProcesses.remove(lrui);
3152        }
3153    }
3154
3155    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3156            ProcessRecord client) {
3157        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3158                || app.treatLikeActivity;
3159        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3160        if (!activityChange && hasActivity) {
3161            // The process has activities, so we are only allowing activity-based adjustments
3162            // to move it.  It should be kept in the front of the list with other
3163            // processes that have activities, and we don't want those to change their
3164            // order except due to activity operations.
3165            return;
3166        }
3167
3168        mLruSeq++;
3169        final long now = SystemClock.uptimeMillis();
3170        app.lastActivityTime = now;
3171
3172        // First a quick reject: if the app is already at the position we will
3173        // put it, then there is nothing to do.
3174        if (hasActivity) {
3175            final int N = mLruProcesses.size();
3176            if (N > 0 && mLruProcesses.get(N-1) == app) {
3177                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3178                return;
3179            }
3180        } else {
3181            if (mLruProcessServiceStart > 0
3182                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3183                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3184                return;
3185            }
3186        }
3187
3188        int lrui = mLruProcesses.lastIndexOf(app);
3189
3190        if (app.persistent && lrui >= 0) {
3191            // We don't care about the position of persistent processes, as long as
3192            // they are in the list.
3193            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3194            return;
3195        }
3196
3197        /* In progress: compute new position first, so we can avoid doing work
3198           if the process is not actually going to move.  Not yet working.
3199        int addIndex;
3200        int nextIndex;
3201        boolean inActivity = false, inService = false;
3202        if (hasActivity) {
3203            // Process has activities, put it at the very tipsy-top.
3204            addIndex = mLruProcesses.size();
3205            nextIndex = mLruProcessServiceStart;
3206            inActivity = true;
3207        } else if (hasService) {
3208            // Process has services, put it at the top of the service list.
3209            addIndex = mLruProcessActivityStart;
3210            nextIndex = mLruProcessServiceStart;
3211            inActivity = true;
3212            inService = true;
3213        } else  {
3214            // Process not otherwise of interest, it goes to the top of the non-service area.
3215            addIndex = mLruProcessServiceStart;
3216            if (client != null) {
3217                int clientIndex = mLruProcesses.lastIndexOf(client);
3218                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3219                        + app);
3220                if (clientIndex >= 0 && addIndex > clientIndex) {
3221                    addIndex = clientIndex;
3222                }
3223            }
3224            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3225        }
3226
3227        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3228                + mLruProcessActivityStart + "): " + app);
3229        */
3230
3231        if (lrui >= 0) {
3232            if (lrui < mLruProcessActivityStart) {
3233                mLruProcessActivityStart--;
3234            }
3235            if (lrui < mLruProcessServiceStart) {
3236                mLruProcessServiceStart--;
3237            }
3238            /*
3239            if (addIndex > lrui) {
3240                addIndex--;
3241            }
3242            if (nextIndex > lrui) {
3243                nextIndex--;
3244            }
3245            */
3246            mLruProcesses.remove(lrui);
3247        }
3248
3249        /*
3250        mLruProcesses.add(addIndex, app);
3251        if (inActivity) {
3252            mLruProcessActivityStart++;
3253        }
3254        if (inService) {
3255            mLruProcessActivityStart++;
3256        }
3257        */
3258
3259        int nextIndex;
3260        if (hasActivity) {
3261            final int N = mLruProcesses.size();
3262            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3263                // Process doesn't have activities, but has clients with
3264                // activities...  move it up, but one below the top (the top
3265                // should always have a real activity).
3266                if (DEBUG_LRU) Slog.d(TAG_LRU,
3267                        "Adding to second-top of LRU activity list: " + app);
3268                mLruProcesses.add(N - 1, app);
3269                // To keep it from spamming the LRU list (by making a bunch of clients),
3270                // we will push down any other entries owned by the app.
3271                final int uid = app.info.uid;
3272                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3273                    ProcessRecord subProc = mLruProcesses.get(i);
3274                    if (subProc.info.uid == uid) {
3275                        // We want to push this one down the list.  If the process after
3276                        // it is for the same uid, however, don't do so, because we don't
3277                        // want them internally to be re-ordered.
3278                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3279                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3280                                    "Pushing uid " + uid + " swapping at " + i + ": "
3281                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3282                            ProcessRecord tmp = mLruProcesses.get(i);
3283                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3284                            mLruProcesses.set(i - 1, tmp);
3285                            i--;
3286                        }
3287                    } else {
3288                        // A gap, we can stop here.
3289                        break;
3290                    }
3291                }
3292            } else {
3293                // Process has activities, put it at the very tipsy-top.
3294                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3295                mLruProcesses.add(app);
3296            }
3297            nextIndex = mLruProcessServiceStart;
3298        } else if (hasService) {
3299            // Process has services, put it at the top of the service list.
3300            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3301            mLruProcesses.add(mLruProcessActivityStart, app);
3302            nextIndex = mLruProcessServiceStart;
3303            mLruProcessActivityStart++;
3304        } else  {
3305            // Process not otherwise of interest, it goes to the top of the non-service area.
3306            int index = mLruProcessServiceStart;
3307            if (client != null) {
3308                // If there is a client, don't allow the process to be moved up higher
3309                // in the list than that client.
3310                int clientIndex = mLruProcesses.lastIndexOf(client);
3311                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3312                        + " when updating " + app);
3313                if (clientIndex <= lrui) {
3314                    // Don't allow the client index restriction to push it down farther in the
3315                    // list than it already is.
3316                    clientIndex = lrui;
3317                }
3318                if (clientIndex >= 0 && index > clientIndex) {
3319                    index = clientIndex;
3320                }
3321            }
3322            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3323            mLruProcesses.add(index, app);
3324            nextIndex = index-1;
3325            mLruProcessActivityStart++;
3326            mLruProcessServiceStart++;
3327        }
3328
3329        // If the app is currently using a content provider or service,
3330        // bump those processes as well.
3331        for (int j=app.connections.size()-1; j>=0; j--) {
3332            ConnectionRecord cr = app.connections.valueAt(j);
3333            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3334                    && cr.binding.service.app != null
3335                    && cr.binding.service.app.lruSeq != mLruSeq
3336                    && !cr.binding.service.app.persistent) {
3337                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3338                        "service connection", cr, app);
3339            }
3340        }
3341        for (int j=app.conProviders.size()-1; j>=0; j--) {
3342            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3343            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3344                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3345                        "provider reference", cpr, app);
3346            }
3347        }
3348    }
3349
3350    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3351        if (uid == Process.SYSTEM_UID) {
3352            // The system gets to run in any process.  If there are multiple
3353            // processes with the same uid, just pick the first (this
3354            // should never happen).
3355            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3356            if (procs == null) return null;
3357            final int procCount = procs.size();
3358            for (int i = 0; i < procCount; i++) {
3359                final int procUid = procs.keyAt(i);
3360                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3361                    // Don't use an app process or different user process for system component.
3362                    continue;
3363                }
3364                return procs.valueAt(i);
3365            }
3366        }
3367        ProcessRecord proc = mProcessNames.get(processName, uid);
3368        if (false && proc != null && !keepIfLarge
3369                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3370                && proc.lastCachedPss >= 4000) {
3371            // Turn this condition on to cause killing to happen regularly, for testing.
3372            if (proc.baseProcessTracker != null) {
3373                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3374            }
3375            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3376        } else if (proc != null && !keepIfLarge
3377                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3378                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3379            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3380            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3381                if (proc.baseProcessTracker != null) {
3382                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3383                }
3384                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3385            }
3386        }
3387        return proc;
3388    }
3389
3390    void notifyPackageUse(String packageName, int reason) {
3391        IPackageManager pm = AppGlobals.getPackageManager();
3392        try {
3393            pm.notifyPackageUse(packageName, reason);
3394        } catch (RemoteException e) {
3395        }
3396    }
3397
3398    boolean isNextTransitionForward() {
3399        int transit = mWindowManager.getPendingAppTransition();
3400        return transit == TRANSIT_ACTIVITY_OPEN
3401                || transit == TRANSIT_TASK_OPEN
3402                || transit == TRANSIT_TASK_TO_FRONT;
3403    }
3404
3405    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3406            String processName, String abiOverride, int uid, Runnable crashHandler) {
3407        synchronized(this) {
3408            ApplicationInfo info = new ApplicationInfo();
3409            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3410            // For isolated processes, the former contains the parent's uid and the latter the
3411            // actual uid of the isolated process.
3412            // In the special case introduced by this method (which is, starting an isolated
3413            // process directly from the SystemServer without an actual parent app process) the
3414            // closest thing to a parent's uid is SYSTEM_UID.
3415            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3416            // the |isolated| logic in the ProcessRecord constructor.
3417            info.uid = Process.SYSTEM_UID;
3418            info.processName = processName;
3419            info.className = entryPoint;
3420            info.packageName = "android";
3421            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3422                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3423                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3424                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3425                    crashHandler);
3426            return proc != null ? proc.pid : 0;
3427        }
3428    }
3429
3430    final ProcessRecord startProcessLocked(String processName,
3431            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3432            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3433            boolean isolated, boolean keepIfLarge) {
3434        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3435                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3436                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3437                null /* crashHandler */);
3438    }
3439
3440    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3441            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3442            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3443            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3444        long startTime = SystemClock.elapsedRealtime();
3445        ProcessRecord app;
3446        if (!isolated) {
3447            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3448            checkTime(startTime, "startProcess: after getProcessRecord");
3449
3450            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3451                // If we are in the background, then check to see if this process
3452                // is bad.  If so, we will just silently fail.
3453                if (mAppErrors.isBadProcessLocked(info)) {
3454                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3455                            + "/" + info.processName);
3456                    return null;
3457                }
3458            } else {
3459                // When the user is explicitly starting a process, then clear its
3460                // crash count so that we won't make it bad until they see at
3461                // least one crash dialog again, and make the process good again
3462                // if it had been bad.
3463                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3464                        + "/" + info.processName);
3465                mAppErrors.resetProcessCrashTimeLocked(info);
3466                if (mAppErrors.isBadProcessLocked(info)) {
3467                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3468                            UserHandle.getUserId(info.uid), info.uid,
3469                            info.processName);
3470                    mAppErrors.clearBadProcessLocked(info);
3471                    if (app != null) {
3472                        app.bad = false;
3473                    }
3474                }
3475            }
3476        } else {
3477            // If this is an isolated process, it can't re-use an existing process.
3478            app = null;
3479        }
3480
3481        // app launch boost for big.little configurations
3482        // use cpusets to migrate freshly launched tasks to big cores
3483        synchronized(ActivityManagerService.this) {
3484            nativeMigrateToBoost();
3485            mIsBoosted = true;
3486            mBoostStartTime = SystemClock.uptimeMillis();
3487            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3488            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3489        }
3490
3491        // We don't have to do anything more if:
3492        // (1) There is an existing application record; and
3493        // (2) The caller doesn't think it is dead, OR there is no thread
3494        //     object attached to it so we know it couldn't have crashed; and
3495        // (3) There is a pid assigned to it, so it is either starting or
3496        //     already running.
3497        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3498                + " app=" + app + " knownToBeDead=" + knownToBeDead
3499                + " thread=" + (app != null ? app.thread : null)
3500                + " pid=" + (app != null ? app.pid : -1));
3501        if (app != null && app.pid > 0) {
3502            if (!knownToBeDead || app.thread == null) {
3503                // We already have the app running, or are waiting for it to
3504                // come up (we have a pid but not yet its thread), so keep it.
3505                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3506                // If this is a new package in the process, add the package to the list
3507                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3508                checkTime(startTime, "startProcess: done, added package to proc");
3509                return app;
3510            }
3511
3512            // An application record is attached to a previous process,
3513            // clean it up now.
3514            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3515            checkTime(startTime, "startProcess: bad proc running, killing");
3516            killProcessGroup(app.uid, app.pid);
3517            handleAppDiedLocked(app, true, true);
3518            checkTime(startTime, "startProcess: done killing old proc");
3519        }
3520
3521        String hostingNameStr = hostingName != null
3522                ? hostingName.flattenToShortString() : null;
3523
3524        if (app == null) {
3525            checkTime(startTime, "startProcess: creating new process record");
3526            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3527            if (app == null) {
3528                Slog.w(TAG, "Failed making new process record for "
3529                        + processName + "/" + info.uid + " isolated=" + isolated);
3530                return null;
3531            }
3532            app.crashHandler = crashHandler;
3533            checkTime(startTime, "startProcess: done creating new process record");
3534        } else {
3535            // If this is a new package in the process, add the package to the list
3536            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3537            checkTime(startTime, "startProcess: added package to existing proc");
3538        }
3539
3540        // If the system is not ready yet, then hold off on starting this
3541        // process until it is.
3542        if (!mProcessesReady
3543                && !isAllowedWhileBooting(info)
3544                && !allowWhileBooting) {
3545            if (!mProcessesOnHold.contains(app)) {
3546                mProcessesOnHold.add(app);
3547            }
3548            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3549                    "System not ready, putting on hold: " + app);
3550            checkTime(startTime, "startProcess: returning with proc on hold");
3551            return app;
3552        }
3553
3554        checkTime(startTime, "startProcess: stepping in to startProcess");
3555        startProcessLocked(
3556                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3557        checkTime(startTime, "startProcess: done starting proc!");
3558        return (app.pid != 0) ? app : null;
3559    }
3560
3561    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3562        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3563    }
3564
3565    private final void startProcessLocked(ProcessRecord app,
3566            String hostingType, String hostingNameStr) {
3567        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3568                null /* entryPoint */, null /* entryPointArgs */);
3569    }
3570
3571    private final void startProcessLocked(ProcessRecord app, String hostingType,
3572            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3573        long startTime = SystemClock.elapsedRealtime();
3574        if (app.pid > 0 && app.pid != MY_PID) {
3575            checkTime(startTime, "startProcess: removing from pids map");
3576            synchronized (mPidsSelfLocked) {
3577                mPidsSelfLocked.remove(app.pid);
3578                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3579            }
3580            checkTime(startTime, "startProcess: done removing from pids map");
3581            app.setPid(0);
3582        }
3583
3584        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3585                "startProcessLocked removing on hold: " + app);
3586        mProcessesOnHold.remove(app);
3587
3588        checkTime(startTime, "startProcess: starting to update cpu stats");
3589        updateCpuStats();
3590        checkTime(startTime, "startProcess: done updating cpu stats");
3591
3592        try {
3593            try {
3594                final int userId = UserHandle.getUserId(app.uid);
3595                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3596            } catch (RemoteException e) {
3597                throw e.rethrowAsRuntimeException();
3598            }
3599
3600            int uid = app.uid;
3601            int[] gids = null;
3602            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3603            if (!app.isolated) {
3604                int[] permGids = null;
3605                try {
3606                    checkTime(startTime, "startProcess: getting gids from package manager");
3607                    final IPackageManager pm = AppGlobals.getPackageManager();
3608                    permGids = pm.getPackageGids(app.info.packageName,
3609                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3610                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3611                            MountServiceInternal.class);
3612                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3613                            app.info.packageName);
3614                } catch (RemoteException e) {
3615                    throw e.rethrowAsRuntimeException();
3616                }
3617
3618                /*
3619                 * Add shared application and profile GIDs so applications can share some
3620                 * resources like shared libraries and access user-wide resources
3621                 */
3622                if (ArrayUtils.isEmpty(permGids)) {
3623                    gids = new int[2];
3624                } else {
3625                    gids = new int[permGids.length + 2];
3626                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3627                }
3628                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3629                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3630            }
3631            checkTime(startTime, "startProcess: building args");
3632            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3633                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3634                        && mTopComponent != null
3635                        && app.processName.equals(mTopComponent.getPackageName())) {
3636                    uid = 0;
3637                }
3638                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3639                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3640                    uid = 0;
3641                }
3642            }
3643            int debugFlags = 0;
3644            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3645                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3646                // Also turn on CheckJNI for debuggable apps. It's quite
3647                // awkward to turn on otherwise.
3648                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3649            }
3650            // Run the app in safe mode if its manifest requests so or the
3651            // system is booted in safe mode.
3652            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3653                mSafeMode == true) {
3654                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3655            }
3656            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3657                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3658            }
3659            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3660            if ("true".equals(genDebugInfoProperty)) {
3661                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3662            }
3663            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3664                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3665            }
3666            if ("1".equals(SystemProperties.get("debug.assert"))) {
3667                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3668            }
3669            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3670                // Enable all debug flags required by the native debugger.
3671                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3672                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3673                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3674                mNativeDebuggingApp = null;
3675            }
3676
3677            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3678            if (requiredAbi == null) {
3679                requiredAbi = Build.SUPPORTED_ABIS[0];
3680            }
3681
3682            String instructionSet = null;
3683            if (app.info.primaryCpuAbi != null) {
3684                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3685            }
3686
3687            app.gids = gids;
3688            app.requiredAbi = requiredAbi;
3689            app.instructionSet = instructionSet;
3690
3691            // Start the process.  It will either succeed and return a result containing
3692            // the PID of the new process, or else throw a RuntimeException.
3693            boolean isActivityProcess = (entryPoint == null);
3694            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3695            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3696                    app.processName);
3697            checkTime(startTime, "startProcess: asking zygote to start proc");
3698            Process.ProcessStartResult startResult = Process.start(entryPoint,
3699                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3700                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3701                    app.info.dataDir, entryPointArgs);
3702            checkTime(startTime, "startProcess: returned from zygote!");
3703            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3704
3705            if (app.isolated) {
3706                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3707            }
3708            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3709            checkTime(startTime, "startProcess: done updating battery stats");
3710
3711            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3712                    UserHandle.getUserId(uid), startResult.pid, uid,
3713                    app.processName, hostingType,
3714                    hostingNameStr != null ? hostingNameStr : "");
3715
3716            try {
3717                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3718                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3719            } catch (RemoteException ex) {
3720                // Ignore
3721            }
3722
3723            if (app.persistent) {
3724                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3725            }
3726
3727            checkTime(startTime, "startProcess: building log message");
3728            StringBuilder buf = mStringBuilder;
3729            buf.setLength(0);
3730            buf.append("Start proc ");
3731            buf.append(startResult.pid);
3732            buf.append(':');
3733            buf.append(app.processName);
3734            buf.append('/');
3735            UserHandle.formatUid(buf, uid);
3736            if (!isActivityProcess) {
3737                buf.append(" [");
3738                buf.append(entryPoint);
3739                buf.append("]");
3740            }
3741            buf.append(" for ");
3742            buf.append(hostingType);
3743            if (hostingNameStr != null) {
3744                buf.append(" ");
3745                buf.append(hostingNameStr);
3746            }
3747            Slog.i(TAG, buf.toString());
3748            app.setPid(startResult.pid);
3749            app.usingWrapper = startResult.usingWrapper;
3750            app.removed = false;
3751            app.killed = false;
3752            app.killedByAm = false;
3753            checkTime(startTime, "startProcess: starting to update pids map");
3754            synchronized (mPidsSelfLocked) {
3755                this.mPidsSelfLocked.put(startResult.pid, app);
3756                if (isActivityProcess) {
3757                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3758                    msg.obj = app;
3759                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3760                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3761                }
3762            }
3763            checkTime(startTime, "startProcess: done updating pids map");
3764        } catch (RuntimeException e) {
3765            Slog.e(TAG, "Failure starting process " + app.processName, e);
3766
3767            // Something went very wrong while trying to start this process; one
3768            // common case is when the package is frozen due to an active
3769            // upgrade. To recover, clean up any active bookkeeping related to
3770            // starting this process. (We already invoked this method once when
3771            // the package was initially frozen through KILL_APPLICATION_MSG, so
3772            // it doesn't hurt to use it again.)
3773            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3774                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3775        }
3776    }
3777
3778    void updateUsageStats(ActivityRecord component, boolean resumed) {
3779        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3780                "updateUsageStats: comp=" + component + "res=" + resumed);
3781        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3782        if (resumed) {
3783            if (mUsageStatsService != null) {
3784                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3785                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3786            }
3787            synchronized (stats) {
3788                stats.noteActivityResumedLocked(component.app.uid);
3789            }
3790        } else {
3791            if (mUsageStatsService != null) {
3792                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3793                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3794            }
3795            synchronized (stats) {
3796                stats.noteActivityPausedLocked(component.app.uid);
3797            }
3798        }
3799    }
3800
3801    Intent getHomeIntent() {
3802        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3803        intent.setComponent(mTopComponent);
3804        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3805        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3806            intent.addCategory(Intent.CATEGORY_HOME);
3807        }
3808        return intent;
3809    }
3810
3811    boolean startHomeActivityLocked(int userId, String reason) {
3812        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3813                && mTopAction == null) {
3814            // We are running in factory test mode, but unable to find
3815            // the factory test app, so just sit around displaying the
3816            // error message and don't try to start anything.
3817            return false;
3818        }
3819        Intent intent = getHomeIntent();
3820        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3821        if (aInfo != null) {
3822            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3823            // Don't do this if the home app is currently being
3824            // instrumented.
3825            aInfo = new ActivityInfo(aInfo);
3826            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3827            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3828                    aInfo.applicationInfo.uid, true);
3829            if (app == null || app.instrumentationClass == null) {
3830                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3831                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3832            }
3833        } else {
3834            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3835        }
3836
3837        return true;
3838    }
3839
3840    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3841        ActivityInfo ai = null;
3842        ComponentName comp = intent.getComponent();
3843        try {
3844            if (comp != null) {
3845                // Factory test.
3846                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3847            } else {
3848                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3849                        intent,
3850                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3851                        flags, userId);
3852
3853                if (info != null) {
3854                    ai = info.activityInfo;
3855                }
3856            }
3857        } catch (RemoteException e) {
3858            // ignore
3859        }
3860
3861        return ai;
3862    }
3863
3864    /**
3865     * Starts the "new version setup screen" if appropriate.
3866     */
3867    void startSetupActivityLocked() {
3868        // Only do this once per boot.
3869        if (mCheckedForSetup) {
3870            return;
3871        }
3872
3873        // We will show this screen if the current one is a different
3874        // version than the last one shown, and we are not running in
3875        // low-level factory test mode.
3876        final ContentResolver resolver = mContext.getContentResolver();
3877        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3878                Settings.Global.getInt(resolver,
3879                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3880            mCheckedForSetup = true;
3881
3882            // See if we should be showing the platform update setup UI.
3883            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3884            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3885                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3886            if (!ris.isEmpty()) {
3887                final ResolveInfo ri = ris.get(0);
3888                String vers = ri.activityInfo.metaData != null
3889                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3890                        : null;
3891                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3892                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3893                            Intent.METADATA_SETUP_VERSION);
3894                }
3895                String lastVers = Settings.Secure.getString(
3896                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3897                if (vers != null && !vers.equals(lastVers)) {
3898                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3899                    intent.setComponent(new ComponentName(
3900                            ri.activityInfo.packageName, ri.activityInfo.name));
3901                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3902                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3903                            null, 0, 0, 0, null, false, false, null, null, null);
3904                }
3905            }
3906        }
3907    }
3908
3909    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3910        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3911    }
3912
3913    void enforceNotIsolatedCaller(String caller) {
3914        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3915            throw new SecurityException("Isolated process not allowed to call " + caller);
3916        }
3917    }
3918
3919    void enforceShellRestriction(String restriction, int userHandle) {
3920        if (Binder.getCallingUid() == Process.SHELL_UID) {
3921            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3922                throw new SecurityException("Shell does not have permission to access user "
3923                        + userHandle);
3924            }
3925        }
3926    }
3927
3928    @Override
3929    public int getFrontActivityScreenCompatMode() {
3930        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3931        synchronized (this) {
3932            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3933        }
3934    }
3935
3936    @Override
3937    public void setFrontActivityScreenCompatMode(int mode) {
3938        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3939                "setFrontActivityScreenCompatMode");
3940        synchronized (this) {
3941            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3942        }
3943    }
3944
3945    @Override
3946    public int getPackageScreenCompatMode(String packageName) {
3947        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3948        synchronized (this) {
3949            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3950        }
3951    }
3952
3953    @Override
3954    public void setPackageScreenCompatMode(String packageName, int mode) {
3955        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3956                "setPackageScreenCompatMode");
3957        synchronized (this) {
3958            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3959        }
3960    }
3961
3962    @Override
3963    public boolean getPackageAskScreenCompat(String packageName) {
3964        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3965        synchronized (this) {
3966            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3967        }
3968    }
3969
3970    @Override
3971    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3973                "setPackageAskScreenCompat");
3974        synchronized (this) {
3975            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3976        }
3977    }
3978
3979    private boolean hasUsageStatsPermission(String callingPackage) {
3980        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3981                Binder.getCallingUid(), callingPackage);
3982        if (mode == AppOpsManager.MODE_DEFAULT) {
3983            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3984                    == PackageManager.PERMISSION_GRANTED;
3985        }
3986        return mode == AppOpsManager.MODE_ALLOWED;
3987    }
3988
3989    @Override
3990    public int getPackageProcessState(String packageName, String callingPackage) {
3991        if (!hasUsageStatsPermission(callingPackage)) {
3992            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3993                    "getPackageProcessState");
3994        }
3995
3996        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3997        synchronized (this) {
3998            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3999                final ProcessRecord proc = mLruProcesses.get(i);
4000                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4001                        || procState > proc.setProcState) {
4002                    boolean found = false;
4003                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4004                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4005                            procState = proc.setProcState;
4006                            found = true;
4007                        }
4008                    }
4009                    if (proc.pkgDeps != null && !found) {
4010                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4011                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4012                                procState = proc.setProcState;
4013                                break;
4014                            }
4015                        }
4016                    }
4017                }
4018            }
4019        }
4020        return procState;
4021    }
4022
4023    @Override
4024    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4025        synchronized (this) {
4026            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4027            if (app == null) {
4028                return false;
4029            }
4030            if (app.trimMemoryLevel < level && app.thread != null &&
4031                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4032                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4033                try {
4034                    app.thread.scheduleTrimMemory(level);
4035                    app.trimMemoryLevel = level;
4036                    return true;
4037                } catch (RemoteException e) {
4038                    // Fallthrough to failure case.
4039                }
4040            }
4041        }
4042        return false;
4043    }
4044
4045    private void dispatchProcessesChanged() {
4046        int N;
4047        synchronized (this) {
4048            N = mPendingProcessChanges.size();
4049            if (mActiveProcessChanges.length < N) {
4050                mActiveProcessChanges = new ProcessChangeItem[N];
4051            }
4052            mPendingProcessChanges.toArray(mActiveProcessChanges);
4053            mPendingProcessChanges.clear();
4054            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4055                    "*** Delivering " + N + " process changes");
4056        }
4057
4058        int i = mProcessObservers.beginBroadcast();
4059        while (i > 0) {
4060            i--;
4061            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4062            if (observer != null) {
4063                try {
4064                    for (int j=0; j<N; j++) {
4065                        ProcessChangeItem item = mActiveProcessChanges[j];
4066                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4067                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4068                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4069                                    + item.uid + ": " + item.foregroundActivities);
4070                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4071                                    item.foregroundActivities);
4072                        }
4073                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4074                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4075                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4076                                    + ": " + item.processState);
4077                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4078                        }
4079                    }
4080                } catch (RemoteException e) {
4081                }
4082            }
4083        }
4084        mProcessObservers.finishBroadcast();
4085
4086        synchronized (this) {
4087            for (int j=0; j<N; j++) {
4088                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4089            }
4090        }
4091    }
4092
4093    private void dispatchProcessDied(int pid, int uid) {
4094        int i = mProcessObservers.beginBroadcast();
4095        while (i > 0) {
4096            i--;
4097            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4098            if (observer != null) {
4099                try {
4100                    observer.onProcessDied(pid, uid);
4101                } catch (RemoteException e) {
4102                }
4103            }
4104        }
4105        mProcessObservers.finishBroadcast();
4106    }
4107
4108    private void dispatchUidsChanged() {
4109        int N;
4110        synchronized (this) {
4111            N = mPendingUidChanges.size();
4112            if (mActiveUidChanges.length < N) {
4113                mActiveUidChanges = new UidRecord.ChangeItem[N];
4114            }
4115            for (int i=0; i<N; i++) {
4116                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4117                mActiveUidChanges[i] = change;
4118                if (change.uidRecord != null) {
4119                    change.uidRecord.pendingChange = null;
4120                    change.uidRecord = null;
4121                }
4122            }
4123            mPendingUidChanges.clear();
4124            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4125                    "*** Delivering " + N + " uid changes");
4126        }
4127
4128        if (mLocalPowerManager != null) {
4129            for (int j=0; j<N; j++) {
4130                UidRecord.ChangeItem item = mActiveUidChanges[j];
4131                if (item.change == UidRecord.CHANGE_GONE
4132                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4133                    mLocalPowerManager.uidGone(item.uid);
4134                } else {
4135                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4136                }
4137            }
4138        }
4139
4140        int i = mUidObservers.beginBroadcast();
4141        while (i > 0) {
4142            i--;
4143            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4144            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4145            if (observer != null) {
4146                try {
4147                    for (int j=0; j<N; j++) {
4148                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4149                        final int change = item.change;
4150                        UidRecord validateUid = null;
4151                        if (VALIDATE_UID_STATES && i == 0) {
4152                            validateUid = mValidateUids.get(item.uid);
4153                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4154                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4155                                validateUid = new UidRecord(item.uid);
4156                                mValidateUids.put(item.uid, validateUid);
4157                            }
4158                        }
4159                        if (change == UidRecord.CHANGE_IDLE
4160                                || change == UidRecord.CHANGE_GONE_IDLE) {
4161                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4162                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4163                                        "UID idle uid=" + item.uid);
4164                                observer.onUidIdle(item.uid);
4165                            }
4166                            if (VALIDATE_UID_STATES && i == 0) {
4167                                if (validateUid != null) {
4168                                    validateUid.idle = true;
4169                                }
4170                            }
4171                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4172                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4173                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4174                                        "UID active uid=" + item.uid);
4175                                observer.onUidActive(item.uid);
4176                            }
4177                            if (VALIDATE_UID_STATES && i == 0) {
4178                                validateUid.idle = false;
4179                            }
4180                        }
4181                        if (change == UidRecord.CHANGE_GONE
4182                                || change == UidRecord.CHANGE_GONE_IDLE) {
4183                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4184                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4185                                        "UID gone uid=" + item.uid);
4186                                observer.onUidGone(item.uid);
4187                            }
4188                            if (VALIDATE_UID_STATES && i == 0) {
4189                                if (validateUid != null) {
4190                                    mValidateUids.remove(item.uid);
4191                                }
4192                            }
4193                        } else {
4194                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4195                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4196                                        "UID CHANGED uid=" + item.uid
4197                                                + ": " + item.processState);
4198                                observer.onUidStateChanged(item.uid, item.processState);
4199                            }
4200                            if (VALIDATE_UID_STATES && i == 0) {
4201                                validateUid.curProcState = validateUid.setProcState
4202                                        = item.processState;
4203                            }
4204                        }
4205                    }
4206                } catch (RemoteException e) {
4207                }
4208            }
4209        }
4210        mUidObservers.finishBroadcast();
4211
4212        synchronized (this) {
4213            for (int j=0; j<N; j++) {
4214                mAvailUidChanges.add(mActiveUidChanges[j]);
4215            }
4216        }
4217    }
4218
4219    @Override
4220    public final int startActivity(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4223        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4224                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4225                UserHandle.getCallingUserId());
4226    }
4227
4228    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4229        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4230        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4231                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4232                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4233
4234        // TODO: Switch to user app stacks here.
4235        String mimeType = intent.getType();
4236        final Uri data = intent.getData();
4237        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4238            mimeType = getProviderMimeType(data, userId);
4239        }
4240        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4241
4242        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4243        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4244                null, 0, 0, null, null, null, null, false, userId, container, null);
4245    }
4246
4247    @Override
4248    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4249            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4250            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4251        enforceNotIsolatedCaller("startActivity");
4252        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4253                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4254        // TODO: Switch to user app stacks here.
4255        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4256                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4257                profilerInfo, null, null, bOptions, false, userId, null, null);
4258    }
4259
4260    @Override
4261    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4262            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4263            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4264            int userId) {
4265
4266        // This is very dangerous -- it allows you to perform a start activity (including
4267        // permission grants) as any app that may launch one of your own activities.  So
4268        // we will only allow this to be done from activities that are part of the core framework,
4269        // and then only when they are running as the system.
4270        final ActivityRecord sourceRecord;
4271        final int targetUid;
4272        final String targetPackage;
4273        synchronized (this) {
4274            if (resultTo == null) {
4275                throw new SecurityException("Must be called from an activity");
4276            }
4277            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4278            if (sourceRecord == null) {
4279                throw new SecurityException("Called with bad activity token: " + resultTo);
4280            }
4281            if (!sourceRecord.info.packageName.equals("android")) {
4282                throw new SecurityException(
4283                        "Must be called from an activity that is declared in the android package");
4284            }
4285            if (sourceRecord.app == null) {
4286                throw new SecurityException("Called without a process attached to activity");
4287            }
4288            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4289                // This is still okay, as long as this activity is running under the
4290                // uid of the original calling activity.
4291                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4292                    throw new SecurityException(
4293                            "Calling activity in uid " + sourceRecord.app.uid
4294                                    + " must be system uid or original calling uid "
4295                                    + sourceRecord.launchedFromUid);
4296                }
4297            }
4298            if (ignoreTargetSecurity) {
4299                if (intent.getComponent() == null) {
4300                    throw new SecurityException(
4301                            "Component must be specified with ignoreTargetSecurity");
4302                }
4303                if (intent.getSelector() != null) {
4304                    throw new SecurityException(
4305                            "Selector not allowed with ignoreTargetSecurity");
4306                }
4307            }
4308            targetUid = sourceRecord.launchedFromUid;
4309            targetPackage = sourceRecord.launchedFromPackage;
4310        }
4311
4312        if (userId == UserHandle.USER_NULL) {
4313            userId = UserHandle.getUserId(sourceRecord.app.uid);
4314        }
4315
4316        // TODO: Switch to user app stacks here.
4317        try {
4318            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4319                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4320                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4321            return ret;
4322        } catch (SecurityException e) {
4323            // XXX need to figure out how to propagate to original app.
4324            // A SecurityException here is generally actually a fault of the original
4325            // calling activity (such as a fairly granting permissions), so propagate it
4326            // back to them.
4327            /*
4328            StringBuilder msg = new StringBuilder();
4329            msg.append("While launching");
4330            msg.append(intent.toString());
4331            msg.append(": ");
4332            msg.append(e.getMessage());
4333            */
4334            throw e;
4335        }
4336    }
4337
4338    @Override
4339    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4341            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4342        enforceNotIsolatedCaller("startActivityAndWait");
4343        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4344                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4345        WaitResult res = new WaitResult();
4346        // TODO: Switch to user app stacks here.
4347        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4348                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4349                bOptions, false, userId, null, null);
4350        return res;
4351    }
4352
4353    @Override
4354    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4356            int startFlags, Configuration config, Bundle bOptions, int userId) {
4357        enforceNotIsolatedCaller("startActivityWithConfig");
4358        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4359                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4360        // TODO: Switch to user app stacks here.
4361        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4362                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4363                null, null, config, bOptions, false, userId, null, null);
4364        return ret;
4365    }
4366
4367    @Override
4368    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4369            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4370            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4371            throws TransactionTooLargeException {
4372        enforceNotIsolatedCaller("startActivityIntentSender");
4373        // Refuse possible leaked file descriptors
4374        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4375            throw new IllegalArgumentException("File descriptors passed in Intent");
4376        }
4377
4378        IIntentSender sender = intent.getTarget();
4379        if (!(sender instanceof PendingIntentRecord)) {
4380            throw new IllegalArgumentException("Bad PendingIntent object");
4381        }
4382
4383        PendingIntentRecord pir = (PendingIntentRecord)sender;
4384
4385        synchronized (this) {
4386            // If this is coming from the currently resumed activity, it is
4387            // effectively saying that app switches are allowed at this point.
4388            final ActivityStack stack = getFocusedStack();
4389            if (stack.mResumedActivity != null &&
4390                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4391                mAppSwitchesAllowedTime = 0;
4392            }
4393        }
4394        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4395                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4396        return ret;
4397    }
4398
4399    @Override
4400    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4401            Intent intent, String resolvedType, IVoiceInteractionSession session,
4402            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4403            Bundle bOptions, int userId) {
4404        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4405                != PackageManager.PERMISSION_GRANTED) {
4406            String msg = "Permission Denial: startVoiceActivity() from pid="
4407                    + Binder.getCallingPid()
4408                    + ", uid=" + Binder.getCallingUid()
4409                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4410            Slog.w(TAG, msg);
4411            throw new SecurityException(msg);
4412        }
4413        if (session == null || interactor == null) {
4414            throw new NullPointerException("null session or interactor");
4415        }
4416        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4417                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4418        // TODO: Switch to user app stacks here.
4419        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4420                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4421                null, bOptions, false, userId, null, null);
4422    }
4423
4424    @Override
4425    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4426            throws RemoteException {
4427        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4428        synchronized (this) {
4429            ActivityRecord activity = getFocusedStack().topActivity();
4430            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4431                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4432            }
4433            if (mRunningVoice != null || activity.task.voiceSession != null
4434                    || activity.voiceSession != null) {
4435                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4436                return;
4437            }
4438            if (activity.pendingVoiceInteractionStart) {
4439                Slog.w(TAG, "Pending start of voice interaction already.");
4440                return;
4441            }
4442            activity.pendingVoiceInteractionStart = true;
4443        }
4444        LocalServices.getService(VoiceInteractionManagerInternal.class)
4445                .startLocalVoiceInteraction(callingActivity, options);
4446    }
4447
4448    @Override
4449    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4450        LocalServices.getService(VoiceInteractionManagerInternal.class)
4451                .stopLocalVoiceInteraction(callingActivity);
4452    }
4453
4454    @Override
4455    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4456        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4457                .supportsLocalVoiceInteraction();
4458    }
4459
4460    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4461            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4462        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4463        if (activityToCallback == null) return;
4464        activityToCallback.setVoiceSessionLocked(voiceSession);
4465
4466        // Inform the activity
4467        try {
4468            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4469                    voiceInteractor);
4470            long token = Binder.clearCallingIdentity();
4471            try {
4472                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4473            } finally {
4474                Binder.restoreCallingIdentity(token);
4475            }
4476            // TODO: VI Should we cache the activity so that it's easier to find later
4477            // rather than scan through all the stacks and activities?
4478        } catch (RemoteException re) {
4479            activityToCallback.clearVoiceSessionLocked();
4480            // TODO: VI Should this terminate the voice session?
4481        }
4482    }
4483
4484    @Override
4485    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4486        synchronized (this) {
4487            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4488                if (keepAwake) {
4489                    mVoiceWakeLock.acquire();
4490                } else {
4491                    mVoiceWakeLock.release();
4492                }
4493            }
4494        }
4495    }
4496
4497    @Override
4498    public boolean startNextMatchingActivity(IBinder callingActivity,
4499            Intent intent, Bundle bOptions) {
4500        // Refuse possible leaked file descriptors
4501        if (intent != null && intent.hasFileDescriptors() == true) {
4502            throw new IllegalArgumentException("File descriptors passed in Intent");
4503        }
4504        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4505
4506        synchronized (this) {
4507            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4508            if (r == null) {
4509                ActivityOptions.abort(options);
4510                return false;
4511            }
4512            if (r.app == null || r.app.thread == null) {
4513                // The caller is not running...  d'oh!
4514                ActivityOptions.abort(options);
4515                return false;
4516            }
4517            intent = new Intent(intent);
4518            // The caller is not allowed to change the data.
4519            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4520            // And we are resetting to find the next component...
4521            intent.setComponent(null);
4522
4523            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4524
4525            ActivityInfo aInfo = null;
4526            try {
4527                List<ResolveInfo> resolves =
4528                    AppGlobals.getPackageManager().queryIntentActivities(
4529                            intent, r.resolvedType,
4530                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4531                            UserHandle.getCallingUserId()).getList();
4532
4533                // Look for the original activity in the list...
4534                final int N = resolves != null ? resolves.size() : 0;
4535                for (int i=0; i<N; i++) {
4536                    ResolveInfo rInfo = resolves.get(i);
4537                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4538                            && rInfo.activityInfo.name.equals(r.info.name)) {
4539                        // We found the current one...  the next matching is
4540                        // after it.
4541                        i++;
4542                        if (i<N) {
4543                            aInfo = resolves.get(i).activityInfo;
4544                        }
4545                        if (debug) {
4546                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4547                                    + "/" + r.info.name);
4548                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4549                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4550                        }
4551                        break;
4552                    }
4553                }
4554            } catch (RemoteException e) {
4555            }
4556
4557            if (aInfo == null) {
4558                // Nobody who is next!
4559                ActivityOptions.abort(options);
4560                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4561                return false;
4562            }
4563
4564            intent.setComponent(new ComponentName(
4565                    aInfo.applicationInfo.packageName, aInfo.name));
4566            intent.setFlags(intent.getFlags()&~(
4567                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4568                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4569                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4570                    Intent.FLAG_ACTIVITY_NEW_TASK));
4571
4572            // Okay now we need to start the new activity, replacing the
4573            // currently running activity.  This is a little tricky because
4574            // we want to start the new one as if the current one is finished,
4575            // but not finish the current one first so that there is no flicker.
4576            // And thus...
4577            final boolean wasFinishing = r.finishing;
4578            r.finishing = true;
4579
4580            // Propagate reply information over to the new activity.
4581            final ActivityRecord resultTo = r.resultTo;
4582            final String resultWho = r.resultWho;
4583            final int requestCode = r.requestCode;
4584            r.resultTo = null;
4585            if (resultTo != null) {
4586                resultTo.removeResultsLocked(r, resultWho, requestCode);
4587            }
4588
4589            final long origId = Binder.clearCallingIdentity();
4590            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4591                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4592                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4593                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4594                    false, false, null, null, null);
4595            Binder.restoreCallingIdentity(origId);
4596
4597            r.finishing = wasFinishing;
4598            if (res != ActivityManager.START_SUCCESS) {
4599                return false;
4600            }
4601            return true;
4602        }
4603    }
4604
4605    @Override
4606    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4607        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4608            String msg = "Permission Denial: startActivityFromRecents called without " +
4609                    START_TASKS_FROM_RECENTS;
4610            Slog.w(TAG, msg);
4611            throw new SecurityException(msg);
4612        }
4613        final long origId = Binder.clearCallingIdentity();
4614        try {
4615            synchronized (this) {
4616                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4617            }
4618        } finally {
4619            Binder.restoreCallingIdentity(origId);
4620        }
4621    }
4622
4623    final int startActivityInPackage(int uid, String callingPackage,
4624            Intent intent, String resolvedType, IBinder resultTo,
4625            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4626            IActivityContainer container, TaskRecord inTask) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630
4631        // TODO: Switch to user app stacks here.
4632        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4633                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4634                null, null, null, bOptions, false, userId, container, inTask);
4635        return ret;
4636    }
4637
4638    @Override
4639    public final int startActivities(IApplicationThread caller, String callingPackage,
4640            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4641            int userId) {
4642        enforceNotIsolatedCaller("startActivities");
4643        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4644                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4645        // TODO: Switch to user app stacks here.
4646        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4647                resolvedTypes, resultTo, bOptions, userId);
4648        return ret;
4649    }
4650
4651    final int startActivitiesInPackage(int uid, String callingPackage,
4652            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4653            Bundle bOptions, int userId) {
4654
4655        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4656                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4657        // TODO: Switch to user app stacks here.
4658        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4659                resultTo, bOptions, userId);
4660        return ret;
4661    }
4662
4663    @Override
4664    public void reportActivityFullyDrawn(IBinder token) {
4665        synchronized (this) {
4666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4667            if (r == null) {
4668                return;
4669            }
4670            r.reportFullyDrawnLocked();
4671        }
4672    }
4673
4674    @Override
4675    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return;
4680            }
4681            TaskRecord task = r.task;
4682            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4683                // Fixed screen orientation isn't supported when activities aren't in full screen
4684                // mode.
4685                return;
4686            }
4687            final long origId = Binder.clearCallingIdentity();
4688            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4689            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4690                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4691            if (config != null) {
4692                r.frozenBeforeDestroy = true;
4693                if (!updateConfigurationLocked(config, r, false)) {
4694                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4695                }
4696            }
4697            Binder.restoreCallingIdentity(origId);
4698        }
4699    }
4700
4701    @Override
4702    public int getRequestedOrientation(IBinder token) {
4703        synchronized (this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4707            }
4708            return mWindowManager.getAppOrientation(r.appToken);
4709        }
4710    }
4711
4712    /**
4713     * This is the internal entry point for handling Activity.finish().
4714     *
4715     * @param token The Binder token referencing the Activity we want to finish.
4716     * @param resultCode Result code, if any, from this Activity.
4717     * @param resultData Result data (Intent), if any, from this Activity.
4718     * @param finishTask Whether to finish the task associated with this Activity.
4719     *
4720     * @return Returns true if the activity successfully finished, or false if it is still running.
4721     */
4722    @Override
4723    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4724            int finishTask) {
4725        // Refuse possible leaked file descriptors
4726        if (resultData != null && resultData.hasFileDescriptors() == true) {
4727            throw new IllegalArgumentException("File descriptors passed in Intent");
4728        }
4729
4730        synchronized(this) {
4731            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4732            if (r == null) {
4733                return true;
4734            }
4735            // Keep track of the root activity of the task before we finish it
4736            TaskRecord tr = r.task;
4737            ActivityRecord rootR = tr.getRootActivity();
4738            if (rootR == null) {
4739                Slog.w(TAG, "Finishing task with all activities already finished");
4740            }
4741            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4742            // finish.
4743            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4744                    mStackSupervisor.isLastLockedTask(tr)) {
4745                Slog.i(TAG, "Not finishing task in lock task mode");
4746                mStackSupervisor.showLockTaskToast();
4747                return false;
4748            }
4749            if (mController != null) {
4750                // Find the first activity that is not finishing.
4751                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4752                if (next != null) {
4753                    // ask watcher if this is allowed
4754                    boolean resumeOK = true;
4755                    try {
4756                        resumeOK = mController.activityResuming(next.packageName);
4757                    } catch (RemoteException e) {
4758                        mController = null;
4759                        Watchdog.getInstance().setActivityController(null);
4760                    }
4761
4762                    if (!resumeOK) {
4763                        Slog.i(TAG, "Not finishing activity because controller resumed");
4764                        return false;
4765                    }
4766                }
4767            }
4768            final long origId = Binder.clearCallingIdentity();
4769            try {
4770                boolean res;
4771                final boolean finishWithRootActivity =
4772                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4773                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4774                        || (finishWithRootActivity && r == rootR)) {
4775                    // If requested, remove the task that is associated to this activity only if it
4776                    // was the root activity in the task. The result code and data is ignored
4777                    // because we don't support returning them across task boundaries. Also, to
4778                    // keep backwards compatibility we remove the task from recents when finishing
4779                    // task with root activity.
4780                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4781                    if (!res) {
4782                        Slog.i(TAG, "Removing task failed to finish activity");
4783                    }
4784                } else {
4785                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4786                            resultData, "app-request", true);
4787                    if (!res) {
4788                        Slog.i(TAG, "Failed to finish by app-request");
4789                    }
4790                }
4791                return res;
4792            } finally {
4793                Binder.restoreCallingIdentity(origId);
4794            }
4795        }
4796    }
4797
4798    @Override
4799    public final void finishHeavyWeightApp() {
4800        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4801                != PackageManager.PERMISSION_GRANTED) {
4802            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4803                    + Binder.getCallingPid()
4804                    + ", uid=" + Binder.getCallingUid()
4805                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4806            Slog.w(TAG, msg);
4807            throw new SecurityException(msg);
4808        }
4809
4810        synchronized(this) {
4811            if (mHeavyWeightProcess == null) {
4812                return;
4813            }
4814
4815            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4816            for (int i = 0; i < activities.size(); i++) {
4817                ActivityRecord r = activities.get(i);
4818                if (!r.finishing && r.isInStackLocked()) {
4819                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4820                            null, "finish-heavy", true);
4821                }
4822            }
4823
4824            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4825                    mHeavyWeightProcess.userId, 0));
4826            mHeavyWeightProcess = null;
4827        }
4828    }
4829
4830    @Override
4831    public void crashApplication(int uid, int initialPid, String packageName,
4832            String message) {
4833        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4834                != PackageManager.PERMISSION_GRANTED) {
4835            String msg = "Permission Denial: crashApplication() from pid="
4836                    + Binder.getCallingPid()
4837                    + ", uid=" + Binder.getCallingUid()
4838                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4839            Slog.w(TAG, msg);
4840            throw new SecurityException(msg);
4841        }
4842
4843        synchronized(this) {
4844            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4845        }
4846    }
4847
4848    @Override
4849    public final void finishSubActivity(IBinder token, String resultWho,
4850            int requestCode) {
4851        synchronized(this) {
4852            final long origId = Binder.clearCallingIdentity();
4853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4854            if (r != null) {
4855                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4856            }
4857            Binder.restoreCallingIdentity(origId);
4858        }
4859    }
4860
4861    @Override
4862    public boolean finishActivityAffinity(IBinder token) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            try {
4866                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4867                if (r == null) {
4868                    return false;
4869                }
4870
4871                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4872                // can finish.
4873                final TaskRecord task = r.task;
4874                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4875                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4876                    mStackSupervisor.showLockTaskToast();
4877                    return false;
4878                }
4879                return task.stack.finishActivityAffinityLocked(r);
4880            } finally {
4881                Binder.restoreCallingIdentity(origId);
4882            }
4883        }
4884    }
4885
4886    @Override
4887    public void finishVoiceTask(IVoiceInteractionSession session) {
4888        synchronized (this) {
4889            final long origId = Binder.clearCallingIdentity();
4890            try {
4891                // TODO: VI Consider treating local voice interactions and voice tasks
4892                // differently here
4893                mStackSupervisor.finishVoiceTask(session);
4894            } finally {
4895                Binder.restoreCallingIdentity(origId);
4896            }
4897        }
4898
4899    }
4900
4901    @Override
4902    public boolean releaseActivityInstance(IBinder token) {
4903        synchronized(this) {
4904            final long origId = Binder.clearCallingIdentity();
4905            try {
4906                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4907                if (r == null) {
4908                    return false;
4909                }
4910                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4911            } finally {
4912                Binder.restoreCallingIdentity(origId);
4913            }
4914        }
4915    }
4916
4917    @Override
4918    public void releaseSomeActivities(IApplicationThread appInt) {
4919        synchronized(this) {
4920            final long origId = Binder.clearCallingIdentity();
4921            try {
4922                ProcessRecord app = getRecordForAppLocked(appInt);
4923                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4924            } finally {
4925                Binder.restoreCallingIdentity(origId);
4926            }
4927        }
4928    }
4929
4930    @Override
4931    public boolean willActivityBeVisible(IBinder token) {
4932        synchronized(this) {
4933            ActivityStack stack = ActivityRecord.getStackLocked(token);
4934            if (stack != null) {
4935                return stack.willActivityBeVisibleLocked(token);
4936            }
4937            return false;
4938        }
4939    }
4940
4941    @Override
4942    public void overridePendingTransition(IBinder token, String packageName,
4943            int enterAnim, int exitAnim) {
4944        synchronized(this) {
4945            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4946            if (self == null) {
4947                return;
4948            }
4949
4950            final long origId = Binder.clearCallingIdentity();
4951
4952            if (self.state == ActivityState.RESUMED
4953                    || self.state == ActivityState.PAUSING) {
4954                mWindowManager.overridePendingAppTransition(packageName,
4955                        enterAnim, exitAnim, null);
4956            }
4957
4958            Binder.restoreCallingIdentity(origId);
4959        }
4960    }
4961
4962    /**
4963     * Main function for removing an existing process from the activity manager
4964     * as a result of that process going away.  Clears out all connections
4965     * to the process.
4966     */
4967    private final void handleAppDiedLocked(ProcessRecord app,
4968            boolean restarting, boolean allowRestart) {
4969        int pid = app.pid;
4970        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4971        if (!kept && !restarting) {
4972            removeLruProcessLocked(app);
4973            if (pid > 0) {
4974                ProcessList.remove(pid);
4975            }
4976        }
4977
4978        if (mProfileProc == app) {
4979            clearProfilerLocked();
4980        }
4981
4982        // Remove this application's activities from active lists.
4983        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4984
4985        app.activities.clear();
4986
4987        if (app.instrumentationClass != null) {
4988            Slog.w(TAG, "Crash of app " + app.processName
4989                  + " running instrumentation " + app.instrumentationClass);
4990            Bundle info = new Bundle();
4991            info.putString("shortMsg", "Process crashed.");
4992            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4993        }
4994
4995        if (!restarting && hasVisibleActivities
4996                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4997            // If there was nothing to resume, and we are not already restarting this process, but
4998            // there is a visible activity that is hosted by the process...  then make sure all
4999            // visible activities are running, taking care of restarting this process.
5000            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5001        }
5002    }
5003
5004    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5005        IBinder threadBinder = thread.asBinder();
5006        // Find the application record.
5007        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5008            ProcessRecord rec = mLruProcesses.get(i);
5009            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5010                return i;
5011            }
5012        }
5013        return -1;
5014    }
5015
5016    final ProcessRecord getRecordForAppLocked(
5017            IApplicationThread thread) {
5018        if (thread == null) {
5019            return null;
5020        }
5021
5022        int appIndex = getLRURecordIndexForAppLocked(thread);
5023        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5024    }
5025
5026    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5027        // If there are no longer any background processes running,
5028        // and the app that died was not running instrumentation,
5029        // then tell everyone we are now low on memory.
5030        boolean haveBg = false;
5031        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5032            ProcessRecord rec = mLruProcesses.get(i);
5033            if (rec.thread != null
5034                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5035                haveBg = true;
5036                break;
5037            }
5038        }
5039
5040        if (!haveBg) {
5041            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5042            if (doReport) {
5043                long now = SystemClock.uptimeMillis();
5044                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5045                    doReport = false;
5046                } else {
5047                    mLastMemUsageReportTime = now;
5048                }
5049            }
5050            final ArrayList<ProcessMemInfo> memInfos
5051                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5052            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5053            long now = SystemClock.uptimeMillis();
5054            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5055                ProcessRecord rec = mLruProcesses.get(i);
5056                if (rec == dyingProc || rec.thread == null) {
5057                    continue;
5058                }
5059                if (doReport) {
5060                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5061                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5062                }
5063                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5064                    // The low memory report is overriding any current
5065                    // state for a GC request.  Make sure to do
5066                    // heavy/important/visible/foreground processes first.
5067                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5068                        rec.lastRequestedGc = 0;
5069                    } else {
5070                        rec.lastRequestedGc = rec.lastLowMemory;
5071                    }
5072                    rec.reportLowMemory = true;
5073                    rec.lastLowMemory = now;
5074                    mProcessesToGc.remove(rec);
5075                    addProcessToGcListLocked(rec);
5076                }
5077            }
5078            if (doReport) {
5079                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5080                mHandler.sendMessage(msg);
5081            }
5082            scheduleAppGcsLocked();
5083        }
5084    }
5085
5086    final void appDiedLocked(ProcessRecord app) {
5087       appDiedLocked(app, app.pid, app.thread, false);
5088    }
5089
5090    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5091            boolean fromBinderDied) {
5092        // First check if this ProcessRecord is actually active for the pid.
5093        synchronized (mPidsSelfLocked) {
5094            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5095            if (curProc != app) {
5096                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5097                return;
5098            }
5099        }
5100
5101        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5102        synchronized (stats) {
5103            stats.noteProcessDiedLocked(app.info.uid, pid);
5104        }
5105
5106        if (!app.killed) {
5107            if (!fromBinderDied) {
5108                Process.killProcessQuiet(pid);
5109            }
5110            killProcessGroup(app.uid, pid);
5111            app.killed = true;
5112        }
5113
5114        // Clean up already done if the process has been re-started.
5115        if (app.pid == pid && app.thread != null &&
5116                app.thread.asBinder() == thread.asBinder()) {
5117            boolean doLowMem = app.instrumentationClass == null;
5118            boolean doOomAdj = doLowMem;
5119            if (!app.killedByAm) {
5120                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5121                        + ") has died");
5122                mAllowLowerMemLevel = true;
5123            } else {
5124                // Note that we always want to do oom adj to update our state with the
5125                // new number of procs.
5126                mAllowLowerMemLevel = false;
5127                doLowMem = false;
5128            }
5129            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5130            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5131                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5132            handleAppDiedLocked(app, false, true);
5133
5134            if (doOomAdj) {
5135                updateOomAdjLocked();
5136            }
5137            if (doLowMem) {
5138                doLowMemReportIfNeededLocked(app);
5139            }
5140        } else if (app.pid != pid) {
5141            // A new process has already been started.
5142            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5143                    + ") has died and restarted (pid " + app.pid + ").");
5144            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5145        } else if (DEBUG_PROCESSES) {
5146            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5147                    + thread.asBinder());
5148        }
5149    }
5150
5151    /**
5152     * If a stack trace dump file is configured, dump process stack traces.
5153     * @param clearTraces causes the dump file to be erased prior to the new
5154     *    traces being written, if true; when false, the new traces will be
5155     *    appended to any existing file content.
5156     * @param firstPids of dalvik VM processes to dump stack traces for first
5157     * @param lastPids of dalvik VM processes to dump stack traces for last
5158     * @param nativeProcs optional list of native process names to dump stack crawls
5159     * @return file containing stack traces, or null if no dump file is configured
5160     */
5161    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5162            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5163        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5164        if (tracesPath == null || tracesPath.length() == 0) {
5165            return null;
5166        }
5167
5168        File tracesFile = new File(tracesPath);
5169        try {
5170            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5171            tracesFile.createNewFile();
5172            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5173        } catch (IOException e) {
5174            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5175            return null;
5176        }
5177
5178        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5179        return tracesFile;
5180    }
5181
5182    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5183            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5184        // Use a FileObserver to detect when traces finish writing.
5185        // The order of traces is considered important to maintain for legibility.
5186        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5187            @Override
5188            public synchronized void onEvent(int event, String path) { notify(); }
5189        };
5190
5191        try {
5192            observer.startWatching();
5193
5194            // First collect all of the stacks of the most important pids.
5195            if (firstPids != null) {
5196                try {
5197                    int num = firstPids.size();
5198                    for (int i = 0; i < num; i++) {
5199                        synchronized (observer) {
5200                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5201                                    + firstPids.get(i));
5202                            final long sime = SystemClock.elapsedRealtime();
5203                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5204                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5205                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5206                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5207                        }
5208                    }
5209                } catch (InterruptedException e) {
5210                    Slog.wtf(TAG, e);
5211                }
5212            }
5213
5214            // Next collect the stacks of the native pids
5215            if (nativeProcs != null) {
5216                int[] pids = Process.getPidsForCommands(nativeProcs);
5217                if (pids != null) {
5218                    for (int pid : pids) {
5219                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5220                        final long sime = SystemClock.elapsedRealtime();
5221                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5222                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5223                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5224                    }
5225                }
5226            }
5227
5228            // Lastly, measure CPU usage.
5229            if (processCpuTracker != null) {
5230                processCpuTracker.init();
5231                System.gc();
5232                processCpuTracker.update();
5233                try {
5234                    synchronized (processCpuTracker) {
5235                        processCpuTracker.wait(500); // measure over 1/2 second.
5236                    }
5237                } catch (InterruptedException e) {
5238                }
5239                processCpuTracker.update();
5240
5241                // We'll take the stack crawls of just the top apps using CPU.
5242                final int N = processCpuTracker.countWorkingStats();
5243                int numProcs = 0;
5244                for (int i=0; i<N && numProcs<5; i++) {
5245                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5246                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5247                        numProcs++;
5248                        try {
5249                            synchronized (observer) {
5250                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5251                                        + stats.pid);
5252                                final long stime = SystemClock.elapsedRealtime();
5253                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5254                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5255                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5256                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5257                            }
5258                        } catch (InterruptedException e) {
5259                            Slog.wtf(TAG, e);
5260                        }
5261                    } else if (DEBUG_ANR) {
5262                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5263                                + stats.pid);
5264                    }
5265                }
5266            }
5267        } finally {
5268            observer.stopWatching();
5269        }
5270    }
5271
5272    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5273        if (true || IS_USER_BUILD) {
5274            return;
5275        }
5276        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5277        if (tracesPath == null || tracesPath.length() == 0) {
5278            return;
5279        }
5280
5281        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5282        StrictMode.allowThreadDiskWrites();
5283        try {
5284            final File tracesFile = new File(tracesPath);
5285            final File tracesDir = tracesFile.getParentFile();
5286            final File tracesTmp = new File(tracesDir, "__tmp__");
5287            try {
5288                if (tracesFile.exists()) {
5289                    tracesTmp.delete();
5290                    tracesFile.renameTo(tracesTmp);
5291                }
5292                StringBuilder sb = new StringBuilder();
5293                Time tobj = new Time();
5294                tobj.set(System.currentTimeMillis());
5295                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5296                sb.append(": ");
5297                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5298                sb.append(" since ");
5299                sb.append(msg);
5300                FileOutputStream fos = new FileOutputStream(tracesFile);
5301                fos.write(sb.toString().getBytes());
5302                if (app == null) {
5303                    fos.write("\n*** No application process!".getBytes());
5304                }
5305                fos.close();
5306                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5307            } catch (IOException e) {
5308                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5309                return;
5310            }
5311
5312            if (app != null) {
5313                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5314                firstPids.add(app.pid);
5315                dumpStackTraces(tracesPath, firstPids, null, null, null);
5316            }
5317
5318            File lastTracesFile = null;
5319            File curTracesFile = null;
5320            for (int i=9; i>=0; i--) {
5321                String name = String.format(Locale.US, "slow%02d.txt", i);
5322                curTracesFile = new File(tracesDir, name);
5323                if (curTracesFile.exists()) {
5324                    if (lastTracesFile != null) {
5325                        curTracesFile.renameTo(lastTracesFile);
5326                    } else {
5327                        curTracesFile.delete();
5328                    }
5329                }
5330                lastTracesFile = curTracesFile;
5331            }
5332            tracesFile.renameTo(curTracesFile);
5333            if (tracesTmp.exists()) {
5334                tracesTmp.renameTo(tracesFile);
5335            }
5336        } finally {
5337            StrictMode.setThreadPolicy(oldPolicy);
5338        }
5339    }
5340
5341    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5342        if (!mLaunchWarningShown) {
5343            mLaunchWarningShown = true;
5344            mUiHandler.post(new Runnable() {
5345                @Override
5346                public void run() {
5347                    synchronized (ActivityManagerService.this) {
5348                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5349                        d.show();
5350                        mUiHandler.postDelayed(new Runnable() {
5351                            @Override
5352                            public void run() {
5353                                synchronized (ActivityManagerService.this) {
5354                                    d.dismiss();
5355                                    mLaunchWarningShown = false;
5356                                }
5357                            }
5358                        }, 4000);
5359                    }
5360                }
5361            });
5362        }
5363    }
5364
5365    @Override
5366    public boolean clearApplicationUserData(final String packageName,
5367            final IPackageDataObserver observer, int userId) {
5368        enforceNotIsolatedCaller("clearApplicationUserData");
5369        int uid = Binder.getCallingUid();
5370        int pid = Binder.getCallingPid();
5371        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5372                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5373
5374        final DevicePolicyManagerInternal dpmi = LocalServices
5375                .getService(DevicePolicyManagerInternal.class);
5376        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5377            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5378        }
5379
5380        long callingId = Binder.clearCallingIdentity();
5381        try {
5382            IPackageManager pm = AppGlobals.getPackageManager();
5383            int pkgUid = -1;
5384            synchronized(this) {
5385                try {
5386                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5387                } catch (RemoteException e) {
5388                }
5389                if (pkgUid == -1) {
5390                    Slog.w(TAG, "Invalid packageName: " + packageName);
5391                    if (observer != null) {
5392                        try {
5393                            observer.onRemoveCompleted(packageName, false);
5394                        } catch (RemoteException e) {
5395                            Slog.i(TAG, "Observer no longer exists.");
5396                        }
5397                    }
5398                    return false;
5399                }
5400                if (uid == pkgUid || checkComponentPermission(
5401                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5402                        pid, uid, -1, true)
5403                        == PackageManager.PERMISSION_GRANTED) {
5404                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5405                } else {
5406                    throw new SecurityException("PID " + pid + " does not have permission "
5407                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5408                                    + " of package " + packageName);
5409                }
5410
5411                // Remove all tasks match the cleared application package and user
5412                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5413                    final TaskRecord tr = mRecentTasks.get(i);
5414                    final String taskPackageName =
5415                            tr.getBaseIntent().getComponent().getPackageName();
5416                    if (tr.userId != userId) continue;
5417                    if (!taskPackageName.equals(packageName)) continue;
5418                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5419                }
5420            }
5421
5422            final int pkgUidF = pkgUid;
5423            final int userIdF = userId;
5424            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5425                @Override
5426                public void onRemoveCompleted(String packageName, boolean succeeded)
5427                        throws RemoteException {
5428                    synchronized (ActivityManagerService.this) {
5429                        finishForceStopPackageLocked(packageName, pkgUidF);
5430                    }
5431
5432                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5433                            Uri.fromParts("package", packageName, null));
5434                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5435                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5436                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5437                            null, null, 0, null, null, null, null, false, false, userIdF);
5438
5439                    if (observer != null) {
5440                        observer.onRemoveCompleted(packageName, succeeded);
5441                    }
5442                }
5443            };
5444
5445            try {
5446                // Clear application user data
5447                pm.clearApplicationUserData(packageName, localObserver, userId);
5448
5449                synchronized(this) {
5450                    // Remove all permissions granted from/to this package
5451                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5452                }
5453
5454                // Remove all zen rules created by this package; revoke it's zen access.
5455                INotificationManager inm = NotificationManager.getService();
5456                inm.removeAutomaticZenRules(packageName);
5457                inm.setNotificationPolicyAccessGranted(packageName, false);
5458
5459            } catch (RemoteException e) {
5460            }
5461        } finally {
5462            Binder.restoreCallingIdentity(callingId);
5463        }
5464        return true;
5465    }
5466
5467    @Override
5468    public void killBackgroundProcesses(final String packageName, int userId) {
5469        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5470                != PackageManager.PERMISSION_GRANTED &&
5471                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5472                        != PackageManager.PERMISSION_GRANTED) {
5473            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5474                    + Binder.getCallingPid()
5475                    + ", uid=" + Binder.getCallingUid()
5476                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5477            Slog.w(TAG, msg);
5478            throw new SecurityException(msg);
5479        }
5480
5481        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5482                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5483        long callingId = Binder.clearCallingIdentity();
5484        try {
5485            IPackageManager pm = AppGlobals.getPackageManager();
5486            synchronized(this) {
5487                int appId = -1;
5488                try {
5489                    appId = UserHandle.getAppId(
5490                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5491                } catch (RemoteException e) {
5492                }
5493                if (appId == -1) {
5494                    Slog.w(TAG, "Invalid packageName: " + packageName);
5495                    return;
5496                }
5497                killPackageProcessesLocked(packageName, appId, userId,
5498                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5499            }
5500        } finally {
5501            Binder.restoreCallingIdentity(callingId);
5502        }
5503    }
5504
5505    @Override
5506    public void killAllBackgroundProcesses() {
5507        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5508                != PackageManager.PERMISSION_GRANTED) {
5509            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5510                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5511                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5512            Slog.w(TAG, msg);
5513            throw new SecurityException(msg);
5514        }
5515
5516        final long callingId = Binder.clearCallingIdentity();
5517        try {
5518            synchronized (this) {
5519                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5520                final int NP = mProcessNames.getMap().size();
5521                for (int ip = 0; ip < NP; ip++) {
5522                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5523                    final int NA = apps.size();
5524                    for (int ia = 0; ia < NA; ia++) {
5525                        final ProcessRecord app = apps.valueAt(ia);
5526                        if (app.persistent) {
5527                            // We don't kill persistent processes.
5528                            continue;
5529                        }
5530                        if (app.removed) {
5531                            procs.add(app);
5532                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5533                            app.removed = true;
5534                            procs.add(app);
5535                        }
5536                    }
5537                }
5538
5539                final int N = procs.size();
5540                for (int i = 0; i < N; i++) {
5541                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5542                }
5543
5544                mAllowLowerMemLevel = true;
5545
5546                updateOomAdjLocked();
5547                doLowMemReportIfNeededLocked(null);
5548            }
5549        } finally {
5550            Binder.restoreCallingIdentity(callingId);
5551        }
5552    }
5553
5554    /**
5555     * Kills all background processes, except those matching any of the
5556     * specified properties.
5557     *
5558     * @param minTargetSdk the target SDK version at or above which to preserve
5559     *                     processes, or {@code -1} to ignore the target SDK
5560     * @param maxProcState the process state at or below which to preserve
5561     *                     processes, or {@code -1} to ignore the process state
5562     */
5563    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5564        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5565                != PackageManager.PERMISSION_GRANTED) {
5566            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5567                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5568                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5569            Slog.w(TAG, msg);
5570            throw new SecurityException(msg);
5571        }
5572
5573        final long callingId = Binder.clearCallingIdentity();
5574        try {
5575            synchronized (this) {
5576                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5577                final int NP = mProcessNames.getMap().size();
5578                for (int ip = 0; ip < NP; ip++) {
5579                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5580                    final int NA = apps.size();
5581                    for (int ia = 0; ia < NA; ia++) {
5582                        final ProcessRecord app = apps.valueAt(ia);
5583                        if (app.removed) {
5584                            procs.add(app);
5585                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5586                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5587                            app.removed = true;
5588                            procs.add(app);
5589                        }
5590                    }
5591                }
5592
5593                final int N = procs.size();
5594                for (int i = 0; i < N; i++) {
5595                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5596                }
5597            }
5598        } finally {
5599            Binder.restoreCallingIdentity(callingId);
5600        }
5601    }
5602
5603    @Override
5604    public void forceStopPackage(final String packageName, int userId) {
5605        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5606                != PackageManager.PERMISSION_GRANTED) {
5607            String msg = "Permission Denial: forceStopPackage() from pid="
5608                    + Binder.getCallingPid()
5609                    + ", uid=" + Binder.getCallingUid()
5610                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5611            Slog.w(TAG, msg);
5612            throw new SecurityException(msg);
5613        }
5614        final int callingPid = Binder.getCallingPid();
5615        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5616                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5617        long callingId = Binder.clearCallingIdentity();
5618        try {
5619            IPackageManager pm = AppGlobals.getPackageManager();
5620            synchronized(this) {
5621                int[] users = userId == UserHandle.USER_ALL
5622                        ? mUserController.getUsers() : new int[] { userId };
5623                for (int user : users) {
5624                    int pkgUid = -1;
5625                    try {
5626                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5627                                user);
5628                    } catch (RemoteException e) {
5629                    }
5630                    if (pkgUid == -1) {
5631                        Slog.w(TAG, "Invalid packageName: " + packageName);
5632                        continue;
5633                    }
5634                    try {
5635                        pm.setPackageStoppedState(packageName, true, user);
5636                    } catch (RemoteException e) {
5637                    } catch (IllegalArgumentException e) {
5638                        Slog.w(TAG, "Failed trying to unstop package "
5639                                + packageName + ": " + e);
5640                    }
5641                    if (mUserController.isUserRunningLocked(user, 0)) {
5642                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5643                        finishForceStopPackageLocked(packageName, pkgUid);
5644                    }
5645                }
5646            }
5647        } finally {
5648            Binder.restoreCallingIdentity(callingId);
5649        }
5650    }
5651
5652    @Override
5653    public void addPackageDependency(String packageName) {
5654        synchronized (this) {
5655            int callingPid = Binder.getCallingPid();
5656            if (callingPid == Process.myPid()) {
5657                //  Yeah, um, no.
5658                return;
5659            }
5660            ProcessRecord proc;
5661            synchronized (mPidsSelfLocked) {
5662                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5663            }
5664            if (proc != null) {
5665                if (proc.pkgDeps == null) {
5666                    proc.pkgDeps = new ArraySet<String>(1);
5667                }
5668                proc.pkgDeps.add(packageName);
5669            }
5670        }
5671    }
5672
5673    /*
5674     * The pkg name and app id have to be specified.
5675     */
5676    @Override
5677    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5678        if (pkg == null) {
5679            return;
5680        }
5681        // Make sure the uid is valid.
5682        if (appid < 0) {
5683            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5684            return;
5685        }
5686        int callerUid = Binder.getCallingUid();
5687        // Only the system server can kill an application
5688        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5689            // Post an aysnc message to kill the application
5690            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5691            msg.arg1 = appid;
5692            msg.arg2 = 0;
5693            Bundle bundle = new Bundle();
5694            bundle.putString("pkg", pkg);
5695            bundle.putString("reason", reason);
5696            msg.obj = bundle;
5697            mHandler.sendMessage(msg);
5698        } else {
5699            throw new SecurityException(callerUid + " cannot kill pkg: " +
5700                    pkg);
5701        }
5702    }
5703
5704    @Override
5705    public void closeSystemDialogs(String reason) {
5706        enforceNotIsolatedCaller("closeSystemDialogs");
5707
5708        final int pid = Binder.getCallingPid();
5709        final int uid = Binder.getCallingUid();
5710        final long origId = Binder.clearCallingIdentity();
5711        try {
5712            synchronized (this) {
5713                // Only allow this from foreground processes, so that background
5714                // applications can't abuse it to prevent system UI from being shown.
5715                if (uid >= Process.FIRST_APPLICATION_UID) {
5716                    ProcessRecord proc;
5717                    synchronized (mPidsSelfLocked) {
5718                        proc = mPidsSelfLocked.get(pid);
5719                    }
5720                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5721                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5722                                + " from background process " + proc);
5723                        return;
5724                    }
5725                }
5726                closeSystemDialogsLocked(reason);
5727            }
5728        } finally {
5729            Binder.restoreCallingIdentity(origId);
5730        }
5731    }
5732
5733    void closeSystemDialogsLocked(String reason) {
5734        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5735        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5736                | Intent.FLAG_RECEIVER_FOREGROUND);
5737        if (reason != null) {
5738            intent.putExtra("reason", reason);
5739        }
5740        mWindowManager.closeSystemDialogs(reason);
5741
5742        mStackSupervisor.closeSystemDialogsLocked();
5743
5744        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5745                AppOpsManager.OP_NONE, null, false, false,
5746                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5747    }
5748
5749    @Override
5750    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5751        enforceNotIsolatedCaller("getProcessMemoryInfo");
5752        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5753        for (int i=pids.length-1; i>=0; i--) {
5754            ProcessRecord proc;
5755            int oomAdj;
5756            synchronized (this) {
5757                synchronized (mPidsSelfLocked) {
5758                    proc = mPidsSelfLocked.get(pids[i]);
5759                    oomAdj = proc != null ? proc.setAdj : 0;
5760                }
5761            }
5762            infos[i] = new Debug.MemoryInfo();
5763            Debug.getMemoryInfo(pids[i], infos[i]);
5764            if (proc != null) {
5765                synchronized (this) {
5766                    if (proc.thread != null && proc.setAdj == oomAdj) {
5767                        // Record this for posterity if the process has been stable.
5768                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5769                                infos[i].getTotalUss(), false, proc.pkgList);
5770                    }
5771                }
5772            }
5773        }
5774        return infos;
5775    }
5776
5777    @Override
5778    public long[] getProcessPss(int[] pids) {
5779        enforceNotIsolatedCaller("getProcessPss");
5780        long[] pss = new long[pids.length];
5781        for (int i=pids.length-1; i>=0; i--) {
5782            ProcessRecord proc;
5783            int oomAdj;
5784            synchronized (this) {
5785                synchronized (mPidsSelfLocked) {
5786                    proc = mPidsSelfLocked.get(pids[i]);
5787                    oomAdj = proc != null ? proc.setAdj : 0;
5788                }
5789            }
5790            long[] tmpUss = new long[1];
5791            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5792            if (proc != null) {
5793                synchronized (this) {
5794                    if (proc.thread != null && proc.setAdj == oomAdj) {
5795                        // Record this for posterity if the process has been stable.
5796                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5797                    }
5798                }
5799            }
5800        }
5801        return pss;
5802    }
5803
5804    @Override
5805    public void killApplicationProcess(String processName, int uid) {
5806        if (processName == null) {
5807            return;
5808        }
5809
5810        int callerUid = Binder.getCallingUid();
5811        // Only the system server can kill an application
5812        if (callerUid == Process.SYSTEM_UID) {
5813            synchronized (this) {
5814                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5815                if (app != null && app.thread != null) {
5816                    try {
5817                        app.thread.scheduleSuicide();
5818                    } catch (RemoteException e) {
5819                        // If the other end already died, then our work here is done.
5820                    }
5821                } else {
5822                    Slog.w(TAG, "Process/uid not found attempting kill of "
5823                            + processName + " / " + uid);
5824                }
5825            }
5826        } else {
5827            throw new SecurityException(callerUid + " cannot kill app process: " +
5828                    processName);
5829        }
5830    }
5831
5832    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5833        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5834                false, true, false, false, UserHandle.getUserId(uid), reason);
5835    }
5836
5837    private void finishForceStopPackageLocked(final String packageName, int uid) {
5838        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5839                Uri.fromParts("package", packageName, null));
5840        if (!mProcessesReady) {
5841            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5842                    | Intent.FLAG_RECEIVER_FOREGROUND);
5843        }
5844        intent.putExtra(Intent.EXTRA_UID, uid);
5845        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5846        broadcastIntentLocked(null, null, intent,
5847                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5848                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5849    }
5850
5851
5852    private final boolean killPackageProcessesLocked(String packageName, int appId,
5853            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5854            boolean doit, boolean evenPersistent, String reason) {
5855        ArrayList<ProcessRecord> procs = new ArrayList<>();
5856
5857        // Remove all processes this package may have touched: all with the
5858        // same UID (except for the system or root user), and all whose name
5859        // matches the package name.
5860        final int NP = mProcessNames.getMap().size();
5861        for (int ip=0; ip<NP; ip++) {
5862            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5863            final int NA = apps.size();
5864            for (int ia=0; ia<NA; ia++) {
5865                ProcessRecord app = apps.valueAt(ia);
5866                if (app.persistent && !evenPersistent) {
5867                    // we don't kill persistent processes
5868                    continue;
5869                }
5870                if (app.removed) {
5871                    if (doit) {
5872                        procs.add(app);
5873                    }
5874                    continue;
5875                }
5876
5877                // Skip process if it doesn't meet our oom adj requirement.
5878                if (app.setAdj < minOomAdj) {
5879                    continue;
5880                }
5881
5882                // If no package is specified, we call all processes under the
5883                // give user id.
5884                if (packageName == null) {
5885                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5886                        continue;
5887                    }
5888                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5889                        continue;
5890                    }
5891                // Package has been specified, we want to hit all processes
5892                // that match it.  We need to qualify this by the processes
5893                // that are running under the specified app and user ID.
5894                } else {
5895                    final boolean isDep = app.pkgDeps != null
5896                            && app.pkgDeps.contains(packageName);
5897                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5898                        continue;
5899                    }
5900                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5901                        continue;
5902                    }
5903                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5904                        continue;
5905                    }
5906                }
5907
5908                // Process has passed all conditions, kill it!
5909                if (!doit) {
5910                    return true;
5911                }
5912                app.removed = true;
5913                procs.add(app);
5914            }
5915        }
5916
5917        int N = procs.size();
5918        for (int i=0; i<N; i++) {
5919            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5920        }
5921        updateOomAdjLocked();
5922        return N > 0;
5923    }
5924
5925    private void cleanupDisabledPackageComponentsLocked(
5926            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5927
5928        Set<String> disabledClasses = null;
5929        boolean packageDisabled = false;
5930        IPackageManager pm = AppGlobals.getPackageManager();
5931
5932        if (changedClasses == null) {
5933            // Nothing changed...
5934            return;
5935        }
5936
5937        // Determine enable/disable state of the package and its components.
5938        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5939        for (int i = changedClasses.length - 1; i >= 0; i--) {
5940            final String changedClass = changedClasses[i];
5941
5942            if (changedClass.equals(packageName)) {
5943                try {
5944                    // Entire package setting changed
5945                    enabled = pm.getApplicationEnabledSetting(packageName,
5946                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5947                } catch (Exception e) {
5948                    // No such package/component; probably racing with uninstall.  In any
5949                    // event it means we have nothing further to do here.
5950                    return;
5951                }
5952                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5953                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5954                if (packageDisabled) {
5955                    // Entire package is disabled.
5956                    // No need to continue to check component states.
5957                    disabledClasses = null;
5958                    break;
5959                }
5960            } else {
5961                try {
5962                    enabled = pm.getComponentEnabledSetting(
5963                            new ComponentName(packageName, changedClass),
5964                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5965                } catch (Exception e) {
5966                    // As above, probably racing with uninstall.
5967                    return;
5968                }
5969                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5970                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5971                    if (disabledClasses == null) {
5972                        disabledClasses = new ArraySet<>(changedClasses.length);
5973                    }
5974                    disabledClasses.add(changedClass);
5975                }
5976            }
5977        }
5978
5979        if (!packageDisabled && disabledClasses == null) {
5980            // Nothing to do here...
5981            return;
5982        }
5983
5984        // Clean-up disabled activities.
5985        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5986                packageName, disabledClasses, true, false, userId) && mBooted) {
5987            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5988            mStackSupervisor.scheduleIdleLocked();
5989        }
5990
5991        // Clean-up disabled tasks
5992        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5993
5994        // Clean-up disabled services.
5995        mServices.bringDownDisabledPackageServicesLocked(
5996                packageName, disabledClasses, userId, false, killProcess, true);
5997
5998        // Clean-up disabled providers.
5999        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6000        mProviderMap.collectPackageProvidersLocked(
6001                packageName, disabledClasses, true, false, userId, providers);
6002        for (int i = providers.size() - 1; i >= 0; i--) {
6003            removeDyingProviderLocked(null, providers.get(i), true);
6004        }
6005
6006        // Clean-up disabled broadcast receivers.
6007        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6008            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6009                    packageName, disabledClasses, userId, true);
6010        }
6011
6012    }
6013
6014    final boolean clearBroadcastQueueForUserLocked(int userId) {
6015        boolean didSomething = false;
6016        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6017            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6018                    null, null, userId, true);
6019        }
6020        return didSomething;
6021    }
6022
6023    final boolean forceStopPackageLocked(String packageName, int appId,
6024            boolean callerWillRestart, boolean purgeCache, boolean doit,
6025            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6026        int i;
6027
6028        if (userId == UserHandle.USER_ALL && packageName == null) {
6029            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6030        }
6031
6032        if (appId < 0 && packageName != null) {
6033            try {
6034                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6035                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6036            } catch (RemoteException e) {
6037            }
6038        }
6039
6040        if (doit) {
6041            if (packageName != null) {
6042                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6043                        + " user=" + userId + ": " + reason);
6044            } else {
6045                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6046            }
6047
6048            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6049        }
6050
6051        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6052                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6053                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6054
6055        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6056                packageName, null, doit, evenPersistent, userId)) {
6057            if (!doit) {
6058                return true;
6059            }
6060            didSomething = true;
6061        }
6062
6063        if (mServices.bringDownDisabledPackageServicesLocked(
6064                packageName, null, userId, evenPersistent, true, doit)) {
6065            if (!doit) {
6066                return true;
6067            }
6068            didSomething = true;
6069        }
6070
6071        if (packageName == null) {
6072            // Remove all sticky broadcasts from this user.
6073            mStickyBroadcasts.remove(userId);
6074        }
6075
6076        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6077        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6078                userId, providers)) {
6079            if (!doit) {
6080                return true;
6081            }
6082            didSomething = true;
6083        }
6084        for (i = providers.size() - 1; i >= 0; i--) {
6085            removeDyingProviderLocked(null, providers.get(i), true);
6086        }
6087
6088        // Remove transient permissions granted from/to this package/user
6089        removeUriPermissionsForPackageLocked(packageName, userId, false);
6090
6091        if (doit) {
6092            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6093                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6094                        packageName, null, userId, doit);
6095            }
6096        }
6097
6098        if (packageName == null || uninstalling) {
6099            // Remove pending intents.  For now we only do this when force
6100            // stopping users, because we have some problems when doing this
6101            // for packages -- app widgets are not currently cleaned up for
6102            // such packages, so they can be left with bad pending intents.
6103            if (mIntentSenderRecords.size() > 0) {
6104                Iterator<WeakReference<PendingIntentRecord>> it
6105                        = mIntentSenderRecords.values().iterator();
6106                while (it.hasNext()) {
6107                    WeakReference<PendingIntentRecord> wpir = it.next();
6108                    if (wpir == null) {
6109                        it.remove();
6110                        continue;
6111                    }
6112                    PendingIntentRecord pir = wpir.get();
6113                    if (pir == null) {
6114                        it.remove();
6115                        continue;
6116                    }
6117                    if (packageName == null) {
6118                        // Stopping user, remove all objects for the user.
6119                        if (pir.key.userId != userId) {
6120                            // Not the same user, skip it.
6121                            continue;
6122                        }
6123                    } else {
6124                        if (UserHandle.getAppId(pir.uid) != appId) {
6125                            // Different app id, skip it.
6126                            continue;
6127                        }
6128                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6129                            // Different user, skip it.
6130                            continue;
6131                        }
6132                        if (!pir.key.packageName.equals(packageName)) {
6133                            // Different package, skip it.
6134                            continue;
6135                        }
6136                    }
6137                    if (!doit) {
6138                        return true;
6139                    }
6140                    didSomething = true;
6141                    it.remove();
6142                    pir.canceled = true;
6143                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6144                        pir.key.activity.pendingResults.remove(pir.ref);
6145                    }
6146                }
6147            }
6148        }
6149
6150        if (doit) {
6151            if (purgeCache && packageName != null) {
6152                AttributeCache ac = AttributeCache.instance();
6153                if (ac != null) {
6154                    ac.removePackage(packageName);
6155                }
6156            }
6157            if (mBooted) {
6158                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6159                mStackSupervisor.scheduleIdleLocked();
6160            }
6161        }
6162
6163        return didSomething;
6164    }
6165
6166    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6167        ProcessRecord old = mProcessNames.remove(name, uid);
6168        if (old != null) {
6169            old.uidRecord.numProcs--;
6170            if (old.uidRecord.numProcs == 0) {
6171                // No more processes using this uid, tell clients it is gone.
6172                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6173                        "No more processes in " + old.uidRecord);
6174                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6175                mActiveUids.remove(uid);
6176                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6177            }
6178            old.uidRecord = null;
6179        }
6180        mIsolatedProcesses.remove(uid);
6181        return old;
6182    }
6183
6184    private final void addProcessNameLocked(ProcessRecord proc) {
6185        // We shouldn't already have a process under this name, but just in case we
6186        // need to clean up whatever may be there now.
6187        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6188        if (old == proc && proc.persistent) {
6189            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6190            Slog.w(TAG, "Re-adding persistent process " + proc);
6191        } else if (old != null) {
6192            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6193        }
6194        UidRecord uidRec = mActiveUids.get(proc.uid);
6195        if (uidRec == null) {
6196            uidRec = new UidRecord(proc.uid);
6197            // This is the first appearance of the uid, report it now!
6198            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6199                    "Creating new process uid: " + uidRec);
6200            mActiveUids.put(proc.uid, uidRec);
6201            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6202            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6203        }
6204        proc.uidRecord = uidRec;
6205        uidRec.numProcs++;
6206        mProcessNames.put(proc.processName, proc.uid, proc);
6207        if (proc.isolated) {
6208            mIsolatedProcesses.put(proc.uid, proc);
6209        }
6210    }
6211
6212    boolean removeProcessLocked(ProcessRecord app,
6213            boolean callerWillRestart, boolean allowRestart, String reason) {
6214        final String name = app.processName;
6215        final int uid = app.uid;
6216        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6217            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6218
6219        ProcessRecord old = mProcessNames.get(name, uid);
6220        if (old != app) {
6221            // This process is no longer active, so nothing to do.
6222            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6223            return false;
6224        }
6225        removeProcessNameLocked(name, uid);
6226        if (mHeavyWeightProcess == app) {
6227            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6228                    mHeavyWeightProcess.userId, 0));
6229            mHeavyWeightProcess = null;
6230        }
6231        boolean needRestart = false;
6232        if (app.pid > 0 && app.pid != MY_PID) {
6233            int pid = app.pid;
6234            synchronized (mPidsSelfLocked) {
6235                mPidsSelfLocked.remove(pid);
6236                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6237            }
6238            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6239            if (app.isolated) {
6240                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6241            }
6242            boolean willRestart = false;
6243            if (app.persistent && !app.isolated) {
6244                if (!callerWillRestart) {
6245                    willRestart = true;
6246                } else {
6247                    needRestart = true;
6248                }
6249            }
6250            app.kill(reason, true);
6251            handleAppDiedLocked(app, willRestart, allowRestart);
6252            if (willRestart) {
6253                removeLruProcessLocked(app);
6254                addAppLocked(app.info, false, null /* ABI override */);
6255            }
6256        } else {
6257            mRemovedProcesses.add(app);
6258        }
6259
6260        return needRestart;
6261    }
6262
6263    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6264        cleanupAppInLaunchingProvidersLocked(app, true);
6265        removeProcessLocked(app, false, true, "timeout publishing content providers");
6266    }
6267
6268    private final void processStartTimedOutLocked(ProcessRecord app) {
6269        final int pid = app.pid;
6270        boolean gone = false;
6271        synchronized (mPidsSelfLocked) {
6272            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6273            if (knownApp != null && knownApp.thread == null) {
6274                mPidsSelfLocked.remove(pid);
6275                gone = true;
6276            }
6277        }
6278
6279        if (gone) {
6280            Slog.w(TAG, "Process " + app + " failed to attach");
6281            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6282                    pid, app.uid, app.processName);
6283            removeProcessNameLocked(app.processName, app.uid);
6284            if (mHeavyWeightProcess == app) {
6285                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6286                        mHeavyWeightProcess.userId, 0));
6287                mHeavyWeightProcess = null;
6288            }
6289            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6290            if (app.isolated) {
6291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6292            }
6293            // Take care of any launching providers waiting for this process.
6294            cleanupAppInLaunchingProvidersLocked(app, true);
6295            // Take care of any services that are waiting for the process.
6296            mServices.processStartTimedOutLocked(app);
6297            app.kill("start timeout", true);
6298            removeLruProcessLocked(app);
6299            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6300                Slog.w(TAG, "Unattached app died before backup, skipping");
6301                try {
6302                    IBackupManager bm = IBackupManager.Stub.asInterface(
6303                            ServiceManager.getService(Context.BACKUP_SERVICE));
6304                    bm.agentDisconnected(app.info.packageName);
6305                } catch (RemoteException e) {
6306                    // Can't happen; the backup manager is local
6307                }
6308            }
6309            if (isPendingBroadcastProcessLocked(pid)) {
6310                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6311                skipPendingBroadcastLocked(pid);
6312            }
6313        } else {
6314            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6315        }
6316    }
6317
6318    private final boolean attachApplicationLocked(IApplicationThread thread,
6319            int pid) {
6320
6321        // Find the application record that is being attached...  either via
6322        // the pid if we are running in multiple processes, or just pull the
6323        // next app record if we are emulating process with anonymous threads.
6324        ProcessRecord app;
6325        if (pid != MY_PID && pid >= 0) {
6326            synchronized (mPidsSelfLocked) {
6327                app = mPidsSelfLocked.get(pid);
6328            }
6329        } else {
6330            app = null;
6331        }
6332
6333        if (app == null) {
6334            Slog.w(TAG, "No pending application record for pid " + pid
6335                    + " (IApplicationThread " + thread + "); dropping process");
6336            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6337            if (pid > 0 && pid != MY_PID) {
6338                Process.killProcessQuiet(pid);
6339                //TODO: killProcessGroup(app.info.uid, pid);
6340            } else {
6341                try {
6342                    thread.scheduleExit();
6343                } catch (Exception e) {
6344                    // Ignore exceptions.
6345                }
6346            }
6347            return false;
6348        }
6349
6350        // If this application record is still attached to a previous
6351        // process, clean it up now.
6352        if (app.thread != null) {
6353            handleAppDiedLocked(app, true, true);
6354        }
6355
6356        // Tell the process all about itself.
6357
6358        if (DEBUG_ALL) Slog.v(
6359                TAG, "Binding process pid " + pid + " to record " + app);
6360
6361        final String processName = app.processName;
6362        try {
6363            AppDeathRecipient adr = new AppDeathRecipient(
6364                    app, pid, thread);
6365            thread.asBinder().linkToDeath(adr, 0);
6366            app.deathRecipient = adr;
6367        } catch (RemoteException e) {
6368            app.resetPackageList(mProcessStats);
6369            startProcessLocked(app, "link fail", processName);
6370            return false;
6371        }
6372
6373        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6374
6375        app.makeActive(thread, mProcessStats);
6376        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6377        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6378        app.forcingToForeground = null;
6379        updateProcessForegroundLocked(app, false, false);
6380        app.hasShownUi = false;
6381        app.debugging = false;
6382        app.cached = false;
6383        app.killedByAm = false;
6384
6385        // We carefully use the same state that PackageManager uses for
6386        // filtering, since we use this flag to decide if we need to install
6387        // providers when user is unlocked later
6388        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6389
6390        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6391
6392        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6393        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6394
6395        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6396            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6397            msg.obj = app;
6398            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6399        }
6400
6401        if (!normalMode) {
6402            Slog.i(TAG, "Launching preboot mode app: " + app);
6403        }
6404
6405        if (DEBUG_ALL) Slog.v(
6406            TAG, "New app record " + app
6407            + " thread=" + thread.asBinder() + " pid=" + pid);
6408        try {
6409            int testMode = IApplicationThread.DEBUG_OFF;
6410            if (mDebugApp != null && mDebugApp.equals(processName)) {
6411                testMode = mWaitForDebugger
6412                    ? IApplicationThread.DEBUG_WAIT
6413                    : IApplicationThread.DEBUG_ON;
6414                app.debugging = true;
6415                if (mDebugTransient) {
6416                    mDebugApp = mOrigDebugApp;
6417                    mWaitForDebugger = mOrigWaitForDebugger;
6418                }
6419            }
6420            String profileFile = app.instrumentationProfileFile;
6421            ParcelFileDescriptor profileFd = null;
6422            int samplingInterval = 0;
6423            boolean profileAutoStop = false;
6424            if (mProfileApp != null && mProfileApp.equals(processName)) {
6425                mProfileProc = app;
6426                profileFile = mProfileFile;
6427                profileFd = mProfileFd;
6428                samplingInterval = mSamplingInterval;
6429                profileAutoStop = mAutoStopProfiler;
6430            }
6431            boolean enableTrackAllocation = false;
6432            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6433                enableTrackAllocation = true;
6434                mTrackAllocationApp = null;
6435            }
6436
6437            // If the app is being launched for restore or full backup, set it up specially
6438            boolean isRestrictedBackupMode = false;
6439            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6440                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6441                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6442                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6443                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6444            }
6445
6446            if (app.instrumentationClass != null) {
6447                notifyPackageUse(app.instrumentationClass.getPackageName(),
6448                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6449            }
6450            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6451                    + processName + " with config " + mConfiguration);
6452            ApplicationInfo appInfo = app.instrumentationInfo != null
6453                    ? app.instrumentationInfo : app.info;
6454            app.compat = compatibilityInfoForPackageLocked(appInfo);
6455            if (profileFd != null) {
6456                profileFd = profileFd.dup();
6457            }
6458            ProfilerInfo profilerInfo = profileFile == null ? null
6459                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6460            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6461                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6462                    app.instrumentationUiAutomationConnection, testMode,
6463                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6464                    isRestrictedBackupMode || !normalMode, app.persistent,
6465                    new Configuration(mConfiguration), app.compat,
6466                    getCommonServicesLocked(app.isolated),
6467                    mCoreSettingsObserver.getCoreSettingsLocked());
6468            updateLruProcessLocked(app, false, null);
6469            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6470        } catch (Exception e) {
6471            // todo: Yikes!  What should we do?  For now we will try to
6472            // start another process, but that could easily get us in
6473            // an infinite loop of restarting processes...
6474            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6475
6476            app.resetPackageList(mProcessStats);
6477            app.unlinkDeathRecipient();
6478            startProcessLocked(app, "bind fail", processName);
6479            return false;
6480        }
6481
6482        // Remove this record from the list of starting applications.
6483        mPersistentStartingProcesses.remove(app);
6484        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6485                "Attach application locked removing on hold: " + app);
6486        mProcessesOnHold.remove(app);
6487
6488        boolean badApp = false;
6489        boolean didSomething = false;
6490
6491        // See if the top visible activity is waiting to run in this process...
6492        if (normalMode) {
6493            try {
6494                if (mStackSupervisor.attachApplicationLocked(app)) {
6495                    didSomething = true;
6496                }
6497            } catch (Exception e) {
6498                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6499                badApp = true;
6500            }
6501        }
6502
6503        // Find any services that should be running in this process...
6504        if (!badApp) {
6505            try {
6506                didSomething |= mServices.attachApplicationLocked(app, processName);
6507            } catch (Exception e) {
6508                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6509                badApp = true;
6510            }
6511        }
6512
6513        // Check if a next-broadcast receiver is in this process...
6514        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6515            try {
6516                didSomething |= sendPendingBroadcastsLocked(app);
6517            } catch (Exception e) {
6518                // If the app died trying to launch the receiver we declare it 'bad'
6519                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6520                badApp = true;
6521            }
6522        }
6523
6524        // Check whether the next backup agent is in this process...
6525        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6526            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6527                    "New app is backup target, launching agent for " + app);
6528            notifyPackageUse(mBackupTarget.appInfo.packageName,
6529                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6530            try {
6531                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6532                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6533                        mBackupTarget.backupMode);
6534            } catch (Exception e) {
6535                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6536                badApp = true;
6537            }
6538        }
6539
6540        if (badApp) {
6541            app.kill("error during init", true);
6542            handleAppDiedLocked(app, false, true);
6543            return false;
6544        }
6545
6546        if (!didSomething) {
6547            updateOomAdjLocked();
6548        }
6549
6550        return true;
6551    }
6552
6553    @Override
6554    public final void attachApplication(IApplicationThread thread) {
6555        synchronized (this) {
6556            int callingPid = Binder.getCallingPid();
6557            final long origId = Binder.clearCallingIdentity();
6558            attachApplicationLocked(thread, callingPid);
6559            Binder.restoreCallingIdentity(origId);
6560        }
6561    }
6562
6563    @Override
6564    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6565        final long origId = Binder.clearCallingIdentity();
6566        synchronized (this) {
6567            ActivityStack stack = ActivityRecord.getStackLocked(token);
6568            if (stack != null) {
6569                ActivityRecord r =
6570                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6571                if (stopProfiling) {
6572                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6573                        try {
6574                            mProfileFd.close();
6575                        } catch (IOException e) {
6576                        }
6577                        clearProfilerLocked();
6578                    }
6579                }
6580            }
6581        }
6582        Binder.restoreCallingIdentity(origId);
6583    }
6584
6585    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6586        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6587                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6588    }
6589
6590    void enableScreenAfterBoot() {
6591        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6592                SystemClock.uptimeMillis());
6593        mWindowManager.enableScreenAfterBoot();
6594
6595        synchronized (this) {
6596            updateEventDispatchingLocked();
6597        }
6598    }
6599
6600    @Override
6601    public void showBootMessage(final CharSequence msg, final boolean always) {
6602        if (Binder.getCallingUid() != Process.myUid()) {
6603            // These days only the core system can call this, so apps can't get in
6604            // the way of what we show about running them.
6605        }
6606        mWindowManager.showBootMessage(msg, always);
6607    }
6608
6609    @Override
6610    public void keyguardWaitingForActivityDrawn() {
6611        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6612        final long token = Binder.clearCallingIdentity();
6613        try {
6614            synchronized (this) {
6615                if (DEBUG_LOCKSCREEN) logLockScreen("");
6616                mWindowManager.keyguardWaitingForActivityDrawn();
6617                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6618                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6619                    updateSleepIfNeededLocked();
6620                }
6621            }
6622        } finally {
6623            Binder.restoreCallingIdentity(token);
6624        }
6625    }
6626
6627    @Override
6628    public void keyguardGoingAway(int flags) {
6629        enforceNotIsolatedCaller("keyguardGoingAway");
6630        final long token = Binder.clearCallingIdentity();
6631        try {
6632            synchronized (this) {
6633                if (DEBUG_LOCKSCREEN) logLockScreen("");
6634                mWindowManager.keyguardGoingAway(flags);
6635                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6636                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6637                    updateSleepIfNeededLocked();
6638
6639                    // Some stack visibility might change (e.g. docked stack)
6640                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6641                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6642                }
6643            }
6644        } finally {
6645            Binder.restoreCallingIdentity(token);
6646        }
6647    }
6648
6649    final void finishBooting() {
6650        synchronized (this) {
6651            if (!mBootAnimationComplete) {
6652                mCallFinishBooting = true;
6653                return;
6654            }
6655            mCallFinishBooting = false;
6656        }
6657
6658        ArraySet<String> completedIsas = new ArraySet<String>();
6659        for (String abi : Build.SUPPORTED_ABIS) {
6660            Process.establishZygoteConnectionForAbi(abi);
6661            final String instructionSet = VMRuntime.getInstructionSet(abi);
6662            if (!completedIsas.contains(instructionSet)) {
6663                try {
6664                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6665                } catch (InstallerException e) {
6666                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6667                            e.getMessage() +")");
6668                }
6669                completedIsas.add(instructionSet);
6670            }
6671        }
6672
6673        IntentFilter pkgFilter = new IntentFilter();
6674        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6675        pkgFilter.addDataScheme("package");
6676        mContext.registerReceiver(new BroadcastReceiver() {
6677            @Override
6678            public void onReceive(Context context, Intent intent) {
6679                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6680                if (pkgs != null) {
6681                    for (String pkg : pkgs) {
6682                        synchronized (ActivityManagerService.this) {
6683                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6684                                    0, "query restart")) {
6685                                setResultCode(Activity.RESULT_OK);
6686                                return;
6687                            }
6688                        }
6689                    }
6690                }
6691            }
6692        }, pkgFilter);
6693
6694        IntentFilter dumpheapFilter = new IntentFilter();
6695        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6696        mContext.registerReceiver(new BroadcastReceiver() {
6697            @Override
6698            public void onReceive(Context context, Intent intent) {
6699                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6700                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6701                } else {
6702                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6703                }
6704            }
6705        }, dumpheapFilter);
6706
6707        // Let system services know.
6708        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6709
6710        synchronized (this) {
6711            // Ensure that any processes we had put on hold are now started
6712            // up.
6713            final int NP = mProcessesOnHold.size();
6714            if (NP > 0) {
6715                ArrayList<ProcessRecord> procs =
6716                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6717                for (int ip=0; ip<NP; ip++) {
6718                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6719                            + procs.get(ip));
6720                    startProcessLocked(procs.get(ip), "on-hold", null);
6721                }
6722            }
6723
6724            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6725                // Start looking for apps that are abusing wake locks.
6726                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6727                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6728                // Tell anyone interested that we are done booting!
6729                SystemProperties.set("sys.boot_completed", "1");
6730
6731                // And trigger dev.bootcomplete if we are not showing encryption progress
6732                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6733                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6734                    SystemProperties.set("dev.bootcomplete", "1");
6735                }
6736                mUserController.sendBootCompletedLocked(
6737                        new IIntentReceiver.Stub() {
6738                            @Override
6739                            public void performReceive(Intent intent, int resultCode,
6740                                    String data, Bundle extras, boolean ordered,
6741                                    boolean sticky, int sendingUser) {
6742                                synchronized (ActivityManagerService.this) {
6743                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6744                                            true, false);
6745                                }
6746                            }
6747                        });
6748                scheduleStartProfilesLocked();
6749            }
6750        }
6751    }
6752
6753    @Override
6754    public void bootAnimationComplete() {
6755        final boolean callFinishBooting;
6756        synchronized (this) {
6757            callFinishBooting = mCallFinishBooting;
6758            mBootAnimationComplete = true;
6759        }
6760        if (callFinishBooting) {
6761            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6762            finishBooting();
6763            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6764        }
6765    }
6766
6767    final void ensureBootCompleted() {
6768        boolean booting;
6769        boolean enableScreen;
6770        synchronized (this) {
6771            booting = mBooting;
6772            mBooting = false;
6773            enableScreen = !mBooted;
6774            mBooted = true;
6775        }
6776
6777        if (booting) {
6778            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6779            finishBooting();
6780            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6781        }
6782
6783        if (enableScreen) {
6784            enableScreenAfterBoot();
6785        }
6786    }
6787
6788    @Override
6789    public final void activityResumed(IBinder token) {
6790        final long origId = Binder.clearCallingIdentity();
6791        synchronized(this) {
6792            ActivityStack stack = ActivityRecord.getStackLocked(token);
6793            if (stack != null) {
6794                stack.activityResumedLocked(token);
6795            }
6796        }
6797        Binder.restoreCallingIdentity(origId);
6798    }
6799
6800    @Override
6801    public final void activityPaused(IBinder token) {
6802        final long origId = Binder.clearCallingIdentity();
6803        synchronized(this) {
6804            ActivityStack stack = ActivityRecord.getStackLocked(token);
6805            if (stack != null) {
6806                stack.activityPausedLocked(token, false);
6807            }
6808        }
6809        Binder.restoreCallingIdentity(origId);
6810    }
6811
6812    @Override
6813    public final void activityStopped(IBinder token, Bundle icicle,
6814            PersistableBundle persistentState, CharSequence description) {
6815        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6816
6817        // Refuse possible leaked file descriptors
6818        if (icicle != null && icicle.hasFileDescriptors()) {
6819            throw new IllegalArgumentException("File descriptors passed in Bundle");
6820        }
6821
6822        final long origId = Binder.clearCallingIdentity();
6823
6824        synchronized (this) {
6825            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6826            if (r != null) {
6827                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6828            }
6829        }
6830
6831        trimApplications();
6832
6833        Binder.restoreCallingIdentity(origId);
6834    }
6835
6836    @Override
6837    public final void activityDestroyed(IBinder token) {
6838        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6839        synchronized (this) {
6840            ActivityStack stack = ActivityRecord.getStackLocked(token);
6841            if (stack != null) {
6842                stack.activityDestroyedLocked(token, "activityDestroyed");
6843            }
6844        }
6845    }
6846
6847    @Override
6848    public final void activityRelaunched(IBinder token) {
6849        final long origId = Binder.clearCallingIdentity();
6850        synchronized (this) {
6851            mStackSupervisor.activityRelaunchedLocked(token);
6852        }
6853        Binder.restoreCallingIdentity(origId);
6854    }
6855
6856    @Override
6857    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6858            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6859        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6860                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6861        synchronized (this) {
6862            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6863            if (record == null) {
6864                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6865                        + "found for: " + token);
6866            }
6867            record.setSizeConfigurations(horizontalSizeConfiguration,
6868                    verticalSizeConfigurations, smallestSizeConfigurations);
6869        }
6870    }
6871
6872    @Override
6873    public final void backgroundResourcesReleased(IBinder token) {
6874        final long origId = Binder.clearCallingIdentity();
6875        try {
6876            synchronized (this) {
6877                ActivityStack stack = ActivityRecord.getStackLocked(token);
6878                if (stack != null) {
6879                    stack.backgroundResourcesReleased();
6880                }
6881            }
6882        } finally {
6883            Binder.restoreCallingIdentity(origId);
6884        }
6885    }
6886
6887    @Override
6888    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6889        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6890    }
6891
6892    @Override
6893    public final void notifyEnterAnimationComplete(IBinder token) {
6894        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6895    }
6896
6897    @Override
6898    public String getCallingPackage(IBinder token) {
6899        synchronized (this) {
6900            ActivityRecord r = getCallingRecordLocked(token);
6901            return r != null ? r.info.packageName : null;
6902        }
6903    }
6904
6905    @Override
6906    public ComponentName getCallingActivity(IBinder token) {
6907        synchronized (this) {
6908            ActivityRecord r = getCallingRecordLocked(token);
6909            return r != null ? r.intent.getComponent() : null;
6910        }
6911    }
6912
6913    private ActivityRecord getCallingRecordLocked(IBinder token) {
6914        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6915        if (r == null) {
6916            return null;
6917        }
6918        return r.resultTo;
6919    }
6920
6921    @Override
6922    public ComponentName getActivityClassForToken(IBinder token) {
6923        synchronized(this) {
6924            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6925            if (r == null) {
6926                return null;
6927            }
6928            return r.intent.getComponent();
6929        }
6930    }
6931
6932    @Override
6933    public String getPackageForToken(IBinder token) {
6934        synchronized(this) {
6935            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6936            if (r == null) {
6937                return null;
6938            }
6939            return r.packageName;
6940        }
6941    }
6942
6943    @Override
6944    public boolean isRootVoiceInteraction(IBinder token) {
6945        synchronized(this) {
6946            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6947            if (r == null) {
6948                return false;
6949            }
6950            return r.rootVoiceInteraction;
6951        }
6952    }
6953
6954    @Override
6955    public IIntentSender getIntentSender(int type,
6956            String packageName, IBinder token, String resultWho,
6957            int requestCode, Intent[] intents, String[] resolvedTypes,
6958            int flags, Bundle bOptions, int userId) {
6959        enforceNotIsolatedCaller("getIntentSender");
6960        // Refuse possible leaked file descriptors
6961        if (intents != null) {
6962            if (intents.length < 1) {
6963                throw new IllegalArgumentException("Intents array length must be >= 1");
6964            }
6965            for (int i=0; i<intents.length; i++) {
6966                Intent intent = intents[i];
6967                if (intent != null) {
6968                    if (intent.hasFileDescriptors()) {
6969                        throw new IllegalArgumentException("File descriptors passed in Intent");
6970                    }
6971                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6972                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6973                        throw new IllegalArgumentException(
6974                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6975                    }
6976                    intents[i] = new Intent(intent);
6977                }
6978            }
6979            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6980                throw new IllegalArgumentException(
6981                        "Intent array length does not match resolvedTypes length");
6982            }
6983        }
6984        if (bOptions != null) {
6985            if (bOptions.hasFileDescriptors()) {
6986                throw new IllegalArgumentException("File descriptors passed in options");
6987            }
6988        }
6989
6990        synchronized(this) {
6991            int callingUid = Binder.getCallingUid();
6992            int origUserId = userId;
6993            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6994                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6995                    ALLOW_NON_FULL, "getIntentSender", null);
6996            if (origUserId == UserHandle.USER_CURRENT) {
6997                // We don't want to evaluate this until the pending intent is
6998                // actually executed.  However, we do want to always do the
6999                // security checking for it above.
7000                userId = UserHandle.USER_CURRENT;
7001            }
7002            try {
7003                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7004                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7005                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7006                    if (!UserHandle.isSameApp(callingUid, uid)) {
7007                        String msg = "Permission Denial: getIntentSender() from pid="
7008                            + Binder.getCallingPid()
7009                            + ", uid=" + Binder.getCallingUid()
7010                            + ", (need uid=" + uid + ")"
7011                            + " is not allowed to send as package " + packageName;
7012                        Slog.w(TAG, msg);
7013                        throw new SecurityException(msg);
7014                    }
7015                }
7016
7017                return getIntentSenderLocked(type, packageName, callingUid, userId,
7018                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7019
7020            } catch (RemoteException e) {
7021                throw new SecurityException(e);
7022            }
7023        }
7024    }
7025
7026    IIntentSender getIntentSenderLocked(int type, String packageName,
7027            int callingUid, int userId, IBinder token, String resultWho,
7028            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7029            Bundle bOptions) {
7030        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7031        ActivityRecord activity = null;
7032        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7033            activity = ActivityRecord.isInStackLocked(token);
7034            if (activity == null) {
7035                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7036                return null;
7037            }
7038            if (activity.finishing) {
7039                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7040                return null;
7041            }
7042        }
7043
7044        // We're going to be splicing together extras before sending, so we're
7045        // okay poking into any contained extras.
7046        if (intents != null) {
7047            for (int i = 0; i < intents.length; i++) {
7048                intents[i].setDefusable(true);
7049            }
7050        }
7051        Bundle.setDefusable(bOptions, true);
7052
7053        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7054        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7055        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7056        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7057                |PendingIntent.FLAG_UPDATE_CURRENT);
7058
7059        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7060                type, packageName, activity, resultWho,
7061                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7062        WeakReference<PendingIntentRecord> ref;
7063        ref = mIntentSenderRecords.get(key);
7064        PendingIntentRecord rec = ref != null ? ref.get() : null;
7065        if (rec != null) {
7066            if (!cancelCurrent) {
7067                if (updateCurrent) {
7068                    if (rec.key.requestIntent != null) {
7069                        rec.key.requestIntent.replaceExtras(intents != null ?
7070                                intents[intents.length - 1] : null);
7071                    }
7072                    if (intents != null) {
7073                        intents[intents.length-1] = rec.key.requestIntent;
7074                        rec.key.allIntents = intents;
7075                        rec.key.allResolvedTypes = resolvedTypes;
7076                    } else {
7077                        rec.key.allIntents = null;
7078                        rec.key.allResolvedTypes = null;
7079                    }
7080                }
7081                return rec;
7082            }
7083            rec.canceled = true;
7084            mIntentSenderRecords.remove(key);
7085        }
7086        if (noCreate) {
7087            return rec;
7088        }
7089        rec = new PendingIntentRecord(this, key, callingUid);
7090        mIntentSenderRecords.put(key, rec.ref);
7091        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7092            if (activity.pendingResults == null) {
7093                activity.pendingResults
7094                        = new HashSet<WeakReference<PendingIntentRecord>>();
7095            }
7096            activity.pendingResults.add(rec.ref);
7097        }
7098        return rec;
7099    }
7100
7101    @Override
7102    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7103            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7104        if (target instanceof PendingIntentRecord) {
7105            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7106                    finishedReceiver, requiredPermission, options);
7107        } else {
7108            if (intent == null) {
7109                // Weird case: someone has given us their own custom IIntentSender, and now
7110                // they have someone else trying to send to it but of course this isn't
7111                // really a PendingIntent, so there is no base Intent, and the caller isn't
7112                // supplying an Intent... but we never want to dispatch a null Intent to
7113                // a receiver, so um...  let's make something up.
7114                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7115                intent = new Intent(Intent.ACTION_MAIN);
7116            }
7117            try {
7118                target.send(code, intent, resolvedType, null, requiredPermission, options);
7119            } catch (RemoteException e) {
7120            }
7121            // Platform code can rely on getting a result back when the send is done, but if
7122            // this intent sender is from outside of the system we can't rely on it doing that.
7123            // So instead we don't give it the result receiver, and instead just directly
7124            // report the finish immediately.
7125            if (finishedReceiver != null) {
7126                try {
7127                    finishedReceiver.performReceive(intent, 0,
7128                            null, null, false, false, UserHandle.getCallingUserId());
7129                } catch (RemoteException e) {
7130                }
7131            }
7132            return 0;
7133        }
7134    }
7135
7136    @Override
7137    public void cancelIntentSender(IIntentSender sender) {
7138        if (!(sender instanceof PendingIntentRecord)) {
7139            return;
7140        }
7141        synchronized(this) {
7142            PendingIntentRecord rec = (PendingIntentRecord)sender;
7143            try {
7144                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7145                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7146                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7147                    String msg = "Permission Denial: cancelIntentSender() from pid="
7148                        + Binder.getCallingPid()
7149                        + ", uid=" + Binder.getCallingUid()
7150                        + " is not allowed to cancel packges "
7151                        + rec.key.packageName;
7152                    Slog.w(TAG, msg);
7153                    throw new SecurityException(msg);
7154                }
7155            } catch (RemoteException e) {
7156                throw new SecurityException(e);
7157            }
7158            cancelIntentSenderLocked(rec, true);
7159        }
7160    }
7161
7162    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7163        rec.canceled = true;
7164        mIntentSenderRecords.remove(rec.key);
7165        if (cleanActivity && rec.key.activity != null) {
7166            rec.key.activity.pendingResults.remove(rec.ref);
7167        }
7168    }
7169
7170    @Override
7171    public String getPackageForIntentSender(IIntentSender pendingResult) {
7172        if (!(pendingResult instanceof PendingIntentRecord)) {
7173            return null;
7174        }
7175        try {
7176            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7177            return res.key.packageName;
7178        } catch (ClassCastException e) {
7179        }
7180        return null;
7181    }
7182
7183    @Override
7184    public int getUidForIntentSender(IIntentSender sender) {
7185        if (sender instanceof PendingIntentRecord) {
7186            try {
7187                PendingIntentRecord res = (PendingIntentRecord)sender;
7188                return res.uid;
7189            } catch (ClassCastException e) {
7190            }
7191        }
7192        return -1;
7193    }
7194
7195    @Override
7196    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7197        if (!(pendingResult instanceof PendingIntentRecord)) {
7198            return false;
7199        }
7200        try {
7201            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7202            if (res.key.allIntents == null) {
7203                return false;
7204            }
7205            for (int i=0; i<res.key.allIntents.length; i++) {
7206                Intent intent = res.key.allIntents[i];
7207                if (intent.getPackage() != null && intent.getComponent() != null) {
7208                    return false;
7209                }
7210            }
7211            return true;
7212        } catch (ClassCastException e) {
7213        }
7214        return false;
7215    }
7216
7217    @Override
7218    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7219        if (!(pendingResult instanceof PendingIntentRecord)) {
7220            return false;
7221        }
7222        try {
7223            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7224            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7225                return true;
7226            }
7227            return false;
7228        } catch (ClassCastException e) {
7229        }
7230        return false;
7231    }
7232
7233    @Override
7234    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7235        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7236                "getIntentForIntentSender()");
7237        if (!(pendingResult instanceof PendingIntentRecord)) {
7238            return null;
7239        }
7240        try {
7241            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7242            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7243        } catch (ClassCastException e) {
7244        }
7245        return null;
7246    }
7247
7248    @Override
7249    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7250        if (!(pendingResult instanceof PendingIntentRecord)) {
7251            return null;
7252        }
7253        try {
7254            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7255            synchronized (this) {
7256                return getTagForIntentSenderLocked(res, prefix);
7257            }
7258        } catch (ClassCastException e) {
7259        }
7260        return null;
7261    }
7262
7263    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7264        final Intent intent = res.key.requestIntent;
7265        if (intent != null) {
7266            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7267                    || res.lastTagPrefix.equals(prefix))) {
7268                return res.lastTag;
7269            }
7270            res.lastTagPrefix = prefix;
7271            final StringBuilder sb = new StringBuilder(128);
7272            if (prefix != null) {
7273                sb.append(prefix);
7274            }
7275            if (intent.getAction() != null) {
7276                sb.append(intent.getAction());
7277            } else if (intent.getComponent() != null) {
7278                intent.getComponent().appendShortString(sb);
7279            } else {
7280                sb.append("?");
7281            }
7282            return res.lastTag = sb.toString();
7283        }
7284        return null;
7285    }
7286
7287    @Override
7288    public void setProcessLimit(int max) {
7289        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7290                "setProcessLimit()");
7291        synchronized (this) {
7292            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7293            mProcessLimitOverride = max;
7294        }
7295        trimApplications();
7296    }
7297
7298    @Override
7299    public int getProcessLimit() {
7300        synchronized (this) {
7301            return mProcessLimitOverride;
7302        }
7303    }
7304
7305    void foregroundTokenDied(ForegroundToken token) {
7306        synchronized (ActivityManagerService.this) {
7307            synchronized (mPidsSelfLocked) {
7308                ForegroundToken cur
7309                    = mForegroundProcesses.get(token.pid);
7310                if (cur != token) {
7311                    return;
7312                }
7313                mForegroundProcesses.remove(token.pid);
7314                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7315                if (pr == null) {
7316                    return;
7317                }
7318                pr.forcingToForeground = null;
7319                updateProcessForegroundLocked(pr, false, false);
7320            }
7321            updateOomAdjLocked();
7322        }
7323    }
7324
7325    @Override
7326    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7327        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7328                "setProcessForeground()");
7329        synchronized(this) {
7330            boolean changed = false;
7331
7332            synchronized (mPidsSelfLocked) {
7333                ProcessRecord pr = mPidsSelfLocked.get(pid);
7334                if (pr == null && isForeground) {
7335                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7336                    return;
7337                }
7338                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7339                if (oldToken != null) {
7340                    oldToken.token.unlinkToDeath(oldToken, 0);
7341                    mForegroundProcesses.remove(pid);
7342                    if (pr != null) {
7343                        pr.forcingToForeground = null;
7344                    }
7345                    changed = true;
7346                }
7347                if (isForeground && token != null) {
7348                    ForegroundToken newToken = new ForegroundToken() {
7349                        @Override
7350                        public void binderDied() {
7351                            foregroundTokenDied(this);
7352                        }
7353                    };
7354                    newToken.pid = pid;
7355                    newToken.token = token;
7356                    try {
7357                        token.linkToDeath(newToken, 0);
7358                        mForegroundProcesses.put(pid, newToken);
7359                        pr.forcingToForeground = token;
7360                        changed = true;
7361                    } catch (RemoteException e) {
7362                        // If the process died while doing this, we will later
7363                        // do the cleanup with the process death link.
7364                    }
7365                }
7366            }
7367
7368            if (changed) {
7369                updateOomAdjLocked();
7370            }
7371        }
7372    }
7373
7374    @Override
7375    public boolean isAppForeground(int uid) throws RemoteException {
7376        synchronized (this) {
7377            UidRecord uidRec = mActiveUids.get(uid);
7378            if (uidRec == null || uidRec.idle) {
7379                return false;
7380            }
7381            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7382        }
7383    }
7384
7385    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7386    // be guarded by permission checking.
7387    int getUidState(int uid) {
7388        synchronized (this) {
7389            UidRecord uidRec = mActiveUids.get(uid);
7390            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7391        }
7392    }
7393
7394    @Override
7395    public boolean isInMultiWindowMode(IBinder token) {
7396        final long origId = Binder.clearCallingIdentity();
7397        try {
7398            synchronized(this) {
7399                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7400                if (r == null) {
7401                    return false;
7402                }
7403                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7404                return !r.task.mFullscreen;
7405            }
7406        } finally {
7407            Binder.restoreCallingIdentity(origId);
7408        }
7409    }
7410
7411    @Override
7412    public boolean isInPictureInPictureMode(IBinder token) {
7413        final long origId = Binder.clearCallingIdentity();
7414        try {
7415            synchronized(this) {
7416                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7417                if (stack == null) {
7418                    return false;
7419                }
7420                return stack.mStackId == PINNED_STACK_ID;
7421            }
7422        } finally {
7423            Binder.restoreCallingIdentity(origId);
7424        }
7425    }
7426
7427    @Override
7428    public void enterPictureInPictureMode(IBinder token) {
7429        final long origId = Binder.clearCallingIdentity();
7430        try {
7431            synchronized(this) {
7432                if (!mSupportsPictureInPicture) {
7433                    throw new IllegalStateException("enterPictureInPictureMode: "
7434                            + "Device doesn't support picture-in-picture mode.");
7435                }
7436
7437                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7438
7439                if (r == null) {
7440                    throw new IllegalStateException("enterPictureInPictureMode: "
7441                            + "Can't find activity for token=" + token);
7442                }
7443
7444                if (!r.supportsPictureInPicture()) {
7445                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7446                            + "Picture-In-Picture not supported for r=" + r);
7447                }
7448
7449                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7450                // current bounds.
7451                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7452                final Rect bounds = (pinnedStack != null)
7453                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7454
7455                mStackSupervisor.moveActivityToPinnedStackLocked(
7456                        r, "enterPictureInPictureMode", bounds);
7457            }
7458        } finally {
7459            Binder.restoreCallingIdentity(origId);
7460        }
7461    }
7462
7463    // =========================================================
7464    // PROCESS INFO
7465    // =========================================================
7466
7467    static class ProcessInfoService extends IProcessInfoService.Stub {
7468        final ActivityManagerService mActivityManagerService;
7469        ProcessInfoService(ActivityManagerService activityManagerService) {
7470            mActivityManagerService = activityManagerService;
7471        }
7472
7473        @Override
7474        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7475            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7476                    /*in*/ pids, /*out*/ states, null);
7477        }
7478
7479        @Override
7480        public void getProcessStatesAndOomScoresFromPids(
7481                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7482            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7483                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7484        }
7485    }
7486
7487    /**
7488     * For each PID in the given input array, write the current process state
7489     * for that process into the states array, or -1 to indicate that no
7490     * process with the given PID exists. If scores array is provided, write
7491     * the oom score for the process into the scores array, with INVALID_ADJ
7492     * indicating the PID doesn't exist.
7493     */
7494    public void getProcessStatesAndOomScoresForPIDs(
7495            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7496        if (scores != null) {
7497            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7498                    "getProcessStatesAndOomScoresForPIDs()");
7499        }
7500
7501        if (pids == null) {
7502            throw new NullPointerException("pids");
7503        } else if (states == null) {
7504            throw new NullPointerException("states");
7505        } else if (pids.length != states.length) {
7506            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7507        } else if (scores != null && pids.length != scores.length) {
7508            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7509        }
7510
7511        synchronized (mPidsSelfLocked) {
7512            for (int i = 0; i < pids.length; i++) {
7513                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7514                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7515                        pr.curProcState;
7516                if (scores != null) {
7517                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7518                }
7519            }
7520        }
7521    }
7522
7523    // =========================================================
7524    // PERMISSIONS
7525    // =========================================================
7526
7527    static class PermissionController extends IPermissionController.Stub {
7528        ActivityManagerService mActivityManagerService;
7529        PermissionController(ActivityManagerService activityManagerService) {
7530            mActivityManagerService = activityManagerService;
7531        }
7532
7533        @Override
7534        public boolean checkPermission(String permission, int pid, int uid) {
7535            return mActivityManagerService.checkPermission(permission, pid,
7536                    uid) == PackageManager.PERMISSION_GRANTED;
7537        }
7538
7539        @Override
7540        public String[] getPackagesForUid(int uid) {
7541            return mActivityManagerService.mContext.getPackageManager()
7542                    .getPackagesForUid(uid);
7543        }
7544
7545        @Override
7546        public boolean isRuntimePermission(String permission) {
7547            try {
7548                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7549                        .getPermissionInfo(permission, 0);
7550                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7551            } catch (NameNotFoundException nnfe) {
7552                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7553            }
7554            return false;
7555        }
7556    }
7557
7558    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7559        @Override
7560        public int checkComponentPermission(String permission, int pid, int uid,
7561                int owningUid, boolean exported) {
7562            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7563                    owningUid, exported);
7564        }
7565
7566        @Override
7567        public Object getAMSLock() {
7568            return ActivityManagerService.this;
7569        }
7570    }
7571
7572    /**
7573     * This can be called with or without the global lock held.
7574     */
7575    int checkComponentPermission(String permission, int pid, int uid,
7576            int owningUid, boolean exported) {
7577        if (pid == MY_PID) {
7578            return PackageManager.PERMISSION_GRANTED;
7579        }
7580        return ActivityManager.checkComponentPermission(permission, uid,
7581                owningUid, exported);
7582    }
7583
7584    /**
7585     * As the only public entry point for permissions checking, this method
7586     * can enforce the semantic that requesting a check on a null global
7587     * permission is automatically denied.  (Internally a null permission
7588     * string is used when calling {@link #checkComponentPermission} in cases
7589     * when only uid-based security is needed.)
7590     *
7591     * This can be called with or without the global lock held.
7592     */
7593    @Override
7594    public int checkPermission(String permission, int pid, int uid) {
7595        if (permission == null) {
7596            return PackageManager.PERMISSION_DENIED;
7597        }
7598        return checkComponentPermission(permission, pid, uid, -1, true);
7599    }
7600
7601    @Override
7602    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7603        if (permission == null) {
7604            return PackageManager.PERMISSION_DENIED;
7605        }
7606
7607        // We might be performing an operation on behalf of an indirect binder
7608        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7609        // client identity accordingly before proceeding.
7610        Identity tlsIdentity = sCallerIdentity.get();
7611        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7612            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7613                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7614            uid = tlsIdentity.uid;
7615            pid = tlsIdentity.pid;
7616        }
7617
7618        return checkComponentPermission(permission, pid, uid, -1, true);
7619    }
7620
7621    /**
7622     * Binder IPC calls go through the public entry point.
7623     * This can be called with or without the global lock held.
7624     */
7625    int checkCallingPermission(String permission) {
7626        return checkPermission(permission,
7627                Binder.getCallingPid(),
7628                UserHandle.getAppId(Binder.getCallingUid()));
7629    }
7630
7631    /**
7632     * This can be called with or without the global lock held.
7633     */
7634    void enforceCallingPermission(String permission, String func) {
7635        if (checkCallingPermission(permission)
7636                == PackageManager.PERMISSION_GRANTED) {
7637            return;
7638        }
7639
7640        String msg = "Permission Denial: " + func + " from pid="
7641                + Binder.getCallingPid()
7642                + ", uid=" + Binder.getCallingUid()
7643                + " requires " + permission;
7644        Slog.w(TAG, msg);
7645        throw new SecurityException(msg);
7646    }
7647
7648    /**
7649     * Determine if UID is holding permissions required to access {@link Uri} in
7650     * the given {@link ProviderInfo}. Final permission checking is always done
7651     * in {@link ContentProvider}.
7652     */
7653    private final boolean checkHoldingPermissionsLocked(
7654            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7655        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7656                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7657        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7658            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7659                    != PERMISSION_GRANTED) {
7660                return false;
7661            }
7662        }
7663        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7664    }
7665
7666    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7667            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7668        if (pi.applicationInfo.uid == uid) {
7669            return true;
7670        } else if (!pi.exported) {
7671            return false;
7672        }
7673
7674        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7675        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7676        try {
7677            // check if target holds top-level <provider> permissions
7678            if (!readMet && pi.readPermission != null && considerUidPermissions
7679                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7680                readMet = true;
7681            }
7682            if (!writeMet && pi.writePermission != null && considerUidPermissions
7683                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7684                writeMet = true;
7685            }
7686
7687            // track if unprotected read/write is allowed; any denied
7688            // <path-permission> below removes this ability
7689            boolean allowDefaultRead = pi.readPermission == null;
7690            boolean allowDefaultWrite = pi.writePermission == null;
7691
7692            // check if target holds any <path-permission> that match uri
7693            final PathPermission[] pps = pi.pathPermissions;
7694            if (pps != null) {
7695                final String path = grantUri.uri.getPath();
7696                int i = pps.length;
7697                while (i > 0 && (!readMet || !writeMet)) {
7698                    i--;
7699                    PathPermission pp = pps[i];
7700                    if (pp.match(path)) {
7701                        if (!readMet) {
7702                            final String pprperm = pp.getReadPermission();
7703                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7704                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7705                                    + ": match=" + pp.match(path)
7706                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7707                            if (pprperm != null) {
7708                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7709                                        == PERMISSION_GRANTED) {
7710                                    readMet = true;
7711                                } else {
7712                                    allowDefaultRead = false;
7713                                }
7714                            }
7715                        }
7716                        if (!writeMet) {
7717                            final String ppwperm = pp.getWritePermission();
7718                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7719                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7720                                    + ": match=" + pp.match(path)
7721                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7722                            if (ppwperm != null) {
7723                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7724                                        == PERMISSION_GRANTED) {
7725                                    writeMet = true;
7726                                } else {
7727                                    allowDefaultWrite = false;
7728                                }
7729                            }
7730                        }
7731                    }
7732                }
7733            }
7734
7735            // grant unprotected <provider> read/write, if not blocked by
7736            // <path-permission> above
7737            if (allowDefaultRead) readMet = true;
7738            if (allowDefaultWrite) writeMet = true;
7739
7740        } catch (RemoteException e) {
7741            return false;
7742        }
7743
7744        return readMet && writeMet;
7745    }
7746
7747    public int getAppStartMode(int uid, String packageName) {
7748        synchronized (this) {
7749            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7750        }
7751    }
7752
7753    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7754            boolean allowWhenForeground) {
7755        UidRecord uidRec = mActiveUids.get(uid);
7756        if (!mLenientBackgroundCheck) {
7757            if (!allowWhenForeground || uidRec == null
7758                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7759                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7760                        packageName) != AppOpsManager.MODE_ALLOWED) {
7761                    return ActivityManager.APP_START_MODE_DELAYED;
7762                }
7763            }
7764
7765        } else if (uidRec == null || uidRec.idle) {
7766            if (callingPid >= 0) {
7767                ProcessRecord proc;
7768                synchronized (mPidsSelfLocked) {
7769                    proc = mPidsSelfLocked.get(callingPid);
7770                }
7771                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7772                    // Whoever is instigating this is in the foreground, so we will allow it
7773                    // to go through.
7774                    return ActivityManager.APP_START_MODE_NORMAL;
7775                }
7776            }
7777            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7778                    != AppOpsManager.MODE_ALLOWED) {
7779                return ActivityManager.APP_START_MODE_DELAYED;
7780            }
7781        }
7782        return ActivityManager.APP_START_MODE_NORMAL;
7783    }
7784
7785    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7786        ProviderInfo pi = null;
7787        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7788        if (cpr != null) {
7789            pi = cpr.info;
7790        } else {
7791            try {
7792                pi = AppGlobals.getPackageManager().resolveContentProvider(
7793                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7794            } catch (RemoteException ex) {
7795            }
7796        }
7797        return pi;
7798    }
7799
7800    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7801        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7802        if (targetUris != null) {
7803            return targetUris.get(grantUri);
7804        }
7805        return null;
7806    }
7807
7808    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7809            String targetPkg, int targetUid, GrantUri grantUri) {
7810        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7811        if (targetUris == null) {
7812            targetUris = Maps.newArrayMap();
7813            mGrantedUriPermissions.put(targetUid, targetUris);
7814        }
7815
7816        UriPermission perm = targetUris.get(grantUri);
7817        if (perm == null) {
7818            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7819            targetUris.put(grantUri, perm);
7820        }
7821
7822        return perm;
7823    }
7824
7825    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7826            final int modeFlags) {
7827        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7828        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7829                : UriPermission.STRENGTH_OWNED;
7830
7831        // Root gets to do everything.
7832        if (uid == 0) {
7833            return true;
7834        }
7835
7836        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7837        if (perms == null) return false;
7838
7839        // First look for exact match
7840        final UriPermission exactPerm = perms.get(grantUri);
7841        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7842            return true;
7843        }
7844
7845        // No exact match, look for prefixes
7846        final int N = perms.size();
7847        for (int i = 0; i < N; i++) {
7848            final UriPermission perm = perms.valueAt(i);
7849            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7850                    && perm.getStrength(modeFlags) >= minStrength) {
7851                return true;
7852            }
7853        }
7854
7855        return false;
7856    }
7857
7858    /**
7859     * @param uri This uri must NOT contain an embedded userId.
7860     * @param userId The userId in which the uri is to be resolved.
7861     */
7862    @Override
7863    public int checkUriPermission(Uri uri, int pid, int uid,
7864            final int modeFlags, int userId, IBinder callerToken) {
7865        enforceNotIsolatedCaller("checkUriPermission");
7866
7867        // Another redirected-binder-call permissions check as in
7868        // {@link checkPermissionWithToken}.
7869        Identity tlsIdentity = sCallerIdentity.get();
7870        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7871            uid = tlsIdentity.uid;
7872            pid = tlsIdentity.pid;
7873        }
7874
7875        // Our own process gets to do everything.
7876        if (pid == MY_PID) {
7877            return PackageManager.PERMISSION_GRANTED;
7878        }
7879        synchronized (this) {
7880            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7881                    ? PackageManager.PERMISSION_GRANTED
7882                    : PackageManager.PERMISSION_DENIED;
7883        }
7884    }
7885
7886    /**
7887     * Check if the targetPkg can be granted permission to access uri by
7888     * the callingUid using the given modeFlags.  Throws a security exception
7889     * if callingUid is not allowed to do this.  Returns the uid of the target
7890     * if the URI permission grant should be performed; returns -1 if it is not
7891     * needed (for example targetPkg already has permission to access the URI).
7892     * If you already know the uid of the target, you can supply it in
7893     * lastTargetUid else set that to -1.
7894     */
7895    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7896            final int modeFlags, int lastTargetUid) {
7897        if (!Intent.isAccessUriMode(modeFlags)) {
7898            return -1;
7899        }
7900
7901        if (targetPkg != null) {
7902            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7903                    "Checking grant " + targetPkg + " permission to " + grantUri);
7904        }
7905
7906        final IPackageManager pm = AppGlobals.getPackageManager();
7907
7908        // If this is not a content: uri, we can't do anything with it.
7909        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7910            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7911                    "Can't grant URI permission for non-content URI: " + grantUri);
7912            return -1;
7913        }
7914
7915        final String authority = grantUri.uri.getAuthority();
7916        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7917        if (pi == null) {
7918            Slog.w(TAG, "No content provider found for permission check: " +
7919                    grantUri.uri.toSafeString());
7920            return -1;
7921        }
7922
7923        int targetUid = lastTargetUid;
7924        if (targetUid < 0 && targetPkg != null) {
7925            try {
7926                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7927                        UserHandle.getUserId(callingUid));
7928                if (targetUid < 0) {
7929                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7930                            "Can't grant URI permission no uid for: " + targetPkg);
7931                    return -1;
7932                }
7933            } catch (RemoteException ex) {
7934                return -1;
7935            }
7936        }
7937
7938        if (targetUid >= 0) {
7939            // First...  does the target actually need this permission?
7940            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7941                // No need to grant the target this permission.
7942                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7943                        "Target " + targetPkg + " already has full permission to " + grantUri);
7944                return -1;
7945            }
7946        } else {
7947            // First...  there is no target package, so can anyone access it?
7948            boolean allowed = pi.exported;
7949            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7950                if (pi.readPermission != null) {
7951                    allowed = false;
7952                }
7953            }
7954            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7955                if (pi.writePermission != null) {
7956                    allowed = false;
7957                }
7958            }
7959            if (allowed) {
7960                return -1;
7961            }
7962        }
7963
7964        /* There is a special cross user grant if:
7965         * - The target is on another user.
7966         * - Apps on the current user can access the uri without any uid permissions.
7967         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7968         * grant uri permissions.
7969         */
7970        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7971                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7972                modeFlags, false /*without considering the uid permissions*/);
7973
7974        // Second...  is the provider allowing granting of URI permissions?
7975        if (!specialCrossUserGrant) {
7976            if (!pi.grantUriPermissions) {
7977                throw new SecurityException("Provider " + pi.packageName
7978                        + "/" + pi.name
7979                        + " does not allow granting of Uri permissions (uri "
7980                        + grantUri + ")");
7981            }
7982            if (pi.uriPermissionPatterns != null) {
7983                final int N = pi.uriPermissionPatterns.length;
7984                boolean allowed = false;
7985                for (int i=0; i<N; i++) {
7986                    if (pi.uriPermissionPatterns[i] != null
7987                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7988                        allowed = true;
7989                        break;
7990                    }
7991                }
7992                if (!allowed) {
7993                    throw new SecurityException("Provider " + pi.packageName
7994                            + "/" + pi.name
7995                            + " does not allow granting of permission to path of Uri "
7996                            + grantUri);
7997                }
7998            }
7999        }
8000
8001        // Third...  does the caller itself have permission to access
8002        // this uri?
8003        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8004            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8005                // Require they hold a strong enough Uri permission
8006                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8007                    throw new SecurityException("Uid " + callingUid
8008                            + " does not have permission to uri " + grantUri);
8009                }
8010            }
8011        }
8012        return targetUid;
8013    }
8014
8015    /**
8016     * @param uri This uri must NOT contain an embedded userId.
8017     * @param userId The userId in which the uri is to be resolved.
8018     */
8019    @Override
8020    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8021            final int modeFlags, int userId) {
8022        enforceNotIsolatedCaller("checkGrantUriPermission");
8023        synchronized(this) {
8024            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8025                    new GrantUri(userId, uri, false), modeFlags, -1);
8026        }
8027    }
8028
8029    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8030            final int modeFlags, UriPermissionOwner owner) {
8031        if (!Intent.isAccessUriMode(modeFlags)) {
8032            return;
8033        }
8034
8035        // So here we are: the caller has the assumed permission
8036        // to the uri, and the target doesn't.  Let's now give this to
8037        // the target.
8038
8039        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8040                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8041
8042        final String authority = grantUri.uri.getAuthority();
8043        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8044        if (pi == null) {
8045            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8046            return;
8047        }
8048
8049        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8050            grantUri.prefix = true;
8051        }
8052        final UriPermission perm = findOrCreateUriPermissionLocked(
8053                pi.packageName, targetPkg, targetUid, grantUri);
8054        perm.grantModes(modeFlags, owner);
8055    }
8056
8057    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8058            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8059        if (targetPkg == null) {
8060            throw new NullPointerException("targetPkg");
8061        }
8062        int targetUid;
8063        final IPackageManager pm = AppGlobals.getPackageManager();
8064        try {
8065            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8066        } catch (RemoteException ex) {
8067            return;
8068        }
8069
8070        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8071                targetUid);
8072        if (targetUid < 0) {
8073            return;
8074        }
8075
8076        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8077                owner);
8078    }
8079
8080    static class NeededUriGrants extends ArrayList<GrantUri> {
8081        final String targetPkg;
8082        final int targetUid;
8083        final int flags;
8084
8085        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8086            this.targetPkg = targetPkg;
8087            this.targetUid = targetUid;
8088            this.flags = flags;
8089        }
8090    }
8091
8092    /**
8093     * Like checkGrantUriPermissionLocked, but takes an Intent.
8094     */
8095    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8096            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8097        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8098                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8099                + " clip=" + (intent != null ? intent.getClipData() : null)
8100                + " from " + intent + "; flags=0x"
8101                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8102
8103        if (targetPkg == null) {
8104            throw new NullPointerException("targetPkg");
8105        }
8106
8107        if (intent == null) {
8108            return null;
8109        }
8110        Uri data = intent.getData();
8111        ClipData clip = intent.getClipData();
8112        if (data == null && clip == null) {
8113            return null;
8114        }
8115        // Default userId for uris in the intent (if they don't specify it themselves)
8116        int contentUserHint = intent.getContentUserHint();
8117        if (contentUserHint == UserHandle.USER_CURRENT) {
8118            contentUserHint = UserHandle.getUserId(callingUid);
8119        }
8120        final IPackageManager pm = AppGlobals.getPackageManager();
8121        int targetUid;
8122        if (needed != null) {
8123            targetUid = needed.targetUid;
8124        } else {
8125            try {
8126                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8127                        targetUserId);
8128            } catch (RemoteException ex) {
8129                return null;
8130            }
8131            if (targetUid < 0) {
8132                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8133                        "Can't grant URI permission no uid for: " + targetPkg
8134                        + " on user " + targetUserId);
8135                return null;
8136            }
8137        }
8138        if (data != null) {
8139            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8140            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8141                    targetUid);
8142            if (targetUid > 0) {
8143                if (needed == null) {
8144                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8145                }
8146                needed.add(grantUri);
8147            }
8148        }
8149        if (clip != null) {
8150            for (int i=0; i<clip.getItemCount(); i++) {
8151                Uri uri = clip.getItemAt(i).getUri();
8152                if (uri != null) {
8153                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8154                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8155                            targetUid);
8156                    if (targetUid > 0) {
8157                        if (needed == null) {
8158                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8159                        }
8160                        needed.add(grantUri);
8161                    }
8162                } else {
8163                    Intent clipIntent = clip.getItemAt(i).getIntent();
8164                    if (clipIntent != null) {
8165                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8166                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8167                        if (newNeeded != null) {
8168                            needed = newNeeded;
8169                        }
8170                    }
8171                }
8172            }
8173        }
8174
8175        return needed;
8176    }
8177
8178    /**
8179     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8180     */
8181    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8182            UriPermissionOwner owner) {
8183        if (needed != null) {
8184            for (int i=0; i<needed.size(); i++) {
8185                GrantUri grantUri = needed.get(i);
8186                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8187                        grantUri, needed.flags, owner);
8188            }
8189        }
8190    }
8191
8192    void grantUriPermissionFromIntentLocked(int callingUid,
8193            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8194        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8195                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8196        if (needed == null) {
8197            return;
8198        }
8199
8200        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8201    }
8202
8203    /**
8204     * @param uri This uri must NOT contain an embedded userId.
8205     * @param userId The userId in which the uri is to be resolved.
8206     */
8207    @Override
8208    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8209            final int modeFlags, int userId) {
8210        enforceNotIsolatedCaller("grantUriPermission");
8211        GrantUri grantUri = new GrantUri(userId, uri, false);
8212        synchronized(this) {
8213            final ProcessRecord r = getRecordForAppLocked(caller);
8214            if (r == null) {
8215                throw new SecurityException("Unable to find app for caller "
8216                        + caller
8217                        + " when granting permission to uri " + grantUri);
8218            }
8219            if (targetPkg == null) {
8220                throw new IllegalArgumentException("null target");
8221            }
8222            if (grantUri == null) {
8223                throw new IllegalArgumentException("null uri");
8224            }
8225
8226            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8227                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8228                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8229                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8230
8231            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8232                    UserHandle.getUserId(r.uid));
8233        }
8234    }
8235
8236    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8237        if (perm.modeFlags == 0) {
8238            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8239                    perm.targetUid);
8240            if (perms != null) {
8241                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8242                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8243
8244                perms.remove(perm.uri);
8245                if (perms.isEmpty()) {
8246                    mGrantedUriPermissions.remove(perm.targetUid);
8247                }
8248            }
8249        }
8250    }
8251
8252    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8253        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8254                "Revoking all granted permissions to " + grantUri);
8255
8256        final IPackageManager pm = AppGlobals.getPackageManager();
8257        final String authority = grantUri.uri.getAuthority();
8258        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8259        if (pi == null) {
8260            Slog.w(TAG, "No content provider found for permission revoke: "
8261                    + grantUri.toSafeString());
8262            return;
8263        }
8264
8265        // Does the caller have this permission on the URI?
8266        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8267            // If they don't have direct access to the URI, then revoke any
8268            // ownerless URI permissions that have been granted to them.
8269            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8270            if (perms != null) {
8271                boolean persistChanged = false;
8272                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8273                    final UriPermission perm = it.next();
8274                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8275                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8276                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8277                                "Revoking non-owned " + perm.targetUid
8278                                + " permission to " + perm.uri);
8279                        persistChanged |= perm.revokeModes(
8280                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8281                        if (perm.modeFlags == 0) {
8282                            it.remove();
8283                        }
8284                    }
8285                }
8286                if (perms.isEmpty()) {
8287                    mGrantedUriPermissions.remove(callingUid);
8288                }
8289                if (persistChanged) {
8290                    schedulePersistUriGrants();
8291                }
8292            }
8293            return;
8294        }
8295
8296        boolean persistChanged = false;
8297
8298        // Go through all of the permissions and remove any that match.
8299        int N = mGrantedUriPermissions.size();
8300        for (int i = 0; i < N; i++) {
8301            final int targetUid = mGrantedUriPermissions.keyAt(i);
8302            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8303
8304            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8305                final UriPermission perm = it.next();
8306                if (perm.uri.sourceUserId == grantUri.sourceUserId
8307                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8308                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8309                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8310                    persistChanged |= perm.revokeModes(
8311                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8312                    if (perm.modeFlags == 0) {
8313                        it.remove();
8314                    }
8315                }
8316            }
8317
8318            if (perms.isEmpty()) {
8319                mGrantedUriPermissions.remove(targetUid);
8320                N--;
8321                i--;
8322            }
8323        }
8324
8325        if (persistChanged) {
8326            schedulePersistUriGrants();
8327        }
8328    }
8329
8330    /**
8331     * @param uri This uri must NOT contain an embedded userId.
8332     * @param userId The userId in which the uri is to be resolved.
8333     */
8334    @Override
8335    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8336            int userId) {
8337        enforceNotIsolatedCaller("revokeUriPermission");
8338        synchronized(this) {
8339            final ProcessRecord r = getRecordForAppLocked(caller);
8340            if (r == null) {
8341                throw new SecurityException("Unable to find app for caller "
8342                        + caller
8343                        + " when revoking permission to uri " + uri);
8344            }
8345            if (uri == null) {
8346                Slog.w(TAG, "revokeUriPermission: null uri");
8347                return;
8348            }
8349
8350            if (!Intent.isAccessUriMode(modeFlags)) {
8351                return;
8352            }
8353
8354            final String authority = uri.getAuthority();
8355            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8356            if (pi == null) {
8357                Slog.w(TAG, "No content provider found for permission revoke: "
8358                        + uri.toSafeString());
8359                return;
8360            }
8361
8362            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8363        }
8364    }
8365
8366    /**
8367     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8368     * given package.
8369     *
8370     * @param packageName Package name to match, or {@code null} to apply to all
8371     *            packages.
8372     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8373     *            to all users.
8374     * @param persistable If persistable grants should be removed.
8375     */
8376    private void removeUriPermissionsForPackageLocked(
8377            String packageName, int userHandle, boolean persistable) {
8378        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8379            throw new IllegalArgumentException("Must narrow by either package or user");
8380        }
8381
8382        boolean persistChanged = false;
8383
8384        int N = mGrantedUriPermissions.size();
8385        for (int i = 0; i < N; i++) {
8386            final int targetUid = mGrantedUriPermissions.keyAt(i);
8387            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8388
8389            // Only inspect grants matching user
8390            if (userHandle == UserHandle.USER_ALL
8391                    || userHandle == UserHandle.getUserId(targetUid)) {
8392                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8393                    final UriPermission perm = it.next();
8394
8395                    // Only inspect grants matching package
8396                    if (packageName == null || perm.sourcePkg.equals(packageName)
8397                            || perm.targetPkg.equals(packageName)) {
8398                        persistChanged |= perm.revokeModes(persistable
8399                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8400
8401                        // Only remove when no modes remain; any persisted grants
8402                        // will keep this alive.
8403                        if (perm.modeFlags == 0) {
8404                            it.remove();
8405                        }
8406                    }
8407                }
8408
8409                if (perms.isEmpty()) {
8410                    mGrantedUriPermissions.remove(targetUid);
8411                    N--;
8412                    i--;
8413                }
8414            }
8415        }
8416
8417        if (persistChanged) {
8418            schedulePersistUriGrants();
8419        }
8420    }
8421
8422    @Override
8423    public IBinder newUriPermissionOwner(String name) {
8424        enforceNotIsolatedCaller("newUriPermissionOwner");
8425        synchronized(this) {
8426            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8427            return owner.getExternalTokenLocked();
8428        }
8429    }
8430
8431    @Override
8432    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8433        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8434        synchronized(this) {
8435            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8436            if (r == null) {
8437                throw new IllegalArgumentException("Activity does not exist; token="
8438                        + activityToken);
8439            }
8440            return r.getUriPermissionsLocked().getExternalTokenLocked();
8441        }
8442    }
8443    /**
8444     * @param uri This uri must NOT contain an embedded userId.
8445     * @param sourceUserId The userId in which the uri is to be resolved.
8446     * @param targetUserId The userId of the app that receives the grant.
8447     */
8448    @Override
8449    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8450            final int modeFlags, int sourceUserId, int targetUserId) {
8451        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8452                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8453                "grantUriPermissionFromOwner", null);
8454        synchronized(this) {
8455            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8456            if (owner == null) {
8457                throw new IllegalArgumentException("Unknown owner: " + token);
8458            }
8459            if (fromUid != Binder.getCallingUid()) {
8460                if (Binder.getCallingUid() != Process.myUid()) {
8461                    // Only system code can grant URI permissions on behalf
8462                    // of other users.
8463                    throw new SecurityException("nice try");
8464                }
8465            }
8466            if (targetPkg == null) {
8467                throw new IllegalArgumentException("null target");
8468            }
8469            if (uri == null) {
8470                throw new IllegalArgumentException("null uri");
8471            }
8472
8473            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8474                    modeFlags, owner, targetUserId);
8475        }
8476    }
8477
8478    /**
8479     * @param uri This uri must NOT contain an embedded userId.
8480     * @param userId The userId in which the uri is to be resolved.
8481     */
8482    @Override
8483    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8484        synchronized(this) {
8485            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8486            if (owner == null) {
8487                throw new IllegalArgumentException("Unknown owner: " + token);
8488            }
8489
8490            if (uri == null) {
8491                owner.removeUriPermissionsLocked(mode);
8492            } else {
8493                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8494            }
8495        }
8496    }
8497
8498    private void schedulePersistUriGrants() {
8499        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8500            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8501                    10 * DateUtils.SECOND_IN_MILLIS);
8502        }
8503    }
8504
8505    private void writeGrantedUriPermissions() {
8506        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8507
8508        // Snapshot permissions so we can persist without lock
8509        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8510        synchronized (this) {
8511            final int size = mGrantedUriPermissions.size();
8512            for (int i = 0; i < size; i++) {
8513                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8514                for (UriPermission perm : perms.values()) {
8515                    if (perm.persistedModeFlags != 0) {
8516                        persist.add(perm.snapshot());
8517                    }
8518                }
8519            }
8520        }
8521
8522        FileOutputStream fos = null;
8523        try {
8524            fos = mGrantFile.startWrite();
8525
8526            XmlSerializer out = new FastXmlSerializer();
8527            out.setOutput(fos, StandardCharsets.UTF_8.name());
8528            out.startDocument(null, true);
8529            out.startTag(null, TAG_URI_GRANTS);
8530            for (UriPermission.Snapshot perm : persist) {
8531                out.startTag(null, TAG_URI_GRANT);
8532                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8533                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8534                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8535                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8536                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8537                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8538                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8539                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8540                out.endTag(null, TAG_URI_GRANT);
8541            }
8542            out.endTag(null, TAG_URI_GRANTS);
8543            out.endDocument();
8544
8545            mGrantFile.finishWrite(fos);
8546        } catch (IOException e) {
8547            if (fos != null) {
8548                mGrantFile.failWrite(fos);
8549            }
8550        }
8551    }
8552
8553    private void readGrantedUriPermissionsLocked() {
8554        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8555
8556        final long now = System.currentTimeMillis();
8557
8558        FileInputStream fis = null;
8559        try {
8560            fis = mGrantFile.openRead();
8561            final XmlPullParser in = Xml.newPullParser();
8562            in.setInput(fis, StandardCharsets.UTF_8.name());
8563
8564            int type;
8565            while ((type = in.next()) != END_DOCUMENT) {
8566                final String tag = in.getName();
8567                if (type == START_TAG) {
8568                    if (TAG_URI_GRANT.equals(tag)) {
8569                        final int sourceUserId;
8570                        final int targetUserId;
8571                        final int userHandle = readIntAttribute(in,
8572                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8573                        if (userHandle != UserHandle.USER_NULL) {
8574                            // For backwards compatibility.
8575                            sourceUserId = userHandle;
8576                            targetUserId = userHandle;
8577                        } else {
8578                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8579                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8580                        }
8581                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8582                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8583                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8584                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8585                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8586                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8587
8588                        // Sanity check that provider still belongs to source package
8589                        final ProviderInfo pi = getProviderInfoLocked(
8590                                uri.getAuthority(), sourceUserId);
8591                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8592                            int targetUid = -1;
8593                            try {
8594                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8595                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8596                            } catch (RemoteException e) {
8597                            }
8598                            if (targetUid != -1) {
8599                                final UriPermission perm = findOrCreateUriPermissionLocked(
8600                                        sourcePkg, targetPkg, targetUid,
8601                                        new GrantUri(sourceUserId, uri, prefix));
8602                                perm.initPersistedModes(modeFlags, createdTime);
8603                            }
8604                        } else {
8605                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8606                                    + " but instead found " + pi);
8607                        }
8608                    }
8609                }
8610            }
8611        } catch (FileNotFoundException e) {
8612            // Missing grants is okay
8613        } catch (IOException e) {
8614            Slog.wtf(TAG, "Failed reading Uri grants", e);
8615        } catch (XmlPullParserException e) {
8616            Slog.wtf(TAG, "Failed reading Uri grants", e);
8617        } finally {
8618            IoUtils.closeQuietly(fis);
8619        }
8620    }
8621
8622    /**
8623     * @param uri This uri must NOT contain an embedded userId.
8624     * @param userId The userId in which the uri is to be resolved.
8625     */
8626    @Override
8627    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8628        enforceNotIsolatedCaller("takePersistableUriPermission");
8629
8630        Preconditions.checkFlagsArgument(modeFlags,
8631                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8632
8633        synchronized (this) {
8634            final int callingUid = Binder.getCallingUid();
8635            boolean persistChanged = false;
8636            GrantUri grantUri = new GrantUri(userId, uri, false);
8637
8638            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8639                    new GrantUri(userId, uri, false));
8640            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8641                    new GrantUri(userId, uri, true));
8642
8643            final boolean exactValid = (exactPerm != null)
8644                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8645            final boolean prefixValid = (prefixPerm != null)
8646                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8647
8648            if (!(exactValid || prefixValid)) {
8649                throw new SecurityException("No persistable permission grants found for UID "
8650                        + callingUid + " and Uri " + grantUri.toSafeString());
8651            }
8652
8653            if (exactValid) {
8654                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8655            }
8656            if (prefixValid) {
8657                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8658            }
8659
8660            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8661
8662            if (persistChanged) {
8663                schedulePersistUriGrants();
8664            }
8665        }
8666    }
8667
8668    /**
8669     * @param uri This uri must NOT contain an embedded userId.
8670     * @param userId The userId in which the uri is to be resolved.
8671     */
8672    @Override
8673    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8674        enforceNotIsolatedCaller("releasePersistableUriPermission");
8675
8676        Preconditions.checkFlagsArgument(modeFlags,
8677                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8678
8679        synchronized (this) {
8680            final int callingUid = Binder.getCallingUid();
8681            boolean persistChanged = false;
8682
8683            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8684                    new GrantUri(userId, uri, false));
8685            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8686                    new GrantUri(userId, uri, true));
8687            if (exactPerm == null && prefixPerm == null) {
8688                throw new SecurityException("No permission grants found for UID " + callingUid
8689                        + " and Uri " + uri.toSafeString());
8690            }
8691
8692            if (exactPerm != null) {
8693                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8694                removeUriPermissionIfNeededLocked(exactPerm);
8695            }
8696            if (prefixPerm != null) {
8697                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8698                removeUriPermissionIfNeededLocked(prefixPerm);
8699            }
8700
8701            if (persistChanged) {
8702                schedulePersistUriGrants();
8703            }
8704        }
8705    }
8706
8707    /**
8708     * Prune any older {@link UriPermission} for the given UID until outstanding
8709     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8710     *
8711     * @return if any mutations occured that require persisting.
8712     */
8713    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8714        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8715        if (perms == null) return false;
8716        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8717
8718        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8719        for (UriPermission perm : perms.values()) {
8720            if (perm.persistedModeFlags != 0) {
8721                persisted.add(perm);
8722            }
8723        }
8724
8725        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8726        if (trimCount <= 0) return false;
8727
8728        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8729        for (int i = 0; i < trimCount; i++) {
8730            final UriPermission perm = persisted.get(i);
8731
8732            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8733                    "Trimming grant created at " + perm.persistedCreateTime);
8734
8735            perm.releasePersistableModes(~0);
8736            removeUriPermissionIfNeededLocked(perm);
8737        }
8738
8739        return true;
8740    }
8741
8742    @Override
8743    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8744            String packageName, boolean incoming) {
8745        enforceNotIsolatedCaller("getPersistedUriPermissions");
8746        Preconditions.checkNotNull(packageName, "packageName");
8747
8748        final int callingUid = Binder.getCallingUid();
8749        final IPackageManager pm = AppGlobals.getPackageManager();
8750        try {
8751            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8752                    UserHandle.getUserId(callingUid));
8753            if (packageUid != callingUid) {
8754                throw new SecurityException(
8755                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8756            }
8757        } catch (RemoteException e) {
8758            throw new SecurityException("Failed to verify package name ownership");
8759        }
8760
8761        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8762        synchronized (this) {
8763            if (incoming) {
8764                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8765                        callingUid);
8766                if (perms == null) {
8767                    Slog.w(TAG, "No permission grants found for " + packageName);
8768                } else {
8769                    for (UriPermission perm : perms.values()) {
8770                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8771                            result.add(perm.buildPersistedPublicApiObject());
8772                        }
8773                    }
8774                }
8775            } else {
8776                final int size = mGrantedUriPermissions.size();
8777                for (int i = 0; i < size; i++) {
8778                    final ArrayMap<GrantUri, UriPermission> perms =
8779                            mGrantedUriPermissions.valueAt(i);
8780                    for (UriPermission perm : perms.values()) {
8781                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8782                            result.add(perm.buildPersistedPublicApiObject());
8783                        }
8784                    }
8785                }
8786            }
8787        }
8788        return new ParceledListSlice<android.content.UriPermission>(result);
8789    }
8790
8791    @Override
8792    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8793            String packageName, int userId) {
8794        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8795                "getGrantedUriPermissions");
8796
8797        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8798        synchronized (this) {
8799            final int size = mGrantedUriPermissions.size();
8800            for (int i = 0; i < size; i++) {
8801                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8802                for (UriPermission perm : perms.values()) {
8803                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8804                            && perm.persistedModeFlags != 0) {
8805                        result.add(perm.buildPersistedPublicApiObject());
8806                    }
8807                }
8808            }
8809        }
8810        return new ParceledListSlice<android.content.UriPermission>(result);
8811    }
8812
8813    @Override
8814    public void clearGrantedUriPermissions(String packageName, int userId) {
8815        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8816                "clearGrantedUriPermissions");
8817        removeUriPermissionsForPackageLocked(packageName, userId, true);
8818    }
8819
8820    @Override
8821    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8822        synchronized (this) {
8823            ProcessRecord app =
8824                who != null ? getRecordForAppLocked(who) : null;
8825            if (app == null) return;
8826
8827            Message msg = Message.obtain();
8828            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8829            msg.obj = app;
8830            msg.arg1 = waiting ? 1 : 0;
8831            mUiHandler.sendMessage(msg);
8832        }
8833    }
8834
8835    @Override
8836    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8837        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8838        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8839        outInfo.availMem = Process.getFreeMemory();
8840        outInfo.totalMem = Process.getTotalMemory();
8841        outInfo.threshold = homeAppMem;
8842        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8843        outInfo.hiddenAppThreshold = cachedAppMem;
8844        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8845                ProcessList.SERVICE_ADJ);
8846        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8847                ProcessList.VISIBLE_APP_ADJ);
8848        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8849                ProcessList.FOREGROUND_APP_ADJ);
8850    }
8851
8852    // =========================================================
8853    // TASK MANAGEMENT
8854    // =========================================================
8855
8856    @Override
8857    public List<IAppTask> getAppTasks(String callingPackage) {
8858        int callingUid = Binder.getCallingUid();
8859        long ident = Binder.clearCallingIdentity();
8860
8861        synchronized(this) {
8862            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8863            try {
8864                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8865
8866                final int N = mRecentTasks.size();
8867                for (int i = 0; i < N; i++) {
8868                    TaskRecord tr = mRecentTasks.get(i);
8869                    // Skip tasks that do not match the caller.  We don't need to verify
8870                    // callingPackage, because we are also limiting to callingUid and know
8871                    // that will limit to the correct security sandbox.
8872                    if (tr.effectiveUid != callingUid) {
8873                        continue;
8874                    }
8875                    Intent intent = tr.getBaseIntent();
8876                    if (intent == null ||
8877                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8878                        continue;
8879                    }
8880                    ActivityManager.RecentTaskInfo taskInfo =
8881                            createRecentTaskInfoFromTaskRecord(tr);
8882                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8883                    list.add(taskImpl);
8884                }
8885            } finally {
8886                Binder.restoreCallingIdentity(ident);
8887            }
8888            return list;
8889        }
8890    }
8891
8892    @Override
8893    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8894        final int callingUid = Binder.getCallingUid();
8895        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8896
8897        synchronized(this) {
8898            if (DEBUG_ALL) Slog.v(
8899                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8900
8901            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8902                    callingUid);
8903
8904            // TODO: Improve with MRU list from all ActivityStacks.
8905            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8906        }
8907
8908        return list;
8909    }
8910
8911    /**
8912     * Creates a new RecentTaskInfo from a TaskRecord.
8913     */
8914    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8915        // Update the task description to reflect any changes in the task stack
8916        tr.updateTaskDescription();
8917
8918        // Compose the recent task info
8919        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8920        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8921        rti.persistentId = tr.taskId;
8922        rti.baseIntent = new Intent(tr.getBaseIntent());
8923        rti.origActivity = tr.origActivity;
8924        rti.realActivity = tr.realActivity;
8925        rti.description = tr.lastDescription;
8926        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8927        rti.userId = tr.userId;
8928        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8929        rti.firstActiveTime = tr.firstActiveTime;
8930        rti.lastActiveTime = tr.lastActiveTime;
8931        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8932        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8933        rti.numActivities = 0;
8934        if (tr.mBounds != null) {
8935            rti.bounds = new Rect(tr.mBounds);
8936        }
8937        rti.isDockable = tr.canGoInDockedStack();
8938        rti.resizeMode = tr.mResizeMode;
8939
8940        ActivityRecord base = null;
8941        ActivityRecord top = null;
8942        ActivityRecord tmp;
8943
8944        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8945            tmp = tr.mActivities.get(i);
8946            if (tmp.finishing) {
8947                continue;
8948            }
8949            base = tmp;
8950            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8951                top = base;
8952            }
8953            rti.numActivities++;
8954        }
8955
8956        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8957        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8958
8959        return rti;
8960    }
8961
8962    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8963        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8964                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8965        if (!allowed) {
8966            if (checkPermission(android.Manifest.permission.GET_TASKS,
8967                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8968                // Temporary compatibility: some existing apps on the system image may
8969                // still be requesting the old permission and not switched to the new
8970                // one; if so, we'll still allow them full access.  This means we need
8971                // to see if they are holding the old permission and are a system app.
8972                try {
8973                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8974                        allowed = true;
8975                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8976                                + " is using old GET_TASKS but privileged; allowing");
8977                    }
8978                } catch (RemoteException e) {
8979                }
8980            }
8981        }
8982        if (!allowed) {
8983            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8984                    + " does not hold REAL_GET_TASKS; limiting output");
8985        }
8986        return allowed;
8987    }
8988
8989    @Override
8990    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8991        final int callingUid = Binder.getCallingUid();
8992        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8993                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8994
8995        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8996        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8997        synchronized (this) {
8998            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8999                    callingUid);
9000            final boolean detailed = checkCallingPermission(
9001                    android.Manifest.permission.GET_DETAILED_TASKS)
9002                    == PackageManager.PERMISSION_GRANTED;
9003
9004            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9005                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9006                return Collections.emptyList();
9007            }
9008            mRecentTasks.loadUserRecentsLocked(userId);
9009
9010            final int recentsCount = mRecentTasks.size();
9011            ArrayList<ActivityManager.RecentTaskInfo> res =
9012                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9013
9014            final Set<Integer> includedUsers;
9015            if (includeProfiles) {
9016                includedUsers = mUserController.getProfileIds(userId);
9017            } else {
9018                includedUsers = new HashSet<>();
9019            }
9020            includedUsers.add(Integer.valueOf(userId));
9021
9022            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9023                TaskRecord tr = mRecentTasks.get(i);
9024                // Only add calling user or related users recent tasks
9025                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9026                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9027                    continue;
9028                }
9029
9030                if (tr.realActivitySuspended) {
9031                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9032                    continue;
9033                }
9034
9035                // Return the entry if desired by the caller.  We always return
9036                // the first entry, because callers always expect this to be the
9037                // foreground app.  We may filter others if the caller has
9038                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9039                // we should exclude the entry.
9040
9041                if (i == 0
9042                        || withExcluded
9043                        || (tr.intent == null)
9044                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9045                                == 0)) {
9046                    if (!allowed) {
9047                        // If the caller doesn't have the GET_TASKS permission, then only
9048                        // allow them to see a small subset of tasks -- their own and home.
9049                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9050                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9051                            continue;
9052                        }
9053                    }
9054                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9055                        if (tr.stack != null && tr.stack.isHomeStack()) {
9056                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9057                                    "Skipping, home stack task: " + tr);
9058                            continue;
9059                        }
9060                    }
9061                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9062                        final ActivityStack stack = tr.stack;
9063                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9064                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9065                                    "Skipping, top task in docked stack: " + tr);
9066                            continue;
9067                        }
9068                    }
9069                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9070                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9071                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9072                                    "Skipping, pinned stack task: " + tr);
9073                            continue;
9074                        }
9075                    }
9076                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9077                        // Don't include auto remove tasks that are finished or finishing.
9078                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9079                                "Skipping, auto-remove without activity: " + tr);
9080                        continue;
9081                    }
9082                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9083                            && !tr.isAvailable) {
9084                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9085                                "Skipping, unavail real act: " + tr);
9086                        continue;
9087                    }
9088
9089                    if (!tr.mUserSetupComplete) {
9090                        // Don't include task launched while user is not done setting-up.
9091                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9092                                "Skipping, user setup not complete: " + tr);
9093                        continue;
9094                    }
9095
9096                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9097                    if (!detailed) {
9098                        rti.baseIntent.replaceExtras((Bundle)null);
9099                    }
9100
9101                    res.add(rti);
9102                    maxNum--;
9103                }
9104            }
9105            return res;
9106        }
9107    }
9108
9109    @Override
9110    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9111        synchronized (this) {
9112            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9113                    "getTaskThumbnail()");
9114            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9115                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9116            if (tr != null) {
9117                return tr.getTaskThumbnailLocked();
9118            }
9119        }
9120        return null;
9121    }
9122
9123    @Override
9124    public int addAppTask(IBinder activityToken, Intent intent,
9125            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9126        final int callingUid = Binder.getCallingUid();
9127        final long callingIdent = Binder.clearCallingIdentity();
9128
9129        try {
9130            synchronized (this) {
9131                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9132                if (r == null) {
9133                    throw new IllegalArgumentException("Activity does not exist; token="
9134                            + activityToken);
9135                }
9136                ComponentName comp = intent.getComponent();
9137                if (comp == null) {
9138                    throw new IllegalArgumentException("Intent " + intent
9139                            + " must specify explicit component");
9140                }
9141                if (thumbnail.getWidth() != mThumbnailWidth
9142                        || thumbnail.getHeight() != mThumbnailHeight) {
9143                    throw new IllegalArgumentException("Bad thumbnail size: got "
9144                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9145                            + mThumbnailWidth + "x" + mThumbnailHeight);
9146                }
9147                if (intent.getSelector() != null) {
9148                    intent.setSelector(null);
9149                }
9150                if (intent.getSourceBounds() != null) {
9151                    intent.setSourceBounds(null);
9152                }
9153                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9154                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9155                        // The caller has added this as an auto-remove task...  that makes no
9156                        // sense, so turn off auto-remove.
9157                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9158                    }
9159                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9160                    // Must be a new task.
9161                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9162                }
9163                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9164                    mLastAddedTaskActivity = null;
9165                }
9166                ActivityInfo ainfo = mLastAddedTaskActivity;
9167                if (ainfo == null) {
9168                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9169                            comp, 0, UserHandle.getUserId(callingUid));
9170                    if (ainfo.applicationInfo.uid != callingUid) {
9171                        throw new SecurityException(
9172                                "Can't add task for another application: target uid="
9173                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9174                    }
9175                }
9176
9177                // Use the full screen as the context for the task thumbnail
9178                final Point displaySize = new Point();
9179                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9180                r.task.stack.getDisplaySize(displaySize);
9181                thumbnailInfo.taskWidth = displaySize.x;
9182                thumbnailInfo.taskHeight = displaySize.y;
9183                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9184
9185                TaskRecord task = new TaskRecord(this,
9186                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9187                        ainfo, intent, description, thumbnailInfo);
9188
9189                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9190                if (trimIdx >= 0) {
9191                    // If this would have caused a trim, then we'll abort because that
9192                    // means it would be added at the end of the list but then just removed.
9193                    return INVALID_TASK_ID;
9194                }
9195
9196                final int N = mRecentTasks.size();
9197                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9198                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9199                    tr.removedFromRecents();
9200                }
9201
9202                task.inRecents = true;
9203                mRecentTasks.add(task);
9204                r.task.stack.addTask(task, false, "addAppTask");
9205
9206                task.setLastThumbnailLocked(thumbnail);
9207                task.freeLastThumbnail();
9208
9209                return task.taskId;
9210            }
9211        } finally {
9212            Binder.restoreCallingIdentity(callingIdent);
9213        }
9214    }
9215
9216    @Override
9217    public Point getAppTaskThumbnailSize() {
9218        synchronized (this) {
9219            return new Point(mThumbnailWidth,  mThumbnailHeight);
9220        }
9221    }
9222
9223    @Override
9224    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9225        synchronized (this) {
9226            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9227            if (r != null) {
9228                r.setTaskDescription(td);
9229                r.task.updateTaskDescription();
9230            }
9231        }
9232    }
9233
9234    @Override
9235    public void setTaskResizeable(int taskId, int resizeableMode) {
9236        synchronized (this) {
9237            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9238                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9239            if (task == null) {
9240                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9241                return;
9242            }
9243            if (task.mResizeMode != resizeableMode) {
9244                task.mResizeMode = resizeableMode;
9245                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9246                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9247                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9248            }
9249        }
9250    }
9251
9252    @Override
9253    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9254        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9255        long ident = Binder.clearCallingIdentity();
9256        try {
9257            synchronized (this) {
9258                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9259                if (task == null) {
9260                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9261                    return;
9262                }
9263                int stackId = task.stack.mStackId;
9264                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9265                // in crop windows resize mode or if the task size is affected by the docked stack
9266                // changing size. No need to update configuration.
9267                if (bounds != null && task.inCropWindowsResizeMode()
9268                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9269                    mWindowManager.scrollTask(task.taskId, bounds);
9270                    return;
9271                }
9272
9273                // Place the task in the right stack if it isn't there already based on
9274                // the requested bounds.
9275                // The stack transition logic is:
9276                // - a null bounds on a freeform task moves that task to fullscreen
9277                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9278                //   that task to freeform
9279                // - otherwise the task is not moved
9280                if (!StackId.isTaskResizeAllowed(stackId)) {
9281                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9282                }
9283                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9284                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9285                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9286                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9287                }
9288                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9289                if (stackId != task.stack.mStackId) {
9290                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9291                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9292                    preserveWindow = false;
9293                }
9294
9295                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9296                        false /* deferResume */);
9297            }
9298        } finally {
9299            Binder.restoreCallingIdentity(ident);
9300        }
9301    }
9302
9303    @Override
9304    public Rect getTaskBounds(int taskId) {
9305        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9306        long ident = Binder.clearCallingIdentity();
9307        Rect rect = new Rect();
9308        try {
9309            synchronized (this) {
9310                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9311                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9312                if (task == null) {
9313                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9314                    return rect;
9315                }
9316                if (task.stack != null) {
9317                    // Return the bounds from window manager since it will be adjusted for various
9318                    // things like the presense of a docked stack for tasks that aren't resizeable.
9319                    mWindowManager.getTaskBounds(task.taskId, rect);
9320                } else {
9321                    // Task isn't in window manager yet since it isn't associated with a stack.
9322                    // Return the persist value from activity manager
9323                    if (task.mBounds != null) {
9324                        rect.set(task.mBounds);
9325                    } else if (task.mLastNonFullscreenBounds != null) {
9326                        rect.set(task.mLastNonFullscreenBounds);
9327                    }
9328                }
9329            }
9330        } finally {
9331            Binder.restoreCallingIdentity(ident);
9332        }
9333        return rect;
9334    }
9335
9336    @Override
9337    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9338        if (userId != UserHandle.getCallingUserId()) {
9339            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9340                    "getTaskDescriptionIcon");
9341        }
9342        final File passedIconFile = new File(filePath);
9343        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9344                passedIconFile.getName());
9345        if (!legitIconFile.getPath().equals(filePath)
9346                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9347            throw new IllegalArgumentException("Bad file path: " + filePath
9348                    + " passed for userId " + userId);
9349        }
9350        return mRecentTasks.getTaskDescriptionIcon(filePath);
9351    }
9352
9353    @Override
9354    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9355            throws RemoteException {
9356        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9357                opts.getCustomInPlaceResId() == 0) {
9358            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9359                    "with valid animation");
9360        }
9361        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9362        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9363                opts.getCustomInPlaceResId());
9364        mWindowManager.executeAppTransition();
9365    }
9366
9367    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9368            boolean removeFromRecents) {
9369        if (removeFromRecents) {
9370            mRecentTasks.remove(tr);
9371            tr.removedFromRecents();
9372        }
9373        ComponentName component = tr.getBaseIntent().getComponent();
9374        if (component == null) {
9375            Slog.w(TAG, "No component for base intent of task: " + tr);
9376            return;
9377        }
9378
9379        // Find any running services associated with this app and stop if needed.
9380        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9381
9382        if (!killProcess) {
9383            return;
9384        }
9385
9386        // Determine if the process(es) for this task should be killed.
9387        final String pkg = component.getPackageName();
9388        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9389        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9390        for (int i = 0; i < pmap.size(); i++) {
9391
9392            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9393            for (int j = 0; j < uids.size(); j++) {
9394                ProcessRecord proc = uids.valueAt(j);
9395                if (proc.userId != tr.userId) {
9396                    // Don't kill process for a different user.
9397                    continue;
9398                }
9399                if (proc == mHomeProcess) {
9400                    // Don't kill the home process along with tasks from the same package.
9401                    continue;
9402                }
9403                if (!proc.pkgList.containsKey(pkg)) {
9404                    // Don't kill process that is not associated with this task.
9405                    continue;
9406                }
9407
9408                for (int k = 0; k < proc.activities.size(); k++) {
9409                    TaskRecord otherTask = proc.activities.get(k).task;
9410                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9411                        // Don't kill process(es) that has an activity in a different task that is
9412                        // also in recents.
9413                        return;
9414                    }
9415                }
9416
9417                if (proc.foregroundServices) {
9418                    // Don't kill process(es) with foreground service.
9419                    return;
9420                }
9421
9422                // Add process to kill list.
9423                procsToKill.add(proc);
9424            }
9425        }
9426
9427        // Kill the running processes.
9428        for (int i = 0; i < procsToKill.size(); i++) {
9429            ProcessRecord pr = procsToKill.get(i);
9430            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9431                    && pr.curReceiver == null) {
9432                pr.kill("remove task", true);
9433            } else {
9434                // We delay killing processes that are not in the background or running a receiver.
9435                pr.waitingToKill = "remove task";
9436            }
9437        }
9438    }
9439
9440    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9441        // Remove all tasks with activities in the specified package from the list of recent tasks
9442        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9443            TaskRecord tr = mRecentTasks.get(i);
9444            if (tr.userId != userId) continue;
9445
9446            ComponentName cn = tr.intent.getComponent();
9447            if (cn != null && cn.getPackageName().equals(packageName)) {
9448                // If the package name matches, remove the task.
9449                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9450            }
9451        }
9452    }
9453
9454    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9455            int userId) {
9456
9457        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9458            TaskRecord tr = mRecentTasks.get(i);
9459            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9460                continue;
9461            }
9462
9463            ComponentName cn = tr.intent.getComponent();
9464            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9465                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9466            if (sameComponent) {
9467                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9468            }
9469        }
9470    }
9471
9472    /**
9473     * Removes the task with the specified task id.
9474     *
9475     * @param taskId Identifier of the task to be removed.
9476     * @param killProcess Kill any process associated with the task if possible.
9477     * @param removeFromRecents Whether to also remove the task from recents.
9478     * @return Returns true if the given task was found and removed.
9479     */
9480    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9481            boolean removeFromRecents) {
9482        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9483                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9484        if (tr != null) {
9485            tr.removeTaskActivitiesLocked();
9486            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9487            if (tr.isPersistable) {
9488                notifyTaskPersisterLocked(null, true);
9489            }
9490            return true;
9491        }
9492        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9493        return false;
9494    }
9495
9496    @Override
9497    public void removeStack(int stackId) {
9498        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9499        if (stackId == HOME_STACK_ID) {
9500            throw new IllegalArgumentException("Removing home stack is not allowed.");
9501        }
9502
9503        synchronized (this) {
9504            final long ident = Binder.clearCallingIdentity();
9505            try {
9506                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9507                if (stack == null) {
9508                    return;
9509                }
9510                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9511                for (int i = tasks.size() - 1; i >= 0; i--) {
9512                    removeTaskByIdLocked(
9513                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9514                }
9515            } finally {
9516                Binder.restoreCallingIdentity(ident);
9517            }
9518        }
9519    }
9520
9521    @Override
9522    public boolean removeTask(int taskId) {
9523        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9524        synchronized (this) {
9525            final long ident = Binder.clearCallingIdentity();
9526            try {
9527                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9528            } finally {
9529                Binder.restoreCallingIdentity(ident);
9530            }
9531        }
9532    }
9533
9534    /**
9535     * TODO: Add mController hook
9536     */
9537    @Override
9538    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9539        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9540
9541        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9542        synchronized(this) {
9543            moveTaskToFrontLocked(taskId, flags, bOptions);
9544        }
9545    }
9546
9547    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9548        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9549
9550        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9551                Binder.getCallingUid(), -1, -1, "Task to front")) {
9552            ActivityOptions.abort(options);
9553            return;
9554        }
9555        final long origId = Binder.clearCallingIdentity();
9556        try {
9557            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9558            if (task == null) {
9559                Slog.d(TAG, "Could not find task for id: "+ taskId);
9560                return;
9561            }
9562            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9563                mStackSupervisor.showLockTaskToast();
9564                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9565                return;
9566            }
9567            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9568            if (prev != null && prev.isRecentsActivity()) {
9569                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9570            }
9571            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9572                    false /* forceNonResizable */);
9573        } finally {
9574            Binder.restoreCallingIdentity(origId);
9575        }
9576        ActivityOptions.abort(options);
9577    }
9578
9579    /**
9580     * Moves an activity, and all of the other activities within the same task, to the bottom
9581     * of the history stack.  The activity's order within the task is unchanged.
9582     *
9583     * @param token A reference to the activity we wish to move
9584     * @param nonRoot If false then this only works if the activity is the root
9585     *                of a task; if true it will work for any activity in a task.
9586     * @return Returns true if the move completed, false if not.
9587     */
9588    @Override
9589    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9590        enforceNotIsolatedCaller("moveActivityTaskToBack");
9591        synchronized(this) {
9592            final long origId = Binder.clearCallingIdentity();
9593            try {
9594                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9595                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9596                if (task != null) {
9597                    if (mStackSupervisor.isLockedTask(task)) {
9598                        mStackSupervisor.showLockTaskToast();
9599                        return false;
9600                    }
9601                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9602                }
9603            } finally {
9604                Binder.restoreCallingIdentity(origId);
9605            }
9606        }
9607        return false;
9608    }
9609
9610    @Override
9611    public void moveTaskBackwards(int task) {
9612        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9613                "moveTaskBackwards()");
9614
9615        synchronized(this) {
9616            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9617                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9618                return;
9619            }
9620            final long origId = Binder.clearCallingIdentity();
9621            moveTaskBackwardsLocked(task);
9622            Binder.restoreCallingIdentity(origId);
9623        }
9624    }
9625
9626    private final void moveTaskBackwardsLocked(int task) {
9627        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9628    }
9629
9630    @Override
9631    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9632            IActivityContainerCallback callback) throws RemoteException {
9633        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9634        synchronized (this) {
9635            if (parentActivityToken == null) {
9636                throw new IllegalArgumentException("parent token must not be null");
9637            }
9638            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9639            if (r == null) {
9640                return null;
9641            }
9642            if (callback == null) {
9643                throw new IllegalArgumentException("callback must not be null");
9644            }
9645            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9646        }
9647    }
9648
9649    @Override
9650    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9651        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9652        synchronized (this) {
9653            mStackSupervisor.deleteActivityContainer(container);
9654        }
9655    }
9656
9657    @Override
9658    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9659        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9660        synchronized (this) {
9661            final int stackId = mStackSupervisor.getNextStackId();
9662            final ActivityStack stack =
9663                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9664            if (stack == null) {
9665                return null;
9666            }
9667            return stack.mActivityContainer;
9668        }
9669    }
9670
9671    @Override
9672    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9673        synchronized (this) {
9674            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9675            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9676                return stack.mActivityContainer.getDisplayId();
9677            }
9678            return Display.DEFAULT_DISPLAY;
9679        }
9680    }
9681
9682    @Override
9683    public int getActivityStackId(IBinder token) throws RemoteException {
9684        synchronized (this) {
9685            ActivityStack stack = ActivityRecord.getStackLocked(token);
9686            if (stack == null) {
9687                return INVALID_STACK_ID;
9688            }
9689            return stack.mStackId;
9690        }
9691    }
9692
9693    @Override
9694    public void exitFreeformMode(IBinder token) throws RemoteException {
9695        synchronized (this) {
9696            long ident = Binder.clearCallingIdentity();
9697            try {
9698                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9699                if (r == null) {
9700                    throw new IllegalArgumentException(
9701                            "exitFreeformMode: No activity record matching token=" + token);
9702                }
9703                final ActivityStack stack = r.getStackLocked(token);
9704                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9705                    throw new IllegalStateException(
9706                            "exitFreeformMode: You can only go fullscreen from freeform.");
9707                }
9708                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9709                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9710                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9711            } finally {
9712                Binder.restoreCallingIdentity(ident);
9713            }
9714        }
9715    }
9716
9717    @Override
9718    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9719        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9720        if (stackId == HOME_STACK_ID) {
9721            throw new IllegalArgumentException(
9722                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9723        }
9724        synchronized (this) {
9725            long ident = Binder.clearCallingIdentity();
9726            try {
9727                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9728                        + " to stackId=" + stackId + " toTop=" + toTop);
9729                if (stackId == DOCKED_STACK_ID) {
9730                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9731                            null /* initialBounds */);
9732                }
9733                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9734                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9735                if (result && stackId == DOCKED_STACK_ID) {
9736                    // If task moved to docked stack - show recents if needed.
9737                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9738                            "moveTaskToDockedStack");
9739                }
9740            } finally {
9741                Binder.restoreCallingIdentity(ident);
9742            }
9743        }
9744    }
9745
9746    @Override
9747    public void swapDockedAndFullscreenStack() throws RemoteException {
9748        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9749        synchronized (this) {
9750            long ident = Binder.clearCallingIdentity();
9751            try {
9752                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9753                        FULLSCREEN_WORKSPACE_STACK_ID);
9754                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9755                        : null;
9756                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9757                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9758                        : null;
9759                if (topTask == null || tasks == null || tasks.size() == 0) {
9760                    Slog.w(TAG,
9761                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9762                    return;
9763                }
9764
9765                // TODO: App transition
9766                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9767
9768                // Defer the resume so resume/pausing while moving stacks is dangerous.
9769                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9770                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9771                        ANIMATE, true /* deferResume */);
9772                final int size = tasks.size();
9773                for (int i = 0; i < size; i++) {
9774                    final int id = tasks.get(i).taskId;
9775                    if (id == topTask.taskId) {
9776                        continue;
9777                    }
9778                    mStackSupervisor.moveTaskToStackLocked(id,
9779                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9780                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9781                }
9782
9783                // Because we deferred the resume, to avoid conflicts with stack switches while
9784                // resuming, we need to do it after all the tasks are moved.
9785                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9786                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9787
9788                mWindowManager.executeAppTransition();
9789            } finally {
9790                Binder.restoreCallingIdentity(ident);
9791            }
9792        }
9793    }
9794
9795    /**
9796     * Moves the input task to the docked stack.
9797     *
9798     * @param taskId Id of task to move.
9799     * @param createMode The mode the docked stack should be created in if it doesn't exist
9800     *                   already. See
9801     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9802     *                   and
9803     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9804     * @param toTop If the task and stack should be moved to the top.
9805     * @param animate Whether we should play an animation for the moving the task
9806     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9807     *                      docked stack. Pass {@code null} to use default bounds.
9808     */
9809    @Override
9810    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9811            Rect initialBounds, boolean moveHomeStackFront) {
9812        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9813        synchronized (this) {
9814            long ident = Binder.clearCallingIdentity();
9815            try {
9816                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9817                        + " to createMode=" + createMode + " toTop=" + toTop);
9818                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9819                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9820                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9821                        animate, DEFER_RESUME);
9822                if (moved) {
9823                    if (moveHomeStackFront) {
9824                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9825                    }
9826                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9827                }
9828                return moved;
9829            } finally {
9830                Binder.restoreCallingIdentity(ident);
9831            }
9832        }
9833    }
9834
9835    /**
9836     * Moves the top activity in the input stackId to the pinned stack.
9837     *
9838     * @param stackId Id of stack to move the top activity to pinned stack.
9839     * @param bounds Bounds to use for pinned stack.
9840     *
9841     * @return True if the top activity of the input stack was successfully moved to the pinned
9842     *          stack.
9843     */
9844    @Override
9845    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9846        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9847        synchronized (this) {
9848            if (!mSupportsPictureInPicture) {
9849                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9850                        + "Device doesn't support picture-in-pciture mode");
9851            }
9852
9853            long ident = Binder.clearCallingIdentity();
9854            try {
9855                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9856            } finally {
9857                Binder.restoreCallingIdentity(ident);
9858            }
9859        }
9860    }
9861
9862    @Override
9863    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9864            boolean preserveWindows, boolean animate, int animationDuration) {
9865        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9866        long ident = Binder.clearCallingIdentity();
9867        try {
9868            synchronized (this) {
9869                if (animate) {
9870                    if (stackId == PINNED_STACK_ID) {
9871                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9872                    } else {
9873                        throw new IllegalArgumentException("Stack: " + stackId
9874                                + " doesn't support animated resize.");
9875                    }
9876                } else {
9877                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9878                            null /* tempTaskInsetBounds */, preserveWindows,
9879                            allowResizeInDockedMode, !DEFER_RESUME);
9880                }
9881            }
9882        } finally {
9883            Binder.restoreCallingIdentity(ident);
9884        }
9885    }
9886
9887    @Override
9888    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9889            Rect tempDockedTaskInsetBounds,
9890            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9891        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9892                "resizeDockedStack()");
9893        long ident = Binder.clearCallingIdentity();
9894        try {
9895            synchronized (this) {
9896                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9897                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9898                        PRESERVE_WINDOWS);
9899            }
9900        } finally {
9901            Binder.restoreCallingIdentity(ident);
9902        }
9903    }
9904
9905    @Override
9906    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9907        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9908                "resizePinnedStack()");
9909        final long ident = Binder.clearCallingIdentity();
9910        try {
9911            synchronized (this) {
9912                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9913            }
9914        } finally {
9915            Binder.restoreCallingIdentity(ident);
9916        }
9917    }
9918
9919    @Override
9920    public void positionTaskInStack(int taskId, int stackId, int position) {
9921        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9922        if (stackId == HOME_STACK_ID) {
9923            throw new IllegalArgumentException(
9924                    "positionTaskInStack: Attempt to change the position of task "
9925                    + taskId + " in/to home stack");
9926        }
9927        synchronized (this) {
9928            long ident = Binder.clearCallingIdentity();
9929            try {
9930                if (DEBUG_STACK) Slog.d(TAG_STACK,
9931                        "positionTaskInStack: positioning task=" + taskId
9932                        + " in stackId=" + stackId + " at position=" + position);
9933                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9934            } finally {
9935                Binder.restoreCallingIdentity(ident);
9936            }
9937        }
9938    }
9939
9940    @Override
9941    public List<StackInfo> getAllStackInfos() {
9942        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9943        long ident = Binder.clearCallingIdentity();
9944        try {
9945            synchronized (this) {
9946                return mStackSupervisor.getAllStackInfosLocked();
9947            }
9948        } finally {
9949            Binder.restoreCallingIdentity(ident);
9950        }
9951    }
9952
9953    @Override
9954    public StackInfo getStackInfo(int stackId) {
9955        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9956        long ident = Binder.clearCallingIdentity();
9957        try {
9958            synchronized (this) {
9959                return mStackSupervisor.getStackInfoLocked(stackId);
9960            }
9961        } finally {
9962            Binder.restoreCallingIdentity(ident);
9963        }
9964    }
9965
9966    @Override
9967    public boolean isInHomeStack(int taskId) {
9968        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9969        long ident = Binder.clearCallingIdentity();
9970        try {
9971            synchronized (this) {
9972                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9973                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9974                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9975            }
9976        } finally {
9977            Binder.restoreCallingIdentity(ident);
9978        }
9979    }
9980
9981    @Override
9982    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9983        synchronized(this) {
9984            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9985        }
9986    }
9987
9988    @Override
9989    public void updateDeviceOwner(String packageName) {
9990        final int callingUid = Binder.getCallingUid();
9991        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9992            throw new SecurityException("updateDeviceOwner called from non-system process");
9993        }
9994        synchronized (this) {
9995            mDeviceOwnerName = packageName;
9996        }
9997    }
9998
9999    @Override
10000    public void updateLockTaskPackages(int userId, String[] packages) {
10001        final int callingUid = Binder.getCallingUid();
10002        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10003            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10004                    "updateLockTaskPackages()");
10005        }
10006        synchronized (this) {
10007            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10008                    Arrays.toString(packages));
10009            mLockTaskPackages.put(userId, packages);
10010            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10011        }
10012    }
10013
10014
10015    void startLockTaskModeLocked(TaskRecord task) {
10016        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10017        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10018            return;
10019        }
10020
10021        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10022        // is initiated by system after the pinning request was shown and locked mode is initiated
10023        // by an authorized app directly
10024        final int callingUid = Binder.getCallingUid();
10025        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10026        long ident = Binder.clearCallingIdentity();
10027        try {
10028            if (!isSystemInitiated) {
10029                task.mLockTaskUid = callingUid;
10030                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10031                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10032                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10033                    StatusBarManagerInternal statusBarManager =
10034                            LocalServices.getService(StatusBarManagerInternal.class);
10035                    if (statusBarManager != null) {
10036                        statusBarManager.showScreenPinningRequest(task.taskId);
10037                    }
10038                    return;
10039                }
10040
10041                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10042                if (stack == null || task != stack.topTask()) {
10043                    throw new IllegalArgumentException("Invalid task, not in foreground");
10044                }
10045            }
10046            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10047                    "Locking fully");
10048            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10049                    ActivityManager.LOCK_TASK_MODE_PINNED :
10050                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10051                    "startLockTask", true);
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public void startLockTaskMode(int taskId) {
10059        synchronized (this) {
10060            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10061            if (task != null) {
10062                startLockTaskModeLocked(task);
10063            }
10064        }
10065    }
10066
10067    @Override
10068    public void startLockTaskMode(IBinder token) {
10069        synchronized (this) {
10070            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10071            if (r == null) {
10072                return;
10073            }
10074            final TaskRecord task = r.task;
10075            if (task != null) {
10076                startLockTaskModeLocked(task);
10077            }
10078        }
10079    }
10080
10081    @Override
10082    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10083        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10084        // This makes inner call to look as if it was initiated by system.
10085        long ident = Binder.clearCallingIdentity();
10086        try {
10087            synchronized (this) {
10088                startLockTaskMode(taskId);
10089            }
10090        } finally {
10091            Binder.restoreCallingIdentity(ident);
10092        }
10093    }
10094
10095    @Override
10096    public void stopLockTaskMode() {
10097        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10098        if (lockTask == null) {
10099            // Our work here is done.
10100            return;
10101        }
10102
10103        final int callingUid = Binder.getCallingUid();
10104        final int lockTaskUid = lockTask.mLockTaskUid;
10105        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10106        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10107            // Done.
10108            return;
10109        } else {
10110            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10111            // It is possible lockTaskMode was started by the system process because
10112            // android:lockTaskMode is set to a locking value in the application manifest
10113            // instead of the app calling startLockTaskMode. In this case
10114            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10115            // {@link TaskRecord.effectiveUid} instead. Also caller with
10116            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10117            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10118                    && callingUid != lockTaskUid
10119                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10120                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10121                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10122            }
10123        }
10124        long ident = Binder.clearCallingIdentity();
10125        try {
10126            Log.d(TAG, "stopLockTaskMode");
10127            // Stop lock task
10128            synchronized (this) {
10129                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10130                        "stopLockTask", true);
10131            }
10132        } finally {
10133            Binder.restoreCallingIdentity(ident);
10134        }
10135    }
10136
10137    /**
10138     * This API should be called by SystemUI only when user perform certain action to dismiss
10139     * lock task mode. We should only dismiss pinned lock task mode in this case.
10140     */
10141    @Override
10142    public void stopSystemLockTaskMode() throws RemoteException {
10143        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10144            stopLockTaskMode();
10145        } else {
10146            mStackSupervisor.showLockTaskToast();
10147        }
10148    }
10149
10150    @Override
10151    public boolean isInLockTaskMode() {
10152        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10153    }
10154
10155    @Override
10156    public int getLockTaskModeState() {
10157        synchronized (this) {
10158            return mStackSupervisor.getLockTaskModeState();
10159        }
10160    }
10161
10162    @Override
10163    public void showLockTaskEscapeMessage(IBinder token) {
10164        synchronized (this) {
10165            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10166            if (r == null) {
10167                return;
10168            }
10169            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10170        }
10171    }
10172
10173    // =========================================================
10174    // CONTENT PROVIDERS
10175    // =========================================================
10176
10177    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10178        List<ProviderInfo> providers = null;
10179        try {
10180            providers = AppGlobals.getPackageManager()
10181                    .queryContentProviders(app.processName, app.uid,
10182                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10183                                    | MATCH_DEBUG_TRIAGED_MISSING)
10184                    .getList();
10185        } catch (RemoteException ex) {
10186        }
10187        if (DEBUG_MU) Slog.v(TAG_MU,
10188                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10189        int userId = app.userId;
10190        if (providers != null) {
10191            int N = providers.size();
10192            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10193            for (int i=0; i<N; i++) {
10194                // TODO: keep logic in sync with installEncryptionUnawareProviders
10195                ProviderInfo cpi =
10196                    (ProviderInfo)providers.get(i);
10197                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10198                        cpi.name, cpi.flags);
10199                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10200                    // This is a singleton provider, but a user besides the
10201                    // default user is asking to initialize a process it runs
10202                    // in...  well, no, it doesn't actually run in this process,
10203                    // it runs in the process of the default user.  Get rid of it.
10204                    providers.remove(i);
10205                    N--;
10206                    i--;
10207                    continue;
10208                }
10209
10210                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10211                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10212                if (cpr == null) {
10213                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10214                    mProviderMap.putProviderByClass(comp, cpr);
10215                }
10216                if (DEBUG_MU) Slog.v(TAG_MU,
10217                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10218                app.pubProviders.put(cpi.name, cpr);
10219                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10220                    // Don't add this if it is a platform component that is marked
10221                    // to run in multiple processes, because this is actually
10222                    // part of the framework so doesn't make sense to track as a
10223                    // separate apk in the process.
10224                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10225                            mProcessStats);
10226                }
10227                notifyPackageUse(cpi.applicationInfo.packageName,
10228                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10229            }
10230        }
10231        return providers;
10232    }
10233
10234    /**
10235     * Check if {@link ProcessRecord} has a possible chance at accessing the
10236     * given {@link ProviderInfo}. Final permission checking is always done
10237     * in {@link ContentProvider}.
10238     */
10239    private final String checkContentProviderPermissionLocked(
10240            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10241        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10242        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10243        boolean checkedGrants = false;
10244        if (checkUser) {
10245            // Looking for cross-user grants before enforcing the typical cross-users permissions
10246            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10247            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10248                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10249                    return null;
10250                }
10251                checkedGrants = true;
10252            }
10253            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10254                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10255            if (userId != tmpTargetUserId) {
10256                // When we actually went to determine the final targer user ID, this ended
10257                // up different than our initial check for the authority.  This is because
10258                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10259                // SELF.  So we need to re-check the grants again.
10260                checkedGrants = false;
10261            }
10262        }
10263        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10264                cpi.applicationInfo.uid, cpi.exported)
10265                == PackageManager.PERMISSION_GRANTED) {
10266            return null;
10267        }
10268        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10269                cpi.applicationInfo.uid, cpi.exported)
10270                == PackageManager.PERMISSION_GRANTED) {
10271            return null;
10272        }
10273
10274        PathPermission[] pps = cpi.pathPermissions;
10275        if (pps != null) {
10276            int i = pps.length;
10277            while (i > 0) {
10278                i--;
10279                PathPermission pp = pps[i];
10280                String pprperm = pp.getReadPermission();
10281                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10282                        cpi.applicationInfo.uid, cpi.exported)
10283                        == PackageManager.PERMISSION_GRANTED) {
10284                    return null;
10285                }
10286                String ppwperm = pp.getWritePermission();
10287                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10288                        cpi.applicationInfo.uid, cpi.exported)
10289                        == PackageManager.PERMISSION_GRANTED) {
10290                    return null;
10291                }
10292            }
10293        }
10294        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10295            return null;
10296        }
10297
10298        String msg;
10299        if (!cpi.exported) {
10300            msg = "Permission Denial: opening provider " + cpi.name
10301                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10302                    + ", uid=" + callingUid + ") that is not exported from uid "
10303                    + cpi.applicationInfo.uid;
10304        } else {
10305            msg = "Permission Denial: opening provider " + cpi.name
10306                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10307                    + ", uid=" + callingUid + ") requires "
10308                    + cpi.readPermission + " or " + cpi.writePermission;
10309        }
10310        Slog.w(TAG, msg);
10311        return msg;
10312    }
10313
10314    /**
10315     * Returns if the ContentProvider has granted a uri to callingUid
10316     */
10317    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10318        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10319        if (perms != null) {
10320            for (int i=perms.size()-1; i>=0; i--) {
10321                GrantUri grantUri = perms.keyAt(i);
10322                if (grantUri.sourceUserId == userId || !checkUser) {
10323                    if (matchesProvider(grantUri.uri, cpi)) {
10324                        return true;
10325                    }
10326                }
10327            }
10328        }
10329        return false;
10330    }
10331
10332    /**
10333     * Returns true if the uri authority is one of the authorities specified in the provider.
10334     */
10335    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10336        String uriAuth = uri.getAuthority();
10337        String cpiAuth = cpi.authority;
10338        if (cpiAuth.indexOf(';') == -1) {
10339            return cpiAuth.equals(uriAuth);
10340        }
10341        String[] cpiAuths = cpiAuth.split(";");
10342        int length = cpiAuths.length;
10343        for (int i = 0; i < length; i++) {
10344            if (cpiAuths[i].equals(uriAuth)) return true;
10345        }
10346        return false;
10347    }
10348
10349    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10350            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10351        if (r != null) {
10352            for (int i=0; i<r.conProviders.size(); i++) {
10353                ContentProviderConnection conn = r.conProviders.get(i);
10354                if (conn.provider == cpr) {
10355                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10356                            "Adding provider requested by "
10357                            + r.processName + " from process "
10358                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10359                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10360                    if (stable) {
10361                        conn.stableCount++;
10362                        conn.numStableIncs++;
10363                    } else {
10364                        conn.unstableCount++;
10365                        conn.numUnstableIncs++;
10366                    }
10367                    return conn;
10368                }
10369            }
10370            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10371            if (stable) {
10372                conn.stableCount = 1;
10373                conn.numStableIncs = 1;
10374            } else {
10375                conn.unstableCount = 1;
10376                conn.numUnstableIncs = 1;
10377            }
10378            cpr.connections.add(conn);
10379            r.conProviders.add(conn);
10380            startAssociationLocked(r.uid, r.processName, r.curProcState,
10381                    cpr.uid, cpr.name, cpr.info.processName);
10382            return conn;
10383        }
10384        cpr.addExternalProcessHandleLocked(externalProcessToken);
10385        return null;
10386    }
10387
10388    boolean decProviderCountLocked(ContentProviderConnection conn,
10389            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10390        if (conn != null) {
10391            cpr = conn.provider;
10392            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10393                    "Removing provider requested by "
10394                    + conn.client.processName + " from process "
10395                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10396                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10397            if (stable) {
10398                conn.stableCount--;
10399            } else {
10400                conn.unstableCount--;
10401            }
10402            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10403                cpr.connections.remove(conn);
10404                conn.client.conProviders.remove(conn);
10405                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10406                    // The client is more important than last activity -- note the time this
10407                    // is happening, so we keep the old provider process around a bit as last
10408                    // activity to avoid thrashing it.
10409                    if (cpr.proc != null) {
10410                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10411                    }
10412                }
10413                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10414                return true;
10415            }
10416            return false;
10417        }
10418        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10419        return false;
10420    }
10421
10422    private void checkTime(long startTime, String where) {
10423        long now = SystemClock.uptimeMillis();
10424        if ((now-startTime) > 50) {
10425            // If we are taking more than 50ms, log about it.
10426            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10427        }
10428    }
10429
10430    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10431            String name, IBinder token, boolean stable, int userId) {
10432        ContentProviderRecord cpr;
10433        ContentProviderConnection conn = null;
10434        ProviderInfo cpi = null;
10435
10436        synchronized(this) {
10437            long startTime = SystemClock.uptimeMillis();
10438
10439            ProcessRecord r = null;
10440            if (caller != null) {
10441                r = getRecordForAppLocked(caller);
10442                if (r == null) {
10443                    throw new SecurityException(
10444                            "Unable to find app for caller " + caller
10445                          + " (pid=" + Binder.getCallingPid()
10446                          + ") when getting content provider " + name);
10447                }
10448            }
10449
10450            boolean checkCrossUser = true;
10451
10452            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10453
10454            // First check if this content provider has been published...
10455            cpr = mProviderMap.getProviderByName(name, userId);
10456            // If that didn't work, check if it exists for user 0 and then
10457            // verify that it's a singleton provider before using it.
10458            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10459                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10460                if (cpr != null) {
10461                    cpi = cpr.info;
10462                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10463                            cpi.name, cpi.flags)
10464                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10465                        userId = UserHandle.USER_SYSTEM;
10466                        checkCrossUser = false;
10467                    } else {
10468                        cpr = null;
10469                        cpi = null;
10470                    }
10471                }
10472            }
10473
10474            boolean providerRunning = cpr != null;
10475            if (providerRunning) {
10476                cpi = cpr.info;
10477                String msg;
10478                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10479                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10480                        != null) {
10481                    throw new SecurityException(msg);
10482                }
10483                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10484
10485                if (r != null && cpr.canRunHere(r)) {
10486                    // This provider has been published or is in the process
10487                    // of being published...  but it is also allowed to run
10488                    // in the caller's process, so don't make a connection
10489                    // and just let the caller instantiate its own instance.
10490                    ContentProviderHolder holder = cpr.newHolder(null);
10491                    // don't give caller the provider object, it needs
10492                    // to make its own.
10493                    holder.provider = null;
10494                    return holder;
10495                }
10496
10497                final long origId = Binder.clearCallingIdentity();
10498
10499                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10500
10501                // In this case the provider instance already exists, so we can
10502                // return it right away.
10503                conn = incProviderCountLocked(r, cpr, token, stable);
10504                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10505                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10506                        // If this is a perceptible app accessing the provider,
10507                        // make sure to count it as being accessed and thus
10508                        // back up on the LRU list.  This is good because
10509                        // content providers are often expensive to start.
10510                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10511                        updateLruProcessLocked(cpr.proc, false, null);
10512                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10513                    }
10514                }
10515
10516                if (cpr.proc != null) {
10517                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10518                    boolean success = updateOomAdjLocked(cpr.proc);
10519                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10520                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10521                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10522                    // NOTE: there is still a race here where a signal could be
10523                    // pending on the process even though we managed to update its
10524                    // adj level.  Not sure what to do about this, but at least
10525                    // the race is now smaller.
10526                    if (!success) {
10527                        // Uh oh...  it looks like the provider's process
10528                        // has been killed on us.  We need to wait for a new
10529                        // process to be started, and make sure its death
10530                        // doesn't kill our process.
10531                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10532                                + " is crashing; detaching " + r);
10533                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10534                        checkTime(startTime, "getContentProviderImpl: before appDied");
10535                        appDiedLocked(cpr.proc);
10536                        checkTime(startTime, "getContentProviderImpl: after appDied");
10537                        if (!lastRef) {
10538                            // This wasn't the last ref our process had on
10539                            // the provider...  we have now been killed, bail.
10540                            return null;
10541                        }
10542                        providerRunning = false;
10543                        conn = null;
10544                    }
10545                }
10546
10547                Binder.restoreCallingIdentity(origId);
10548            }
10549
10550            if (!providerRunning) {
10551                try {
10552                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10553                    cpi = AppGlobals.getPackageManager().
10554                        resolveContentProvider(name,
10555                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10556                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10557                } catch (RemoteException ex) {
10558                }
10559                if (cpi == null) {
10560                    return null;
10561                }
10562                // If the provider is a singleton AND
10563                // (it's a call within the same user || the provider is a
10564                // privileged app)
10565                // Then allow connecting to the singleton provider
10566                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10567                        cpi.name, cpi.flags)
10568                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10569                if (singleton) {
10570                    userId = UserHandle.USER_SYSTEM;
10571                }
10572                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10573                checkTime(startTime, "getContentProviderImpl: got app info for user");
10574
10575                String msg;
10576                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10577                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10578                        != null) {
10579                    throw new SecurityException(msg);
10580                }
10581                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10582
10583                if (!mProcessesReady
10584                        && !cpi.processName.equals("system")) {
10585                    // If this content provider does not run in the system
10586                    // process, and the system is not yet ready to run other
10587                    // processes, then fail fast instead of hanging.
10588                    throw new IllegalArgumentException(
10589                            "Attempt to launch content provider before system ready");
10590                }
10591
10592                // Make sure that the user who owns this provider is running.  If not,
10593                // we don't want to allow it to run.
10594                if (!mUserController.isUserRunningLocked(userId, 0)) {
10595                    Slog.w(TAG, "Unable to launch app "
10596                            + cpi.applicationInfo.packageName + "/"
10597                            + cpi.applicationInfo.uid + " for provider "
10598                            + name + ": user " + userId + " is stopped");
10599                    return null;
10600                }
10601
10602                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10603                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10604                cpr = mProviderMap.getProviderByClass(comp, userId);
10605                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10606                final boolean firstClass = cpr == null;
10607                if (firstClass) {
10608                    final long ident = Binder.clearCallingIdentity();
10609
10610                    // If permissions need a review before any of the app components can run,
10611                    // we return no provider and launch a review activity if the calling app
10612                    // is in the foreground.
10613                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10614                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10615                            return null;
10616                        }
10617                    }
10618
10619                    try {
10620                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10621                        ApplicationInfo ai =
10622                            AppGlobals.getPackageManager().
10623                                getApplicationInfo(
10624                                        cpi.applicationInfo.packageName,
10625                                        STOCK_PM_FLAGS, userId);
10626                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10627                        if (ai == null) {
10628                            Slog.w(TAG, "No package info for content provider "
10629                                    + cpi.name);
10630                            return null;
10631                        }
10632                        ai = getAppInfoForUser(ai, userId);
10633                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10634                    } catch (RemoteException ex) {
10635                        // pm is in same process, this will never happen.
10636                    } finally {
10637                        Binder.restoreCallingIdentity(ident);
10638                    }
10639                }
10640
10641                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10642
10643                if (r != null && cpr.canRunHere(r)) {
10644                    // If this is a multiprocess provider, then just return its
10645                    // info and allow the caller to instantiate it.  Only do
10646                    // this if the provider is the same user as the caller's
10647                    // process, or can run as root (so can be in any process).
10648                    return cpr.newHolder(null);
10649                }
10650
10651                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10652                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10653                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10654
10655                // This is single process, and our app is now connecting to it.
10656                // See if we are already in the process of launching this
10657                // provider.
10658                final int N = mLaunchingProviders.size();
10659                int i;
10660                for (i = 0; i < N; i++) {
10661                    if (mLaunchingProviders.get(i) == cpr) {
10662                        break;
10663                    }
10664                }
10665
10666                // If the provider is not already being launched, then get it
10667                // started.
10668                if (i >= N) {
10669                    final long origId = Binder.clearCallingIdentity();
10670
10671                    try {
10672                        // Content provider is now in use, its package can't be stopped.
10673                        try {
10674                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10675                            AppGlobals.getPackageManager().setPackageStoppedState(
10676                                    cpr.appInfo.packageName, false, userId);
10677                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10678                        } catch (RemoteException e) {
10679                        } catch (IllegalArgumentException e) {
10680                            Slog.w(TAG, "Failed trying to unstop package "
10681                                    + cpr.appInfo.packageName + ": " + e);
10682                        }
10683
10684                        // Use existing process if already started
10685                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10686                        ProcessRecord proc = getProcessRecordLocked(
10687                                cpi.processName, cpr.appInfo.uid, false);
10688                        if (proc != null && proc.thread != null) {
10689                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10690                                    "Installing in existing process " + proc);
10691                            if (!proc.pubProviders.containsKey(cpi.name)) {
10692                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10693                                proc.pubProviders.put(cpi.name, cpr);
10694                                try {
10695                                    proc.thread.scheduleInstallProvider(cpi);
10696                                } catch (RemoteException e) {
10697                                }
10698                            }
10699                        } else {
10700                            checkTime(startTime, "getContentProviderImpl: before start process");
10701                            proc = startProcessLocked(cpi.processName,
10702                                    cpr.appInfo, false, 0, "content provider",
10703                                    new ComponentName(cpi.applicationInfo.packageName,
10704                                            cpi.name), false, false, false);
10705                            checkTime(startTime, "getContentProviderImpl: after start process");
10706                            if (proc == null) {
10707                                Slog.w(TAG, "Unable to launch app "
10708                                        + cpi.applicationInfo.packageName + "/"
10709                                        + cpi.applicationInfo.uid + " for provider "
10710                                        + name + ": process is bad");
10711                                return null;
10712                            }
10713                        }
10714                        cpr.launchingApp = proc;
10715                        mLaunchingProviders.add(cpr);
10716                    } finally {
10717                        Binder.restoreCallingIdentity(origId);
10718                    }
10719                }
10720
10721                checkTime(startTime, "getContentProviderImpl: updating data structures");
10722
10723                // Make sure the provider is published (the same provider class
10724                // may be published under multiple names).
10725                if (firstClass) {
10726                    mProviderMap.putProviderByClass(comp, cpr);
10727                }
10728
10729                mProviderMap.putProviderByName(name, cpr);
10730                conn = incProviderCountLocked(r, cpr, token, stable);
10731                if (conn != null) {
10732                    conn.waiting = true;
10733                }
10734            }
10735            checkTime(startTime, "getContentProviderImpl: done!");
10736        }
10737
10738        // Wait for the provider to be published...
10739        synchronized (cpr) {
10740            while (cpr.provider == null) {
10741                if (cpr.launchingApp == null) {
10742                    Slog.w(TAG, "Unable to launch app "
10743                            + cpi.applicationInfo.packageName + "/"
10744                            + cpi.applicationInfo.uid + " for provider "
10745                            + name + ": launching app became null");
10746                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10747                            UserHandle.getUserId(cpi.applicationInfo.uid),
10748                            cpi.applicationInfo.packageName,
10749                            cpi.applicationInfo.uid, name);
10750                    return null;
10751                }
10752                try {
10753                    if (DEBUG_MU) Slog.v(TAG_MU,
10754                            "Waiting to start provider " + cpr
10755                            + " launchingApp=" + cpr.launchingApp);
10756                    if (conn != null) {
10757                        conn.waiting = true;
10758                    }
10759                    cpr.wait();
10760                } catch (InterruptedException ex) {
10761                } finally {
10762                    if (conn != null) {
10763                        conn.waiting = false;
10764                    }
10765                }
10766            }
10767        }
10768        return cpr != null ? cpr.newHolder(conn) : null;
10769    }
10770
10771    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10772            ProcessRecord r, final int userId) {
10773        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10774                cpi.packageName, userId)) {
10775
10776            final boolean callerForeground = r == null || r.setSchedGroup
10777                    != ProcessList.SCHED_GROUP_BACKGROUND;
10778
10779            // Show a permission review UI only for starting from a foreground app
10780            if (!callerForeground) {
10781                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10782                        + cpi.packageName + " requires a permissions review");
10783                return false;
10784            }
10785
10786            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10787            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10788                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10789            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10790
10791            if (DEBUG_PERMISSIONS_REVIEW) {
10792                Slog.i(TAG, "u" + userId + " Launching permission review "
10793                        + "for package " + cpi.packageName);
10794            }
10795
10796            final UserHandle userHandle = new UserHandle(userId);
10797            mHandler.post(new Runnable() {
10798                @Override
10799                public void run() {
10800                    mContext.startActivityAsUser(intent, userHandle);
10801                }
10802            });
10803
10804            return false;
10805        }
10806
10807        return true;
10808    }
10809
10810    PackageManagerInternal getPackageManagerInternalLocked() {
10811        if (mPackageManagerInt == null) {
10812            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10813        }
10814        return mPackageManagerInt;
10815    }
10816
10817    @Override
10818    public final ContentProviderHolder getContentProvider(
10819            IApplicationThread caller, String name, int userId, boolean stable) {
10820        enforceNotIsolatedCaller("getContentProvider");
10821        if (caller == null) {
10822            String msg = "null IApplicationThread when getting content provider "
10823                    + name;
10824            Slog.w(TAG, msg);
10825            throw new SecurityException(msg);
10826        }
10827        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10828        // with cross-user grant.
10829        return getContentProviderImpl(caller, name, null, stable, userId);
10830    }
10831
10832    public ContentProviderHolder getContentProviderExternal(
10833            String name, int userId, IBinder token) {
10834        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10835            "Do not have permission in call getContentProviderExternal()");
10836        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10837                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10838        return getContentProviderExternalUnchecked(name, token, userId);
10839    }
10840
10841    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10842            IBinder token, int userId) {
10843        return getContentProviderImpl(null, name, token, true, userId);
10844    }
10845
10846    /**
10847     * Drop a content provider from a ProcessRecord's bookkeeping
10848     */
10849    public void removeContentProvider(IBinder connection, boolean stable) {
10850        enforceNotIsolatedCaller("removeContentProvider");
10851        long ident = Binder.clearCallingIdentity();
10852        try {
10853            synchronized (this) {
10854                ContentProviderConnection conn;
10855                try {
10856                    conn = (ContentProviderConnection)connection;
10857                } catch (ClassCastException e) {
10858                    String msg ="removeContentProvider: " + connection
10859                            + " not a ContentProviderConnection";
10860                    Slog.w(TAG, msg);
10861                    throw new IllegalArgumentException(msg);
10862                }
10863                if (conn == null) {
10864                    throw new NullPointerException("connection is null");
10865                }
10866                if (decProviderCountLocked(conn, null, null, stable)) {
10867                    updateOomAdjLocked();
10868                }
10869            }
10870        } finally {
10871            Binder.restoreCallingIdentity(ident);
10872        }
10873    }
10874
10875    public void removeContentProviderExternal(String name, IBinder token) {
10876        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10877            "Do not have permission in call removeContentProviderExternal()");
10878        int userId = UserHandle.getCallingUserId();
10879        long ident = Binder.clearCallingIdentity();
10880        try {
10881            removeContentProviderExternalUnchecked(name, token, userId);
10882        } finally {
10883            Binder.restoreCallingIdentity(ident);
10884        }
10885    }
10886
10887    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10888        synchronized (this) {
10889            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10890            if(cpr == null) {
10891                //remove from mProvidersByClass
10892                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10893                return;
10894            }
10895
10896            //update content provider record entry info
10897            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10898            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10899            if (localCpr.hasExternalProcessHandles()) {
10900                if (localCpr.removeExternalProcessHandleLocked(token)) {
10901                    updateOomAdjLocked();
10902                } else {
10903                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10904                            + " with no external reference for token: "
10905                            + token + ".");
10906                }
10907            } else {
10908                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10909                        + " with no external references.");
10910            }
10911        }
10912    }
10913
10914    public final void publishContentProviders(IApplicationThread caller,
10915            List<ContentProviderHolder> providers) {
10916        if (providers == null) {
10917            return;
10918        }
10919
10920        enforceNotIsolatedCaller("publishContentProviders");
10921        synchronized (this) {
10922            final ProcessRecord r = getRecordForAppLocked(caller);
10923            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10924            if (r == null) {
10925                throw new SecurityException(
10926                        "Unable to find app for caller " + caller
10927                      + " (pid=" + Binder.getCallingPid()
10928                      + ") when publishing content providers");
10929            }
10930
10931            final long origId = Binder.clearCallingIdentity();
10932
10933            final int N = providers.size();
10934            for (int i = 0; i < N; i++) {
10935                ContentProviderHolder src = providers.get(i);
10936                if (src == null || src.info == null || src.provider == null) {
10937                    continue;
10938                }
10939                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10940                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10941                if (dst != null) {
10942                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10943                    mProviderMap.putProviderByClass(comp, dst);
10944                    String names[] = dst.info.authority.split(";");
10945                    for (int j = 0; j < names.length; j++) {
10946                        mProviderMap.putProviderByName(names[j], dst);
10947                    }
10948
10949                    int launchingCount = mLaunchingProviders.size();
10950                    int j;
10951                    boolean wasInLaunchingProviders = false;
10952                    for (j = 0; j < launchingCount; j++) {
10953                        if (mLaunchingProviders.get(j) == dst) {
10954                            mLaunchingProviders.remove(j);
10955                            wasInLaunchingProviders = true;
10956                            j--;
10957                            launchingCount--;
10958                        }
10959                    }
10960                    if (wasInLaunchingProviders) {
10961                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10962                    }
10963                    synchronized (dst) {
10964                        dst.provider = src.provider;
10965                        dst.proc = r;
10966                        dst.notifyAll();
10967                    }
10968                    updateOomAdjLocked(r);
10969                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10970                            src.info.authority);
10971                }
10972            }
10973
10974            Binder.restoreCallingIdentity(origId);
10975        }
10976    }
10977
10978    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10979        ContentProviderConnection conn;
10980        try {
10981            conn = (ContentProviderConnection)connection;
10982        } catch (ClassCastException e) {
10983            String msg ="refContentProvider: " + connection
10984                    + " not a ContentProviderConnection";
10985            Slog.w(TAG, msg);
10986            throw new IllegalArgumentException(msg);
10987        }
10988        if (conn == null) {
10989            throw new NullPointerException("connection is null");
10990        }
10991
10992        synchronized (this) {
10993            if (stable > 0) {
10994                conn.numStableIncs += stable;
10995            }
10996            stable = conn.stableCount + stable;
10997            if (stable < 0) {
10998                throw new IllegalStateException("stableCount < 0: " + stable);
10999            }
11000
11001            if (unstable > 0) {
11002                conn.numUnstableIncs += unstable;
11003            }
11004            unstable = conn.unstableCount + unstable;
11005            if (unstable < 0) {
11006                throw new IllegalStateException("unstableCount < 0: " + unstable);
11007            }
11008
11009            if ((stable+unstable) <= 0) {
11010                throw new IllegalStateException("ref counts can't go to zero here: stable="
11011                        + stable + " unstable=" + unstable);
11012            }
11013            conn.stableCount = stable;
11014            conn.unstableCount = unstable;
11015            return !conn.dead;
11016        }
11017    }
11018
11019    public void unstableProviderDied(IBinder connection) {
11020        ContentProviderConnection conn;
11021        try {
11022            conn = (ContentProviderConnection)connection;
11023        } catch (ClassCastException e) {
11024            String msg ="refContentProvider: " + connection
11025                    + " not a ContentProviderConnection";
11026            Slog.w(TAG, msg);
11027            throw new IllegalArgumentException(msg);
11028        }
11029        if (conn == null) {
11030            throw new NullPointerException("connection is null");
11031        }
11032
11033        // Safely retrieve the content provider associated with the connection.
11034        IContentProvider provider;
11035        synchronized (this) {
11036            provider = conn.provider.provider;
11037        }
11038
11039        if (provider == null) {
11040            // Um, yeah, we're way ahead of you.
11041            return;
11042        }
11043
11044        // Make sure the caller is being honest with us.
11045        if (provider.asBinder().pingBinder()) {
11046            // Er, no, still looks good to us.
11047            synchronized (this) {
11048                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11049                        + " says " + conn + " died, but we don't agree");
11050                return;
11051            }
11052        }
11053
11054        // Well look at that!  It's dead!
11055        synchronized (this) {
11056            if (conn.provider.provider != provider) {
11057                // But something changed...  good enough.
11058                return;
11059            }
11060
11061            ProcessRecord proc = conn.provider.proc;
11062            if (proc == null || proc.thread == null) {
11063                // Seems like the process is already cleaned up.
11064                return;
11065            }
11066
11067            // As far as we're concerned, this is just like receiving a
11068            // death notification...  just a bit prematurely.
11069            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11070                    + ") early provider death");
11071            final long ident = Binder.clearCallingIdentity();
11072            try {
11073                appDiedLocked(proc);
11074            } finally {
11075                Binder.restoreCallingIdentity(ident);
11076            }
11077        }
11078    }
11079
11080    @Override
11081    public void appNotRespondingViaProvider(IBinder connection) {
11082        enforceCallingPermission(
11083                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11084
11085        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11086        if (conn == null) {
11087            Slog.w(TAG, "ContentProviderConnection is null");
11088            return;
11089        }
11090
11091        final ProcessRecord host = conn.provider.proc;
11092        if (host == null) {
11093            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11094            return;
11095        }
11096
11097        mHandler.post(new Runnable() {
11098            @Override
11099            public void run() {
11100                mAppErrors.appNotResponding(host, null, null, false,
11101                        "ContentProvider not responding");
11102            }
11103        });
11104    }
11105
11106    public final void installSystemProviders() {
11107        List<ProviderInfo> providers;
11108        synchronized (this) {
11109            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11110            providers = generateApplicationProvidersLocked(app);
11111            if (providers != null) {
11112                for (int i=providers.size()-1; i>=0; i--) {
11113                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11114                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11115                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11116                                + ": not system .apk");
11117                        providers.remove(i);
11118                    }
11119                }
11120            }
11121        }
11122        if (providers != null) {
11123            mSystemThread.installSystemProviders(providers);
11124        }
11125
11126        mCoreSettingsObserver = new CoreSettingsObserver(this);
11127        mFontScaleSettingObserver = new FontScaleSettingObserver();
11128
11129        //mUsageStatsService.monitorPackages();
11130    }
11131
11132    private void startPersistentApps(int matchFlags) {
11133        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11134
11135        synchronized (this) {
11136            try {
11137                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11138                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11139                for (ApplicationInfo app : apps) {
11140                    if (!"android".equals(app.packageName)) {
11141                        addAppLocked(app, false, null /* ABI override */);
11142                    }
11143                }
11144            } catch (RemoteException ex) {
11145            }
11146        }
11147    }
11148
11149    /**
11150     * When a user is unlocked, we need to install encryption-unaware providers
11151     * belonging to any running apps.
11152     */
11153    private void installEncryptionUnawareProviders(int userId) {
11154        // We're only interested in providers that are encryption unaware, and
11155        // we don't care about uninstalled apps, since there's no way they're
11156        // running at this point.
11157        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11158
11159        synchronized (this) {
11160            final int NP = mProcessNames.getMap().size();
11161            for (int ip = 0; ip < NP; ip++) {
11162                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11163                final int NA = apps.size();
11164                for (int ia = 0; ia < NA; ia++) {
11165                    final ProcessRecord app = apps.valueAt(ia);
11166                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11167
11168                    final int NG = app.pkgList.size();
11169                    for (int ig = 0; ig < NG; ig++) {
11170                        try {
11171                            final String pkgName = app.pkgList.keyAt(ig);
11172                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11173                                    .getPackageInfo(pkgName, matchFlags, userId);
11174                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11175                                for (ProviderInfo pi : pkgInfo.providers) {
11176                                    // TODO: keep in sync with generateApplicationProvidersLocked
11177                                    final boolean processMatch = Objects.equals(pi.processName,
11178                                            app.processName) || pi.multiprocess;
11179                                    final boolean userMatch = isSingleton(pi.processName,
11180                                            pi.applicationInfo, pi.name, pi.flags)
11181                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11182                                    if (processMatch && userMatch) {
11183                                        Log.v(TAG, "Installing " + pi);
11184                                        app.thread.scheduleInstallProvider(pi);
11185                                    } else {
11186                                        Log.v(TAG, "Skipping " + pi);
11187                                    }
11188                                }
11189                            }
11190                        } catch (RemoteException ignored) {
11191                        }
11192                    }
11193                }
11194            }
11195        }
11196    }
11197
11198    /**
11199     * Allows apps to retrieve the MIME type of a URI.
11200     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11201     * users, then it does not need permission to access the ContentProvider.
11202     * Either, it needs cross-user uri grants.
11203     *
11204     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11205     *
11206     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11207     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11208     */
11209    public String getProviderMimeType(Uri uri, int userId) {
11210        enforceNotIsolatedCaller("getProviderMimeType");
11211        final String name = uri.getAuthority();
11212        int callingUid = Binder.getCallingUid();
11213        int callingPid = Binder.getCallingPid();
11214        long ident = 0;
11215        boolean clearedIdentity = false;
11216        synchronized (this) {
11217            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11218        }
11219        if (canClearIdentity(callingPid, callingUid, userId)) {
11220            clearedIdentity = true;
11221            ident = Binder.clearCallingIdentity();
11222        }
11223        ContentProviderHolder holder = null;
11224        try {
11225            holder = getContentProviderExternalUnchecked(name, null, userId);
11226            if (holder != null) {
11227                return holder.provider.getType(uri);
11228            }
11229        } catch (RemoteException e) {
11230            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11231            return null;
11232        } finally {
11233            // We need to clear the identity to call removeContentProviderExternalUnchecked
11234            if (!clearedIdentity) {
11235                ident = Binder.clearCallingIdentity();
11236            }
11237            try {
11238                if (holder != null) {
11239                    removeContentProviderExternalUnchecked(name, null, userId);
11240                }
11241            } finally {
11242                Binder.restoreCallingIdentity(ident);
11243            }
11244        }
11245
11246        return null;
11247    }
11248
11249    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11250        if (UserHandle.getUserId(callingUid) == userId) {
11251            return true;
11252        }
11253        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11254                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11255                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11256                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11257                return true;
11258        }
11259        return false;
11260    }
11261
11262    // =========================================================
11263    // GLOBAL MANAGEMENT
11264    // =========================================================
11265
11266    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11267            boolean isolated, int isolatedUid) {
11268        String proc = customProcess != null ? customProcess : info.processName;
11269        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11270        final int userId = UserHandle.getUserId(info.uid);
11271        int uid = info.uid;
11272        if (isolated) {
11273            if (isolatedUid == 0) {
11274                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11275                while (true) {
11276                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11277                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11278                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11279                    }
11280                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11281                    mNextIsolatedProcessUid++;
11282                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11283                        // No process for this uid, use it.
11284                        break;
11285                    }
11286                    stepsLeft--;
11287                    if (stepsLeft <= 0) {
11288                        return null;
11289                    }
11290                }
11291            } else {
11292                // Special case for startIsolatedProcess (internal only), where
11293                // the uid of the isolated process is specified by the caller.
11294                uid = isolatedUid;
11295            }
11296        }
11297        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11298        if (!mBooted && !mBooting
11299                && userId == UserHandle.USER_SYSTEM
11300                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11301            r.persistent = true;
11302        }
11303        addProcessNameLocked(r);
11304        return r;
11305    }
11306
11307    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11308            String abiOverride) {
11309        ProcessRecord app;
11310        if (!isolated) {
11311            app = getProcessRecordLocked(info.processName, info.uid, true);
11312        } else {
11313            app = null;
11314        }
11315
11316        if (app == null) {
11317            app = newProcessRecordLocked(info, null, isolated, 0);
11318            updateLruProcessLocked(app, false, null);
11319            updateOomAdjLocked();
11320        }
11321
11322        // This package really, really can not be stopped.
11323        try {
11324            AppGlobals.getPackageManager().setPackageStoppedState(
11325                    info.packageName, false, UserHandle.getUserId(app.uid));
11326        } catch (RemoteException e) {
11327        } catch (IllegalArgumentException e) {
11328            Slog.w(TAG, "Failed trying to unstop package "
11329                    + info.packageName + ": " + e);
11330        }
11331
11332        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11333            app.persistent = true;
11334            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11335        }
11336        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11337            mPersistentStartingProcesses.add(app);
11338            startProcessLocked(app, "added application", app.processName, abiOverride,
11339                    null /* entryPoint */, null /* entryPointArgs */);
11340        }
11341
11342        return app;
11343    }
11344
11345    public void unhandledBack() {
11346        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11347                "unhandledBack()");
11348
11349        synchronized(this) {
11350            final long origId = Binder.clearCallingIdentity();
11351            try {
11352                getFocusedStack().unhandledBackLocked();
11353            } finally {
11354                Binder.restoreCallingIdentity(origId);
11355            }
11356        }
11357    }
11358
11359    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11360        enforceNotIsolatedCaller("openContentUri");
11361        final int userId = UserHandle.getCallingUserId();
11362        String name = uri.getAuthority();
11363        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11364        ParcelFileDescriptor pfd = null;
11365        if (cph != null) {
11366            // We record the binder invoker's uid in thread-local storage before
11367            // going to the content provider to open the file.  Later, in the code
11368            // that handles all permissions checks, we look for this uid and use
11369            // that rather than the Activity Manager's own uid.  The effect is that
11370            // we do the check against the caller's permissions even though it looks
11371            // to the content provider like the Activity Manager itself is making
11372            // the request.
11373            Binder token = new Binder();
11374            sCallerIdentity.set(new Identity(
11375                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11376            try {
11377                pfd = cph.provider.openFile(null, uri, "r", null, token);
11378            } catch (FileNotFoundException e) {
11379                // do nothing; pfd will be returned null
11380            } finally {
11381                // Ensure that whatever happens, we clean up the identity state
11382                sCallerIdentity.remove();
11383                // Ensure we're done with the provider.
11384                removeContentProviderExternalUnchecked(name, null, userId);
11385            }
11386        } else {
11387            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11388        }
11389        return pfd;
11390    }
11391
11392    // Actually is sleeping or shutting down or whatever else in the future
11393    // is an inactive state.
11394    public boolean isSleepingOrShuttingDown() {
11395        return isSleeping() || mShuttingDown;
11396    }
11397
11398    public boolean isSleeping() {
11399        return mSleeping;
11400    }
11401
11402    void onWakefulnessChanged(int wakefulness) {
11403        synchronized(this) {
11404            mWakefulness = wakefulness;
11405            updateSleepIfNeededLocked();
11406        }
11407    }
11408
11409    void finishRunningVoiceLocked() {
11410        if (mRunningVoice != null) {
11411            mRunningVoice = null;
11412            mVoiceWakeLock.release();
11413            updateSleepIfNeededLocked();
11414        }
11415    }
11416
11417    void startTimeTrackingFocusedActivityLocked() {
11418        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11419            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11420        }
11421    }
11422
11423    void updateSleepIfNeededLocked() {
11424        if (mSleeping && !shouldSleepLocked()) {
11425            mSleeping = false;
11426            startTimeTrackingFocusedActivityLocked();
11427            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11428            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11429            updateOomAdjLocked();
11430        } else if (!mSleeping && shouldSleepLocked()) {
11431            mSleeping = true;
11432            if (mCurAppTimeTracker != null) {
11433                mCurAppTimeTracker.stop();
11434            }
11435            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11436            mStackSupervisor.goingToSleepLocked();
11437            updateOomAdjLocked();
11438
11439            // Initialize the wake times of all processes.
11440            checkExcessivePowerUsageLocked(false);
11441            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11442            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11443            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11444        }
11445    }
11446
11447    private boolean shouldSleepLocked() {
11448        // Resume applications while running a voice interactor.
11449        if (mRunningVoice != null) {
11450            return false;
11451        }
11452
11453        // TODO: Transform the lock screen state into a sleep token instead.
11454        switch (mWakefulness) {
11455            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11456            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11457            case PowerManagerInternal.WAKEFULNESS_DOZING:
11458                // Pause applications whenever the lock screen is shown or any sleep
11459                // tokens have been acquired.
11460                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11461            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11462            default:
11463                // If we're asleep then pause applications unconditionally.
11464                return true;
11465        }
11466    }
11467
11468    /** Pokes the task persister. */
11469    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11470        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11471    }
11472
11473    /** Notifies all listeners when the task stack has changed. */
11474    void notifyTaskStackChangedLocked() {
11475        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11476        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11477        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11478        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11479    }
11480
11481    /** Notifies all listeners when an Activity is pinned. */
11482    void notifyActivityPinnedLocked() {
11483        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11484        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11485    }
11486
11487    /**
11488     * Notifies all listeners when an attempt was made to start an an activity that is already
11489     * running in the pinned stack and the activity was not actually started, but the task is
11490     * either brought to the front or a new Intent is delivered to it.
11491     */
11492    void notifyPinnedActivityRestartAttemptLocked() {
11493        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11494        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11495    }
11496
11497    /** Notifies all listeners when the pinned stack animation ends. */
11498    @Override
11499    public void notifyPinnedStackAnimationEnded() {
11500        synchronized (this) {
11501            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11502            mHandler.obtainMessage(
11503                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11504        }
11505    }
11506
11507    @Override
11508    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11509        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11510    }
11511
11512    @Override
11513    public boolean shutdown(int timeout) {
11514        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11515                != PackageManager.PERMISSION_GRANTED) {
11516            throw new SecurityException("Requires permission "
11517                    + android.Manifest.permission.SHUTDOWN);
11518        }
11519
11520        boolean timedout = false;
11521
11522        synchronized(this) {
11523            mShuttingDown = true;
11524            updateEventDispatchingLocked();
11525            timedout = mStackSupervisor.shutdownLocked(timeout);
11526        }
11527
11528        mAppOpsService.shutdown();
11529        if (mUsageStatsService != null) {
11530            mUsageStatsService.prepareShutdown();
11531        }
11532        mBatteryStatsService.shutdown();
11533        synchronized (this) {
11534            mProcessStats.shutdownLocked();
11535            notifyTaskPersisterLocked(null, true);
11536        }
11537
11538        return timedout;
11539    }
11540
11541    public final void activitySlept(IBinder token) {
11542        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11543
11544        final long origId = Binder.clearCallingIdentity();
11545
11546        synchronized (this) {
11547            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11548            if (r != null) {
11549                mStackSupervisor.activitySleptLocked(r);
11550            }
11551        }
11552
11553        Binder.restoreCallingIdentity(origId);
11554    }
11555
11556    private String lockScreenShownToString() {
11557        switch (mLockScreenShown) {
11558            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11559            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11560            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11561            default: return "Unknown=" + mLockScreenShown;
11562        }
11563    }
11564
11565    void logLockScreen(String msg) {
11566        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11567                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11568                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11569                + " mSleeping=" + mSleeping);
11570    }
11571
11572    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11573        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11574        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11575        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11576            boolean wasRunningVoice = mRunningVoice != null;
11577            mRunningVoice = session;
11578            if (!wasRunningVoice) {
11579                mVoiceWakeLock.acquire();
11580                updateSleepIfNeededLocked();
11581            }
11582        }
11583    }
11584
11585    private void updateEventDispatchingLocked() {
11586        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11587    }
11588
11589    public void setLockScreenShown(boolean showing, boolean occluded) {
11590        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11591                != PackageManager.PERMISSION_GRANTED) {
11592            throw new SecurityException("Requires permission "
11593                    + android.Manifest.permission.DEVICE_POWER);
11594        }
11595
11596        synchronized(this) {
11597            long ident = Binder.clearCallingIdentity();
11598            try {
11599                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11600                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11601                if (showing && occluded) {
11602                    // The lock screen is currently showing, but is occluded by a window that can
11603                    // show on top of the lock screen. In this can we want to dismiss the docked
11604                    // stack since it will be complicated/risky to try to put the activity on top
11605                    // of the lock screen in the right fullscreen configuration.
11606                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11607                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11608                }
11609
11610                updateSleepIfNeededLocked();
11611            } finally {
11612                Binder.restoreCallingIdentity(ident);
11613            }
11614        }
11615    }
11616
11617    @Override
11618    public void notifyLockedProfile(@UserIdInt int userId) {
11619        try {
11620            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11621                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11622            }
11623        } catch (RemoteException ex) {
11624            throw new SecurityException("Fail to check is caller a privileged app", ex);
11625        }
11626
11627        synchronized (this) {
11628            if (mStackSupervisor.isUserLockedProfile(userId)) {
11629                final long ident = Binder.clearCallingIdentity();
11630                try {
11631                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11632                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11633                        // If there is no device lock, we will show the profile's credential page.
11634                        mActivityStarter.showConfirmDeviceCredential(userId);
11635                    } else {
11636                        // Showing launcher to avoid user entering credential twice.
11637                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11638                    }
11639                } finally {
11640                    Binder.restoreCallingIdentity(ident);
11641                }
11642            }
11643        }
11644    }
11645
11646    @Override
11647    public void startConfirmDeviceCredentialIntent(Intent intent) {
11648        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11649        synchronized (this) {
11650            final long ident = Binder.clearCallingIdentity();
11651            try {
11652                mActivityStarter.startConfirmCredentialIntent(intent);
11653            } finally {
11654                Binder.restoreCallingIdentity(ident);
11655            }
11656        }
11657    }
11658
11659    @Override
11660    public void stopAppSwitches() {
11661        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11662                != PackageManager.PERMISSION_GRANTED) {
11663            throw new SecurityException("viewquires permission "
11664                    + android.Manifest.permission.STOP_APP_SWITCHES);
11665        }
11666
11667        synchronized(this) {
11668            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11669                    + APP_SWITCH_DELAY_TIME;
11670            mDidAppSwitch = false;
11671            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11672            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11673            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11674        }
11675    }
11676
11677    public void resumeAppSwitches() {
11678        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11679                != PackageManager.PERMISSION_GRANTED) {
11680            throw new SecurityException("Requires permission "
11681                    + android.Manifest.permission.STOP_APP_SWITCHES);
11682        }
11683
11684        synchronized(this) {
11685            // Note that we don't execute any pending app switches... we will
11686            // let those wait until either the timeout, or the next start
11687            // activity request.
11688            mAppSwitchesAllowedTime = 0;
11689        }
11690    }
11691
11692    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11693            int callingPid, int callingUid, String name) {
11694        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11695            return true;
11696        }
11697
11698        int perm = checkComponentPermission(
11699                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11700                sourceUid, -1, true);
11701        if (perm == PackageManager.PERMISSION_GRANTED) {
11702            return true;
11703        }
11704
11705        // If the actual IPC caller is different from the logical source, then
11706        // also see if they are allowed to control app switches.
11707        if (callingUid != -1 && callingUid != sourceUid) {
11708            perm = checkComponentPermission(
11709                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11710                    callingUid, -1, true);
11711            if (perm == PackageManager.PERMISSION_GRANTED) {
11712                return true;
11713            }
11714        }
11715
11716        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11717        return false;
11718    }
11719
11720    public void setDebugApp(String packageName, boolean waitForDebugger,
11721            boolean persistent) {
11722        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11723                "setDebugApp()");
11724
11725        long ident = Binder.clearCallingIdentity();
11726        try {
11727            // Note that this is not really thread safe if there are multiple
11728            // callers into it at the same time, but that's not a situation we
11729            // care about.
11730            if (persistent) {
11731                final ContentResolver resolver = mContext.getContentResolver();
11732                Settings.Global.putString(
11733                    resolver, Settings.Global.DEBUG_APP,
11734                    packageName);
11735                Settings.Global.putInt(
11736                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11737                    waitForDebugger ? 1 : 0);
11738            }
11739
11740            synchronized (this) {
11741                if (!persistent) {
11742                    mOrigDebugApp = mDebugApp;
11743                    mOrigWaitForDebugger = mWaitForDebugger;
11744                }
11745                mDebugApp = packageName;
11746                mWaitForDebugger = waitForDebugger;
11747                mDebugTransient = !persistent;
11748                if (packageName != null) {
11749                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11750                            false, UserHandle.USER_ALL, "set debug app");
11751                }
11752            }
11753        } finally {
11754            Binder.restoreCallingIdentity(ident);
11755        }
11756    }
11757
11758    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11759        synchronized (this) {
11760            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11761            if (!isDebuggable) {
11762                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11763                    throw new SecurityException("Process not debuggable: " + app.packageName);
11764                }
11765            }
11766
11767            mTrackAllocationApp = processName;
11768        }
11769    }
11770
11771    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11772        synchronized (this) {
11773            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11774            if (!isDebuggable) {
11775                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11776                    throw new SecurityException("Process not debuggable: " + app.packageName);
11777                }
11778            }
11779            mProfileApp = processName;
11780            mProfileFile = profilerInfo.profileFile;
11781            if (mProfileFd != null) {
11782                try {
11783                    mProfileFd.close();
11784                } catch (IOException e) {
11785                }
11786                mProfileFd = null;
11787            }
11788            mProfileFd = profilerInfo.profileFd;
11789            mSamplingInterval = profilerInfo.samplingInterval;
11790            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11791            mProfileType = 0;
11792        }
11793    }
11794
11795    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11796        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11797        if (!isDebuggable) {
11798            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11799                throw new SecurityException("Process not debuggable: " + app.packageName);
11800            }
11801        }
11802        mNativeDebuggingApp = processName;
11803    }
11804
11805    @Override
11806    public void setAlwaysFinish(boolean enabled) {
11807        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11808                "setAlwaysFinish()");
11809
11810        long ident = Binder.clearCallingIdentity();
11811        try {
11812            Settings.Global.putInt(
11813                    mContext.getContentResolver(),
11814                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11815
11816            synchronized (this) {
11817                mAlwaysFinishActivities = enabled;
11818            }
11819        } finally {
11820            Binder.restoreCallingIdentity(ident);
11821        }
11822    }
11823
11824    @Override
11825    public void setLenientBackgroundCheck(boolean enabled) {
11826        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11827                "setLenientBackgroundCheck()");
11828
11829        long ident = Binder.clearCallingIdentity();
11830        try {
11831            Settings.Global.putInt(
11832                    mContext.getContentResolver(),
11833                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11834
11835            synchronized (this) {
11836                mLenientBackgroundCheck = enabled;
11837            }
11838        } finally {
11839            Binder.restoreCallingIdentity(ident);
11840        }
11841    }
11842
11843    @Override
11844    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11845        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11846                "setActivityController()");
11847        synchronized (this) {
11848            mController = controller;
11849            mControllerIsAMonkey = imAMonkey;
11850            Watchdog.getInstance().setActivityController(controller);
11851        }
11852    }
11853
11854    @Override
11855    public void setUserIsMonkey(boolean userIsMonkey) {
11856        synchronized (this) {
11857            synchronized (mPidsSelfLocked) {
11858                final int callingPid = Binder.getCallingPid();
11859                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11860                if (precessRecord == null) {
11861                    throw new SecurityException("Unknown process: " + callingPid);
11862                }
11863                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11864                    throw new SecurityException("Only an instrumentation process "
11865                            + "with a UiAutomation can call setUserIsMonkey");
11866                }
11867            }
11868            mUserIsMonkey = userIsMonkey;
11869        }
11870    }
11871
11872    @Override
11873    public boolean isUserAMonkey() {
11874        synchronized (this) {
11875            // If there is a controller also implies the user is a monkey.
11876            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11877        }
11878    }
11879
11880    public void requestBugReport(int bugreportType) {
11881        String service = null;
11882        switch (bugreportType) {
11883            case ActivityManager.BUGREPORT_OPTION_FULL:
11884                service = "bugreport";
11885                break;
11886            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11887                service = "bugreportplus";
11888                break;
11889            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11890                service = "bugreportremote";
11891                break;
11892        }
11893        if (service == null) {
11894            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11895                    + bugreportType);
11896        }
11897        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11898        SystemProperties.set("ctl.start", service);
11899    }
11900
11901    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11902        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11903    }
11904
11905    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11906        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11907            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11908        }
11909        return KEY_DISPATCHING_TIMEOUT;
11910    }
11911
11912    @Override
11913    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11914        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11915                != PackageManager.PERMISSION_GRANTED) {
11916            throw new SecurityException("Requires permission "
11917                    + android.Manifest.permission.FILTER_EVENTS);
11918        }
11919        ProcessRecord proc;
11920        long timeout;
11921        synchronized (this) {
11922            synchronized (mPidsSelfLocked) {
11923                proc = mPidsSelfLocked.get(pid);
11924            }
11925            timeout = getInputDispatchingTimeoutLocked(proc);
11926        }
11927
11928        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11929            return -1;
11930        }
11931
11932        return timeout;
11933    }
11934
11935    /**
11936     * Handle input dispatching timeouts.
11937     * Returns whether input dispatching should be aborted or not.
11938     */
11939    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11940            final ActivityRecord activity, final ActivityRecord parent,
11941            final boolean aboveSystem, String reason) {
11942        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11943                != PackageManager.PERMISSION_GRANTED) {
11944            throw new SecurityException("Requires permission "
11945                    + android.Manifest.permission.FILTER_EVENTS);
11946        }
11947
11948        final String annotation;
11949        if (reason == null) {
11950            annotation = "Input dispatching timed out";
11951        } else {
11952            annotation = "Input dispatching timed out (" + reason + ")";
11953        }
11954
11955        if (proc != null) {
11956            synchronized (this) {
11957                if (proc.debugging) {
11958                    return false;
11959                }
11960
11961                if (mDidDexOpt) {
11962                    // Give more time since we were dexopting.
11963                    mDidDexOpt = false;
11964                    return false;
11965                }
11966
11967                if (proc.instrumentationClass != null) {
11968                    Bundle info = new Bundle();
11969                    info.putString("shortMsg", "keyDispatchingTimedOut");
11970                    info.putString("longMsg", annotation);
11971                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11972                    return true;
11973                }
11974            }
11975            mHandler.post(new Runnable() {
11976                @Override
11977                public void run() {
11978                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11979                }
11980            });
11981        }
11982
11983        return true;
11984    }
11985
11986    @Override
11987    public Bundle getAssistContextExtras(int requestType) {
11988        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11989                null, null, true /* focused */, true /* newSessionId */,
11990                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11991        if (pae == null) {
11992            return null;
11993        }
11994        synchronized (pae) {
11995            while (!pae.haveResult) {
11996                try {
11997                    pae.wait();
11998                } catch (InterruptedException e) {
11999                }
12000            }
12001        }
12002        synchronized (this) {
12003            buildAssistBundleLocked(pae, pae.result);
12004            mPendingAssistExtras.remove(pae);
12005            mUiHandler.removeCallbacks(pae);
12006        }
12007        return pae.extras;
12008    }
12009
12010    @Override
12011    public boolean isAssistDataAllowedOnCurrentActivity() {
12012        int userId;
12013        synchronized (this) {
12014            userId = mUserController.getCurrentUserIdLocked();
12015            ActivityRecord activity = getFocusedStack().topActivity();
12016            if (activity == null) {
12017                return false;
12018            }
12019            userId = activity.userId;
12020        }
12021        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12022                Context.DEVICE_POLICY_SERVICE);
12023        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12024    }
12025
12026    @Override
12027    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12028        long ident = Binder.clearCallingIdentity();
12029        try {
12030            synchronized (this) {
12031                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12032                ActivityRecord top = getFocusedStack().topActivity();
12033                if (top != caller) {
12034                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12035                            + " is not current top " + top);
12036                    return false;
12037                }
12038                if (!top.nowVisible) {
12039                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12040                            + " is not visible");
12041                    return false;
12042                }
12043            }
12044            AssistUtils utils = new AssistUtils(mContext);
12045            return utils.showSessionForActiveService(args,
12046                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12047        } finally {
12048            Binder.restoreCallingIdentity(ident);
12049        }
12050    }
12051
12052    @Override
12053    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12054            Bundle receiverExtras,
12055            IBinder activityToken, boolean focused, boolean newSessionId) {
12056        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12057                activityToken, focused, newSessionId,
12058                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12059                != null;
12060    }
12061
12062    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12063            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12064            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12065        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12066                "enqueueAssistContext()");
12067        synchronized (this) {
12068            ActivityRecord activity = getFocusedStack().topActivity();
12069            if (activity == null) {
12070                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12071                return null;
12072            }
12073            if (activity.app == null || activity.app.thread == null) {
12074                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12075                return null;
12076            }
12077            if (focused) {
12078                if (activityToken != null) {
12079                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12080                    if (activity != caller) {
12081                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12082                                + " is not current top " + activity);
12083                        return null;
12084                    }
12085                }
12086            } else {
12087                activity = ActivityRecord.forTokenLocked(activityToken);
12088                if (activity == null) {
12089                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12090                            + " couldn't be found");
12091                    return null;
12092                }
12093            }
12094
12095            PendingAssistExtras pae;
12096            Bundle extras = new Bundle();
12097            if (args != null) {
12098                extras.putAll(args);
12099            }
12100            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12101            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12102            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12103                    userHandle);
12104            // Increment the sessionId if necessary
12105            if (newSessionId) {
12106                mViSessionId++;
12107            }
12108            try {
12109                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12110                        requestType, mViSessionId);
12111                mPendingAssistExtras.add(pae);
12112                mUiHandler.postDelayed(pae, timeout);
12113            } catch (RemoteException e) {
12114                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12115                return null;
12116            }
12117            return pae;
12118        }
12119    }
12120
12121    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12122        IResultReceiver receiver;
12123        synchronized (this) {
12124            mPendingAssistExtras.remove(pae);
12125            receiver = pae.receiver;
12126        }
12127        if (receiver != null) {
12128            // Caller wants result sent back to them.
12129            Bundle sendBundle = new Bundle();
12130            // At least return the receiver extras
12131            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12132                    pae.receiverExtras);
12133            try {
12134                pae.receiver.send(0, sendBundle);
12135            } catch (RemoteException e) {
12136            }
12137        }
12138    }
12139
12140    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12141        if (result != null) {
12142            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12143        }
12144        if (pae.hint != null) {
12145            pae.extras.putBoolean(pae.hint, true);
12146        }
12147    }
12148
12149    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12150            AssistContent content, Uri referrer) {
12151        PendingAssistExtras pae = (PendingAssistExtras)token;
12152        synchronized (pae) {
12153            pae.result = extras;
12154            pae.structure = structure;
12155            pae.content = content;
12156            if (referrer != null) {
12157                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12158            }
12159            pae.haveResult = true;
12160            pae.notifyAll();
12161            if (pae.intent == null && pae.receiver == null) {
12162                // Caller is just waiting for the result.
12163                return;
12164            }
12165        }
12166
12167        // We are now ready to launch the assist activity.
12168        IResultReceiver sendReceiver = null;
12169        Bundle sendBundle = null;
12170        synchronized (this) {
12171            buildAssistBundleLocked(pae, extras);
12172            boolean exists = mPendingAssistExtras.remove(pae);
12173            mUiHandler.removeCallbacks(pae);
12174            if (!exists) {
12175                // Timed out.
12176                return;
12177            }
12178            if ((sendReceiver=pae.receiver) != null) {
12179                // Caller wants result sent back to them.
12180                sendBundle = new Bundle();
12181                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12182                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12183                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12184                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12185                        pae.receiverExtras);
12186            }
12187        }
12188        if (sendReceiver != null) {
12189            try {
12190                sendReceiver.send(0, sendBundle);
12191            } catch (RemoteException e) {
12192            }
12193            return;
12194        }
12195
12196        long ident = Binder.clearCallingIdentity();
12197        try {
12198            pae.intent.replaceExtras(pae.extras);
12199            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12200                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12201                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12202            closeSystemDialogs("assist");
12203            try {
12204                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12205            } catch (ActivityNotFoundException e) {
12206                Slog.w(TAG, "No activity to handle assist action.", e);
12207            }
12208        } finally {
12209            Binder.restoreCallingIdentity(ident);
12210        }
12211    }
12212
12213    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12214            Bundle args) {
12215        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12216                true /* focused */, true /* newSessionId */,
12217                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12218    }
12219
12220    public void registerProcessObserver(IProcessObserver observer) {
12221        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12222                "registerProcessObserver()");
12223        synchronized (this) {
12224            mProcessObservers.register(observer);
12225        }
12226    }
12227
12228    @Override
12229    public void unregisterProcessObserver(IProcessObserver observer) {
12230        synchronized (this) {
12231            mProcessObservers.unregister(observer);
12232        }
12233    }
12234
12235    @Override
12236    public void registerUidObserver(IUidObserver observer, int which) {
12237        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12238                "registerUidObserver()");
12239        synchronized (this) {
12240            mUidObservers.register(observer, which);
12241        }
12242    }
12243
12244    @Override
12245    public void unregisterUidObserver(IUidObserver observer) {
12246        synchronized (this) {
12247            mUidObservers.unregister(observer);
12248        }
12249    }
12250
12251    @Override
12252    public boolean convertFromTranslucent(IBinder token) {
12253        final long origId = Binder.clearCallingIdentity();
12254        try {
12255            synchronized (this) {
12256                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12257                if (r == null) {
12258                    return false;
12259                }
12260                final boolean translucentChanged = r.changeWindowTranslucency(true);
12261                if (translucentChanged) {
12262                    r.task.stack.releaseBackgroundResources(r);
12263                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12264                }
12265                mWindowManager.setAppFullscreen(token, true);
12266                return translucentChanged;
12267            }
12268        } finally {
12269            Binder.restoreCallingIdentity(origId);
12270        }
12271    }
12272
12273    @Override
12274    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12275        final long origId = Binder.clearCallingIdentity();
12276        try {
12277            synchronized (this) {
12278                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12279                if (r == null) {
12280                    return false;
12281                }
12282                int index = r.task.mActivities.lastIndexOf(r);
12283                if (index > 0) {
12284                    ActivityRecord under = r.task.mActivities.get(index - 1);
12285                    under.returningOptions = options;
12286                }
12287                final boolean translucentChanged = r.changeWindowTranslucency(false);
12288                if (translucentChanged) {
12289                    r.task.stack.convertActivityToTranslucent(r);
12290                }
12291                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12292                mWindowManager.setAppFullscreen(token, false);
12293                return translucentChanged;
12294            }
12295        } finally {
12296            Binder.restoreCallingIdentity(origId);
12297        }
12298    }
12299
12300    @Override
12301    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12302        final long origId = Binder.clearCallingIdentity();
12303        try {
12304            synchronized (this) {
12305                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12306                if (r != null) {
12307                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12308                }
12309            }
12310            return false;
12311        } finally {
12312            Binder.restoreCallingIdentity(origId);
12313        }
12314    }
12315
12316    @Override
12317    public boolean isBackgroundVisibleBehind(IBinder token) {
12318        final long origId = Binder.clearCallingIdentity();
12319        try {
12320            synchronized (this) {
12321                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12322                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12323                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12324                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12325                return visible;
12326            }
12327        } finally {
12328            Binder.restoreCallingIdentity(origId);
12329        }
12330    }
12331
12332    @Override
12333    public ActivityOptions getActivityOptions(IBinder token) {
12334        final long origId = Binder.clearCallingIdentity();
12335        try {
12336            synchronized (this) {
12337                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12338                if (r != null) {
12339                    final ActivityOptions activityOptions = r.pendingOptions;
12340                    r.pendingOptions = null;
12341                    return activityOptions;
12342                }
12343                return null;
12344            }
12345        } finally {
12346            Binder.restoreCallingIdentity(origId);
12347        }
12348    }
12349
12350    @Override
12351    public void setImmersive(IBinder token, boolean immersive) {
12352        synchronized(this) {
12353            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12354            if (r == null) {
12355                throw new IllegalArgumentException();
12356            }
12357            r.immersive = immersive;
12358
12359            // update associated state if we're frontmost
12360            if (r == mFocusedActivity) {
12361                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12362                applyUpdateLockStateLocked(r);
12363            }
12364        }
12365    }
12366
12367    @Override
12368    public boolean isImmersive(IBinder token) {
12369        synchronized (this) {
12370            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12371            if (r == null) {
12372                throw new IllegalArgumentException();
12373            }
12374            return r.immersive;
12375        }
12376    }
12377
12378    @Override
12379    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12380        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12381            throw new UnsupportedOperationException("VR mode not supported on this device!");
12382        }
12383
12384        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12385
12386        ActivityRecord r;
12387        synchronized (this) {
12388            r = ActivityRecord.isInStackLocked(token);
12389        }
12390
12391        if (r == null) {
12392            throw new IllegalArgumentException();
12393        }
12394
12395        int err;
12396        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12397                VrManagerInternal.NO_ERROR) {
12398            return err;
12399        }
12400
12401        synchronized(this) {
12402            r.requestedVrComponent = (enabled) ? packageName : null;
12403
12404            // Update associated state if this activity is currently focused
12405            if (r == mFocusedActivity) {
12406                applyUpdateVrModeLocked(r);
12407            }
12408            return 0;
12409        }
12410    }
12411
12412    @Override
12413    public boolean isVrModePackageEnabled(ComponentName packageName) {
12414        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12415            throw new UnsupportedOperationException("VR mode not supported on this device!");
12416        }
12417
12418        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12419
12420        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12421                VrManagerInternal.NO_ERROR;
12422    }
12423
12424    public boolean isTopActivityImmersive() {
12425        enforceNotIsolatedCaller("startActivity");
12426        synchronized (this) {
12427            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12428            return (r != null) ? r.immersive : false;
12429        }
12430    }
12431
12432    @Override
12433    public boolean isTopOfTask(IBinder token) {
12434        synchronized (this) {
12435            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12436            if (r == null) {
12437                throw new IllegalArgumentException();
12438            }
12439            return r.task.getTopActivity() == r;
12440        }
12441    }
12442
12443    public final void enterSafeMode() {
12444        synchronized(this) {
12445            // It only makes sense to do this before the system is ready
12446            // and started launching other packages.
12447            if (!mSystemReady) {
12448                try {
12449                    AppGlobals.getPackageManager().enterSafeMode();
12450                } catch (RemoteException e) {
12451                }
12452            }
12453
12454            mSafeMode = true;
12455        }
12456    }
12457
12458    public final void showSafeModeOverlay() {
12459        View v = LayoutInflater.from(mContext).inflate(
12460                com.android.internal.R.layout.safe_mode, null);
12461        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12462        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12463        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12464        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12465        lp.gravity = Gravity.BOTTOM | Gravity.START;
12466        lp.format = v.getBackground().getOpacity();
12467        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12468                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12469        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12470        ((WindowManager)mContext.getSystemService(
12471                Context.WINDOW_SERVICE)).addView(v, lp);
12472    }
12473
12474    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12475        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12476            return;
12477        }
12478        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12479        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12480        synchronized (stats) {
12481            if (mBatteryStatsService.isOnBattery()) {
12482                mBatteryStatsService.enforceCallingPermission();
12483                int MY_UID = Binder.getCallingUid();
12484                final int uid;
12485                if (sender == null) {
12486                    uid = sourceUid;
12487                } else {
12488                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12489                }
12490                BatteryStatsImpl.Uid.Pkg pkg =
12491                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12492                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12493                pkg.noteWakeupAlarmLocked(tag);
12494            }
12495        }
12496    }
12497
12498    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12499        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12500            return;
12501        }
12502        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12503        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12504        synchronized (stats) {
12505            mBatteryStatsService.enforceCallingPermission();
12506            int MY_UID = Binder.getCallingUid();
12507            final int uid;
12508            if (sender == null) {
12509                uid = sourceUid;
12510            } else {
12511                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12512            }
12513            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12514        }
12515    }
12516
12517    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12518        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12519            return;
12520        }
12521        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12522        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12523        synchronized (stats) {
12524            mBatteryStatsService.enforceCallingPermission();
12525            int MY_UID = Binder.getCallingUid();
12526            final int uid;
12527            if (sender == null) {
12528                uid = sourceUid;
12529            } else {
12530                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12531            }
12532            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12533        }
12534    }
12535
12536    public boolean killPids(int[] pids, String pReason, boolean secure) {
12537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12538            throw new SecurityException("killPids only available to the system");
12539        }
12540        String reason = (pReason == null) ? "Unknown" : pReason;
12541        // XXX Note: don't acquire main activity lock here, because the window
12542        // manager calls in with its locks held.
12543
12544        boolean killed = false;
12545        synchronized (mPidsSelfLocked) {
12546            int worstType = 0;
12547            for (int i=0; i<pids.length; i++) {
12548                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12549                if (proc != null) {
12550                    int type = proc.setAdj;
12551                    if (type > worstType) {
12552                        worstType = type;
12553                    }
12554                }
12555            }
12556
12557            // If the worst oom_adj is somewhere in the cached proc LRU range,
12558            // then constrain it so we will kill all cached procs.
12559            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12560                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12561                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12562            }
12563
12564            // If this is not a secure call, don't let it kill processes that
12565            // are important.
12566            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12567                worstType = ProcessList.SERVICE_ADJ;
12568            }
12569
12570            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12571            for (int i=0; i<pids.length; i++) {
12572                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12573                if (proc == null) {
12574                    continue;
12575                }
12576                int adj = proc.setAdj;
12577                if (adj >= worstType && !proc.killedByAm) {
12578                    proc.kill(reason, true);
12579                    killed = true;
12580                }
12581            }
12582        }
12583        return killed;
12584    }
12585
12586    @Override
12587    public void killUid(int appId, int userId, String reason) {
12588        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12589        synchronized (this) {
12590            final long identity = Binder.clearCallingIdentity();
12591            try {
12592                killPackageProcessesLocked(null, appId, userId,
12593                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12594                        reason != null ? reason : "kill uid");
12595            } finally {
12596                Binder.restoreCallingIdentity(identity);
12597            }
12598        }
12599    }
12600
12601    @Override
12602    public boolean killProcessesBelowForeground(String reason) {
12603        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12604            throw new SecurityException("killProcessesBelowForeground() only available to system");
12605        }
12606
12607        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12608    }
12609
12610    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12611        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12612            throw new SecurityException("killProcessesBelowAdj() only available to system");
12613        }
12614
12615        boolean killed = false;
12616        synchronized (mPidsSelfLocked) {
12617            final int size = mPidsSelfLocked.size();
12618            for (int i = 0; i < size; i++) {
12619                final int pid = mPidsSelfLocked.keyAt(i);
12620                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12621                if (proc == null) continue;
12622
12623                final int adj = proc.setAdj;
12624                if (adj > belowAdj && !proc.killedByAm) {
12625                    proc.kill(reason, true);
12626                    killed = true;
12627                }
12628            }
12629        }
12630        return killed;
12631    }
12632
12633    @Override
12634    public void hang(final IBinder who, boolean allowRestart) {
12635        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12636                != PackageManager.PERMISSION_GRANTED) {
12637            throw new SecurityException("Requires permission "
12638                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12639        }
12640
12641        final IBinder.DeathRecipient death = new DeathRecipient() {
12642            @Override
12643            public void binderDied() {
12644                synchronized (this) {
12645                    notifyAll();
12646                }
12647            }
12648        };
12649
12650        try {
12651            who.linkToDeath(death, 0);
12652        } catch (RemoteException e) {
12653            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12654            return;
12655        }
12656
12657        synchronized (this) {
12658            Watchdog.getInstance().setAllowRestart(allowRestart);
12659            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12660            synchronized (death) {
12661                while (who.isBinderAlive()) {
12662                    try {
12663                        death.wait();
12664                    } catch (InterruptedException e) {
12665                    }
12666                }
12667            }
12668            Watchdog.getInstance().setAllowRestart(true);
12669        }
12670    }
12671
12672    @Override
12673    public void restart() {
12674        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12675                != PackageManager.PERMISSION_GRANTED) {
12676            throw new SecurityException("Requires permission "
12677                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12678        }
12679
12680        Log.i(TAG, "Sending shutdown broadcast...");
12681
12682        BroadcastReceiver br = new BroadcastReceiver() {
12683            @Override public void onReceive(Context context, Intent intent) {
12684                // Now the broadcast is done, finish up the low-level shutdown.
12685                Log.i(TAG, "Shutting down activity manager...");
12686                shutdown(10000);
12687                Log.i(TAG, "Shutdown complete, restarting!");
12688                Process.killProcess(Process.myPid());
12689                System.exit(10);
12690            }
12691        };
12692
12693        // First send the high-level shut down broadcast.
12694        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12695        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12696        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12697        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12698        mContext.sendOrderedBroadcastAsUser(intent,
12699                UserHandle.ALL, null, br, mHandler, 0, null, null);
12700        */
12701        br.onReceive(mContext, intent);
12702    }
12703
12704    private long getLowRamTimeSinceIdle(long now) {
12705        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12706    }
12707
12708    @Override
12709    public void performIdleMaintenance() {
12710        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12711                != PackageManager.PERMISSION_GRANTED) {
12712            throw new SecurityException("Requires permission "
12713                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12714        }
12715
12716        synchronized (this) {
12717            final long now = SystemClock.uptimeMillis();
12718            final long timeSinceLastIdle = now - mLastIdleTime;
12719            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12720            mLastIdleTime = now;
12721            mLowRamTimeSinceLastIdle = 0;
12722            if (mLowRamStartTime != 0) {
12723                mLowRamStartTime = now;
12724            }
12725
12726            StringBuilder sb = new StringBuilder(128);
12727            sb.append("Idle maintenance over ");
12728            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12729            sb.append(" low RAM for ");
12730            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12731            Slog.i(TAG, sb.toString());
12732
12733            // If at least 1/3 of our time since the last idle period has been spent
12734            // with RAM low, then we want to kill processes.
12735            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12736
12737            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12738                ProcessRecord proc = mLruProcesses.get(i);
12739                if (proc.notCachedSinceIdle) {
12740                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12741                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12742                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12743                        if (doKilling && proc.initialIdlePss != 0
12744                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12745                            sb = new StringBuilder(128);
12746                            sb.append("Kill");
12747                            sb.append(proc.processName);
12748                            sb.append(" in idle maint: pss=");
12749                            sb.append(proc.lastPss);
12750                            sb.append(", swapPss=");
12751                            sb.append(proc.lastSwapPss);
12752                            sb.append(", initialPss=");
12753                            sb.append(proc.initialIdlePss);
12754                            sb.append(", period=");
12755                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12756                            sb.append(", lowRamPeriod=");
12757                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12758                            Slog.wtfQuiet(TAG, sb.toString());
12759                            proc.kill("idle maint (pss " + proc.lastPss
12760                                    + " from " + proc.initialIdlePss + ")", true);
12761                        }
12762                    }
12763                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12764                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12765                    proc.notCachedSinceIdle = true;
12766                    proc.initialIdlePss = 0;
12767                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12768                            mTestPssMode, isSleeping(), now);
12769                }
12770            }
12771
12772            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12773            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12774        }
12775    }
12776
12777    @Override
12778    public void sendIdleJobTrigger() {
12779        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12780                != PackageManager.PERMISSION_GRANTED) {
12781            throw new SecurityException("Requires permission "
12782                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12783        }
12784
12785        final long ident = Binder.clearCallingIdentity();
12786        try {
12787            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12788                    .setPackage("android")
12789                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12790            broadcastIntent(null, intent, null, null, 0, null, null, null,
12791                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12792        } finally {
12793            Binder.restoreCallingIdentity(ident);
12794        }
12795    }
12796
12797    private void retrieveSettings() {
12798        final ContentResolver resolver = mContext.getContentResolver();
12799        final boolean freeformWindowManagement =
12800                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12801                        || Settings.Global.getInt(
12802                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12803        final boolean supportsPictureInPicture =
12804                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12805
12806        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12807        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12808        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12809        final boolean alwaysFinishActivities =
12810                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12811        final boolean lenientBackgroundCheck =
12812                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12813        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12814        final boolean forceResizable = Settings.Global.getInt(
12815                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12816        // Transfer any global setting for forcing RTL layout, into a System Property
12817        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12818
12819        final Configuration configuration = new Configuration();
12820        Settings.System.getConfiguration(resolver, configuration);
12821        if (forceRtl) {
12822            // This will take care of setting the correct layout direction flags
12823            configuration.setLayoutDirection(configuration.locale);
12824        }
12825
12826        synchronized (this) {
12827            mDebugApp = mOrigDebugApp = debugApp;
12828            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12829            mAlwaysFinishActivities = alwaysFinishActivities;
12830            mLenientBackgroundCheck = lenientBackgroundCheck;
12831            mForceResizableActivities = forceResizable;
12832            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12833            if (supportsMultiWindow || forceResizable) {
12834                mSupportsMultiWindow = true;
12835                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12836                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12837            } else {
12838                mSupportsMultiWindow = false;
12839                mSupportsFreeformWindowManagement = false;
12840                mSupportsPictureInPicture = false;
12841            }
12842            // This happens before any activities are started, so we can
12843            // change mConfiguration in-place.
12844            updateConfigurationLocked(configuration, null, true);
12845            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12846                    "Initial config: " + mConfiguration);
12847
12848            // Load resources only after the current configuration has been set.
12849            final Resources res = mContext.getResources();
12850            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12851            mThumbnailWidth = res.getDimensionPixelSize(
12852                    com.android.internal.R.dimen.thumbnail_width);
12853            mThumbnailHeight = res.getDimensionPixelSize(
12854                    com.android.internal.R.dimen.thumbnail_height);
12855            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12856                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12857            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12858                    com.android.internal.R.string.config_appsNotReportingCrashes));
12859            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12860                mFullscreenThumbnailScale = (float) res
12861                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12862                    (float) mConfiguration.screenWidthDp;
12863            } else {
12864                mFullscreenThumbnailScale = res.getFraction(
12865                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12866            }
12867        }
12868    }
12869
12870    public boolean testIsSystemReady() {
12871        // no need to synchronize(this) just to read & return the value
12872        return mSystemReady;
12873    }
12874
12875    public void systemReady(final Runnable goingCallback) {
12876        synchronized(this) {
12877            if (mSystemReady) {
12878                // If we're done calling all the receivers, run the next "boot phase" passed in
12879                // by the SystemServer
12880                if (goingCallback != null) {
12881                    goingCallback.run();
12882                }
12883                return;
12884            }
12885
12886            mLocalDeviceIdleController
12887                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12888
12889            // Make sure we have the current profile info, since it is needed for security checks.
12890            mUserController.onSystemReady();
12891            mRecentTasks.onSystemReadyLocked();
12892            mAppOpsService.systemReady();
12893            mSystemReady = true;
12894        }
12895
12896        ArrayList<ProcessRecord> procsToKill = null;
12897        synchronized(mPidsSelfLocked) {
12898            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12899                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12900                if (!isAllowedWhileBooting(proc.info)){
12901                    if (procsToKill == null) {
12902                        procsToKill = new ArrayList<ProcessRecord>();
12903                    }
12904                    procsToKill.add(proc);
12905                }
12906            }
12907        }
12908
12909        synchronized(this) {
12910            if (procsToKill != null) {
12911                for (int i=procsToKill.size()-1; i>=0; i--) {
12912                    ProcessRecord proc = procsToKill.get(i);
12913                    Slog.i(TAG, "Removing system update proc: " + proc);
12914                    removeProcessLocked(proc, true, false, "system update done");
12915                }
12916            }
12917
12918            // Now that we have cleaned up any update processes, we
12919            // are ready to start launching real processes and know that
12920            // we won't trample on them any more.
12921            mProcessesReady = true;
12922        }
12923
12924        Slog.i(TAG, "System now ready");
12925        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12926            SystemClock.uptimeMillis());
12927
12928        synchronized(this) {
12929            // Make sure we have no pre-ready processes sitting around.
12930
12931            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12932                ResolveInfo ri = mContext.getPackageManager()
12933                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12934                                STOCK_PM_FLAGS);
12935                CharSequence errorMsg = null;
12936                if (ri != null) {
12937                    ActivityInfo ai = ri.activityInfo;
12938                    ApplicationInfo app = ai.applicationInfo;
12939                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12940                        mTopAction = Intent.ACTION_FACTORY_TEST;
12941                        mTopData = null;
12942                        mTopComponent = new ComponentName(app.packageName,
12943                                ai.name);
12944                    } else {
12945                        errorMsg = mContext.getResources().getText(
12946                                com.android.internal.R.string.factorytest_not_system);
12947                    }
12948                } else {
12949                    errorMsg = mContext.getResources().getText(
12950                            com.android.internal.R.string.factorytest_no_action);
12951                }
12952                if (errorMsg != null) {
12953                    mTopAction = null;
12954                    mTopData = null;
12955                    mTopComponent = null;
12956                    Message msg = Message.obtain();
12957                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12958                    msg.getData().putCharSequence("msg", errorMsg);
12959                    mUiHandler.sendMessage(msg);
12960                }
12961            }
12962        }
12963
12964        retrieveSettings();
12965        final int currentUserId;
12966        synchronized (this) {
12967            currentUserId = mUserController.getCurrentUserIdLocked();
12968            readGrantedUriPermissionsLocked();
12969        }
12970
12971        if (goingCallback != null) goingCallback.run();
12972
12973        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12974                Integer.toString(currentUserId), currentUserId);
12975        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12976                Integer.toString(currentUserId), currentUserId);
12977        mSystemServiceManager.startUser(currentUserId);
12978
12979        synchronized (this) {
12980            // Only start up encryption-aware persistent apps; once user is
12981            // unlocked we'll come back around and start unaware apps
12982            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12983
12984            // Start up initial activity.
12985            mBooting = true;
12986            // Enable home activity for system user, so that the system can always boot
12987            if (UserManager.isSplitSystemUser()) {
12988                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12989                try {
12990                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12991                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12992                            UserHandle.USER_SYSTEM);
12993                } catch (RemoteException e) {
12994                    throw e.rethrowAsRuntimeException();
12995                }
12996            }
12997            startHomeActivityLocked(currentUserId, "systemReady");
12998
12999            try {
13000                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13001                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13002                            + " data partition or your device will be unstable.");
13003                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13004                }
13005            } catch (RemoteException e) {
13006            }
13007
13008            if (!Build.isBuildConsistent()) {
13009                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13010                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13011            }
13012
13013            long ident = Binder.clearCallingIdentity();
13014            try {
13015                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13016                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13017                        | Intent.FLAG_RECEIVER_FOREGROUND);
13018                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13019                broadcastIntentLocked(null, null, intent,
13020                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13021                        null, false, false, MY_PID, Process.SYSTEM_UID,
13022                        currentUserId);
13023                intent = new Intent(Intent.ACTION_USER_STARTING);
13024                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13025                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13026                broadcastIntentLocked(null, null, intent,
13027                        null, new IIntentReceiver.Stub() {
13028                            @Override
13029                            public void performReceive(Intent intent, int resultCode, String data,
13030                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13031                                    throws RemoteException {
13032                            }
13033                        }, 0, null, null,
13034                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13035                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13036            } catch (Throwable t) {
13037                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13038            } finally {
13039                Binder.restoreCallingIdentity(ident);
13040            }
13041            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13042            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13043        }
13044    }
13045
13046    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13047        synchronized (this) {
13048            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13049        }
13050    }
13051
13052    void skipCurrentReceiverLocked(ProcessRecord app) {
13053        for (BroadcastQueue queue : mBroadcastQueues) {
13054            queue.skipCurrentReceiverLocked(app);
13055        }
13056    }
13057
13058    /**
13059     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13060     * The application process will exit immediately after this call returns.
13061     * @param app object of the crashing app, null for the system server
13062     * @param crashInfo describing the exception
13063     */
13064    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13065        ProcessRecord r = findAppProcess(app, "Crash");
13066        final String processName = app == null ? "system_server"
13067                : (r == null ? "unknown" : r.processName);
13068
13069        handleApplicationCrashInner("crash", r, processName, crashInfo);
13070    }
13071
13072    /* Native crash reporting uses this inner version because it needs to be somewhat
13073     * decoupled from the AM-managed cleanup lifecycle
13074     */
13075    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13076            ApplicationErrorReport.CrashInfo crashInfo) {
13077        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13078                UserHandle.getUserId(Binder.getCallingUid()), processName,
13079                r == null ? -1 : r.info.flags,
13080                crashInfo.exceptionClassName,
13081                crashInfo.exceptionMessage,
13082                crashInfo.throwFileName,
13083                crashInfo.throwLineNumber);
13084
13085        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13086
13087        mAppErrors.crashApplication(r, crashInfo);
13088    }
13089
13090    public void handleApplicationStrictModeViolation(
13091            IBinder app,
13092            int violationMask,
13093            StrictMode.ViolationInfo info) {
13094        ProcessRecord r = findAppProcess(app, "StrictMode");
13095        if (r == null) {
13096            return;
13097        }
13098
13099        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13100            Integer stackFingerprint = info.hashCode();
13101            boolean logIt = true;
13102            synchronized (mAlreadyLoggedViolatedStacks) {
13103                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13104                    logIt = false;
13105                    // TODO: sub-sample into EventLog for these, with
13106                    // the info.durationMillis?  Then we'd get
13107                    // the relative pain numbers, without logging all
13108                    // the stack traces repeatedly.  We'd want to do
13109                    // likewise in the client code, which also does
13110                    // dup suppression, before the Binder call.
13111                } else {
13112                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13113                        mAlreadyLoggedViolatedStacks.clear();
13114                    }
13115                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13116                }
13117            }
13118            if (logIt) {
13119                logStrictModeViolationToDropBox(r, info);
13120            }
13121        }
13122
13123        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13124            AppErrorResult result = new AppErrorResult();
13125            synchronized (this) {
13126                final long origId = Binder.clearCallingIdentity();
13127
13128                Message msg = Message.obtain();
13129                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13130                HashMap<String, Object> data = new HashMap<String, Object>();
13131                data.put("result", result);
13132                data.put("app", r);
13133                data.put("violationMask", violationMask);
13134                data.put("info", info);
13135                msg.obj = data;
13136                mUiHandler.sendMessage(msg);
13137
13138                Binder.restoreCallingIdentity(origId);
13139            }
13140            int res = result.get();
13141            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13142        }
13143    }
13144
13145    // Depending on the policy in effect, there could be a bunch of
13146    // these in quick succession so we try to batch these together to
13147    // minimize disk writes, number of dropbox entries, and maximize
13148    // compression, by having more fewer, larger records.
13149    private void logStrictModeViolationToDropBox(
13150            ProcessRecord process,
13151            StrictMode.ViolationInfo info) {
13152        if (info == null) {
13153            return;
13154        }
13155        final boolean isSystemApp = process == null ||
13156                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13157                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13158        final String processName = process == null ? "unknown" : process.processName;
13159        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13160        final DropBoxManager dbox = (DropBoxManager)
13161                mContext.getSystemService(Context.DROPBOX_SERVICE);
13162
13163        // Exit early if the dropbox isn't configured to accept this report type.
13164        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13165
13166        boolean bufferWasEmpty;
13167        boolean needsFlush;
13168        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13169        synchronized (sb) {
13170            bufferWasEmpty = sb.length() == 0;
13171            appendDropBoxProcessHeaders(process, processName, sb);
13172            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13173            sb.append("System-App: ").append(isSystemApp).append("\n");
13174            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13175            if (info.violationNumThisLoop != 0) {
13176                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13177            }
13178            if (info.numAnimationsRunning != 0) {
13179                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13180            }
13181            if (info.broadcastIntentAction != null) {
13182                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13183            }
13184            if (info.durationMillis != -1) {
13185                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13186            }
13187            if (info.numInstances != -1) {
13188                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13189            }
13190            if (info.tags != null) {
13191                for (String tag : info.tags) {
13192                    sb.append("Span-Tag: ").append(tag).append("\n");
13193                }
13194            }
13195            sb.append("\n");
13196            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13197                sb.append(info.crashInfo.stackTrace);
13198                sb.append("\n");
13199            }
13200            if (info.message != null) {
13201                sb.append(info.message);
13202                sb.append("\n");
13203            }
13204
13205            // Only buffer up to ~64k.  Various logging bits truncate
13206            // things at 128k.
13207            needsFlush = (sb.length() > 64 * 1024);
13208        }
13209
13210        // Flush immediately if the buffer's grown too large, or this
13211        // is a non-system app.  Non-system apps are isolated with a
13212        // different tag & policy and not batched.
13213        //
13214        // Batching is useful during internal testing with
13215        // StrictMode settings turned up high.  Without batching,
13216        // thousands of separate files could be created on boot.
13217        if (!isSystemApp || needsFlush) {
13218            new Thread("Error dump: " + dropboxTag) {
13219                @Override
13220                public void run() {
13221                    String report;
13222                    synchronized (sb) {
13223                        report = sb.toString();
13224                        sb.delete(0, sb.length());
13225                        sb.trimToSize();
13226                    }
13227                    if (report.length() != 0) {
13228                        dbox.addText(dropboxTag, report);
13229                    }
13230                }
13231            }.start();
13232            return;
13233        }
13234
13235        // System app batching:
13236        if (!bufferWasEmpty) {
13237            // An existing dropbox-writing thread is outstanding, so
13238            // we don't need to start it up.  The existing thread will
13239            // catch the buffer appends we just did.
13240            return;
13241        }
13242
13243        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13244        // (After this point, we shouldn't access AMS internal data structures.)
13245        new Thread("Error dump: " + dropboxTag) {
13246            @Override
13247            public void run() {
13248                // 5 second sleep to let stacks arrive and be batched together
13249                try {
13250                    Thread.sleep(5000);  // 5 seconds
13251                } catch (InterruptedException e) {}
13252
13253                String errorReport;
13254                synchronized (mStrictModeBuffer) {
13255                    errorReport = mStrictModeBuffer.toString();
13256                    if (errorReport.length() == 0) {
13257                        return;
13258                    }
13259                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13260                    mStrictModeBuffer.trimToSize();
13261                }
13262                dbox.addText(dropboxTag, errorReport);
13263            }
13264        }.start();
13265    }
13266
13267    /**
13268     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13269     * @param app object of the crashing app, null for the system server
13270     * @param tag reported by the caller
13271     * @param system whether this wtf is coming from the system
13272     * @param crashInfo describing the context of the error
13273     * @return true if the process should exit immediately (WTF is fatal)
13274     */
13275    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13276            final ApplicationErrorReport.CrashInfo crashInfo) {
13277        final int callingUid = Binder.getCallingUid();
13278        final int callingPid = Binder.getCallingPid();
13279
13280        if (system) {
13281            // If this is coming from the system, we could very well have low-level
13282            // system locks held, so we want to do this all asynchronously.  And we
13283            // never want this to become fatal, so there is that too.
13284            mHandler.post(new Runnable() {
13285                @Override public void run() {
13286                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13287                }
13288            });
13289            return false;
13290        }
13291
13292        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13293                crashInfo);
13294
13295        if (r != null && r.pid != Process.myPid() &&
13296                Settings.Global.getInt(mContext.getContentResolver(),
13297                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13298            mAppErrors.crashApplication(r, crashInfo);
13299            return true;
13300        } else {
13301            return false;
13302        }
13303    }
13304
13305    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13306            final ApplicationErrorReport.CrashInfo crashInfo) {
13307        final ProcessRecord r = findAppProcess(app, "WTF");
13308        final String processName = app == null ? "system_server"
13309                : (r == null ? "unknown" : r.processName);
13310
13311        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13312                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13313
13314        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13315
13316        return r;
13317    }
13318
13319    /**
13320     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13321     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13322     */
13323    private ProcessRecord findAppProcess(IBinder app, String reason) {
13324        if (app == null) {
13325            return null;
13326        }
13327
13328        synchronized (this) {
13329            final int NP = mProcessNames.getMap().size();
13330            for (int ip=0; ip<NP; ip++) {
13331                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13332                final int NA = apps.size();
13333                for (int ia=0; ia<NA; ia++) {
13334                    ProcessRecord p = apps.valueAt(ia);
13335                    if (p.thread != null && p.thread.asBinder() == app) {
13336                        return p;
13337                    }
13338                }
13339            }
13340
13341            Slog.w(TAG, "Can't find mystery application for " + reason
13342                    + " from pid=" + Binder.getCallingPid()
13343                    + " uid=" + Binder.getCallingUid() + ": " + app);
13344            return null;
13345        }
13346    }
13347
13348    /**
13349     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13350     * to append various headers to the dropbox log text.
13351     */
13352    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13353            StringBuilder sb) {
13354        // Watchdog thread ends up invoking this function (with
13355        // a null ProcessRecord) to add the stack file to dropbox.
13356        // Do not acquire a lock on this (am) in such cases, as it
13357        // could cause a potential deadlock, if and when watchdog
13358        // is invoked due to unavailability of lock on am and it
13359        // would prevent watchdog from killing system_server.
13360        if (process == null) {
13361            sb.append("Process: ").append(processName).append("\n");
13362            return;
13363        }
13364        // Note: ProcessRecord 'process' is guarded by the service
13365        // instance.  (notably process.pkgList, which could otherwise change
13366        // concurrently during execution of this method)
13367        synchronized (this) {
13368            sb.append("Process: ").append(processName).append("\n");
13369            int flags = process.info.flags;
13370            IPackageManager pm = AppGlobals.getPackageManager();
13371            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13372            for (int ip=0; ip<process.pkgList.size(); ip++) {
13373                String pkg = process.pkgList.keyAt(ip);
13374                sb.append("Package: ").append(pkg);
13375                try {
13376                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13377                    if (pi != null) {
13378                        sb.append(" v").append(pi.versionCode);
13379                        if (pi.versionName != null) {
13380                            sb.append(" (").append(pi.versionName).append(")");
13381                        }
13382                    }
13383                } catch (RemoteException e) {
13384                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13385                }
13386                sb.append("\n");
13387            }
13388        }
13389    }
13390
13391    private static String processClass(ProcessRecord process) {
13392        if (process == null || process.pid == MY_PID) {
13393            return "system_server";
13394        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13395            return "system_app";
13396        } else {
13397            return "data_app";
13398        }
13399    }
13400
13401    private volatile long mWtfClusterStart;
13402    private volatile int mWtfClusterCount;
13403
13404    /**
13405     * Write a description of an error (crash, WTF, ANR) to the drop box.
13406     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13407     * @param process which caused the error, null means the system server
13408     * @param activity which triggered the error, null if unknown
13409     * @param parent activity related to the error, null if unknown
13410     * @param subject line related to the error, null if absent
13411     * @param report in long form describing the error, null if absent
13412     * @param logFile to include in the report, null if none
13413     * @param crashInfo giving an application stack trace, null if absent
13414     */
13415    public void addErrorToDropBox(String eventType,
13416            ProcessRecord process, String processName, ActivityRecord activity,
13417            ActivityRecord parent, String subject,
13418            final String report, final File logFile,
13419            final ApplicationErrorReport.CrashInfo crashInfo) {
13420        // NOTE -- this must never acquire the ActivityManagerService lock,
13421        // otherwise the watchdog may be prevented from resetting the system.
13422
13423        final String dropboxTag = processClass(process) + "_" + eventType;
13424        final DropBoxManager dbox = (DropBoxManager)
13425                mContext.getSystemService(Context.DROPBOX_SERVICE);
13426
13427        // Exit early if the dropbox isn't configured to accept this report type.
13428        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13429
13430        // Rate-limit how often we're willing to do the heavy lifting below to
13431        // collect and record logs; currently 5 logs per 10 second period.
13432        final long now = SystemClock.elapsedRealtime();
13433        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13434            mWtfClusterStart = now;
13435            mWtfClusterCount = 1;
13436        } else {
13437            if (mWtfClusterCount++ >= 5) return;
13438        }
13439
13440        final StringBuilder sb = new StringBuilder(1024);
13441        appendDropBoxProcessHeaders(process, processName, sb);
13442        if (process != null) {
13443            sb.append("Foreground: ")
13444                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13445                    .append("\n");
13446        }
13447        if (activity != null) {
13448            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13449        }
13450        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13451            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13452        }
13453        if (parent != null && parent != activity) {
13454            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13455        }
13456        if (subject != null) {
13457            sb.append("Subject: ").append(subject).append("\n");
13458        }
13459        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13460        if (Debug.isDebuggerConnected()) {
13461            sb.append("Debugger: Connected\n");
13462        }
13463        sb.append("\n");
13464
13465        // Do the rest in a worker thread to avoid blocking the caller on I/O
13466        // (After this point, we shouldn't access AMS internal data structures.)
13467        Thread worker = new Thread("Error dump: " + dropboxTag) {
13468            @Override
13469            public void run() {
13470                if (report != null) {
13471                    sb.append(report);
13472                }
13473                if (logFile != null) {
13474                    try {
13475                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13476                                    "\n\n[[TRUNCATED]]"));
13477                    } catch (IOException e) {
13478                        Slog.e(TAG, "Error reading " + logFile, e);
13479                    }
13480                }
13481                if (crashInfo != null && crashInfo.stackTrace != null) {
13482                    sb.append(crashInfo.stackTrace);
13483                }
13484
13485                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13486                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13487                if (lines > 0) {
13488                    sb.append("\n");
13489
13490                    // Merge several logcat streams, and take the last N lines
13491                    InputStreamReader input = null;
13492                    try {
13493                        java.lang.Process logcat = new ProcessBuilder(
13494                                "/system/bin/timeout", "-k", "15s", "10s",
13495                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13496                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13497                                        .redirectErrorStream(true).start();
13498
13499                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13500                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13501                        input = new InputStreamReader(logcat.getInputStream());
13502
13503                        int num;
13504                        char[] buf = new char[8192];
13505                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13506                    } catch (IOException e) {
13507                        Slog.e(TAG, "Error running logcat", e);
13508                    } finally {
13509                        if (input != null) try { input.close(); } catch (IOException e) {}
13510                    }
13511                }
13512
13513                dbox.addText(dropboxTag, sb.toString());
13514            }
13515        };
13516
13517        if (process == null) {
13518            // If process is null, we are being called from some internal code
13519            // and may be about to die -- run this synchronously.
13520            worker.run();
13521        } else {
13522            worker.start();
13523        }
13524    }
13525
13526    @Override
13527    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13528        enforceNotIsolatedCaller("getProcessesInErrorState");
13529        // assume our apps are happy - lazy create the list
13530        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13531
13532        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13533                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13534        int userId = UserHandle.getUserId(Binder.getCallingUid());
13535
13536        synchronized (this) {
13537
13538            // iterate across all processes
13539            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13540                ProcessRecord app = mLruProcesses.get(i);
13541                if (!allUsers && app.userId != userId) {
13542                    continue;
13543                }
13544                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13545                    // This one's in trouble, so we'll generate a report for it
13546                    // crashes are higher priority (in case there's a crash *and* an anr)
13547                    ActivityManager.ProcessErrorStateInfo report = null;
13548                    if (app.crashing) {
13549                        report = app.crashingReport;
13550                    } else if (app.notResponding) {
13551                        report = app.notRespondingReport;
13552                    }
13553
13554                    if (report != null) {
13555                        if (errList == null) {
13556                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13557                        }
13558                        errList.add(report);
13559                    } else {
13560                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13561                                " crashing = " + app.crashing +
13562                                " notResponding = " + app.notResponding);
13563                    }
13564                }
13565            }
13566        }
13567
13568        return errList;
13569    }
13570
13571    static int procStateToImportance(int procState, int memAdj,
13572            ActivityManager.RunningAppProcessInfo currApp) {
13573        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13574        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13575            currApp.lru = memAdj;
13576        } else {
13577            currApp.lru = 0;
13578        }
13579        return imp;
13580    }
13581
13582    private void fillInProcMemInfo(ProcessRecord app,
13583            ActivityManager.RunningAppProcessInfo outInfo) {
13584        outInfo.pid = app.pid;
13585        outInfo.uid = app.info.uid;
13586        if (mHeavyWeightProcess == app) {
13587            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13588        }
13589        if (app.persistent) {
13590            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13591        }
13592        if (app.activities.size() > 0) {
13593            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13594        }
13595        outInfo.lastTrimLevel = app.trimMemoryLevel;
13596        int adj = app.curAdj;
13597        int procState = app.curProcState;
13598        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13599        outInfo.importanceReasonCode = app.adjTypeCode;
13600        outInfo.processState = app.curProcState;
13601    }
13602
13603    @Override
13604    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13605        enforceNotIsolatedCaller("getRunningAppProcesses");
13606
13607        final int callingUid = Binder.getCallingUid();
13608
13609        // Lazy instantiation of list
13610        List<ActivityManager.RunningAppProcessInfo> runList = null;
13611        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13612                callingUid) == PackageManager.PERMISSION_GRANTED;
13613        final int userId = UserHandle.getUserId(callingUid);
13614        final boolean allUids = isGetTasksAllowed(
13615                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13616
13617        synchronized (this) {
13618            // Iterate across all processes
13619            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13620                ProcessRecord app = mLruProcesses.get(i);
13621                if ((!allUsers && app.userId != userId)
13622                        || (!allUids && app.uid != callingUid)) {
13623                    continue;
13624                }
13625                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13626                    // Generate process state info for running application
13627                    ActivityManager.RunningAppProcessInfo currApp =
13628                        new ActivityManager.RunningAppProcessInfo(app.processName,
13629                                app.pid, app.getPackageList());
13630                    fillInProcMemInfo(app, currApp);
13631                    if (app.adjSource instanceof ProcessRecord) {
13632                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13633                        currApp.importanceReasonImportance =
13634                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13635                                        app.adjSourceProcState);
13636                    } else if (app.adjSource instanceof ActivityRecord) {
13637                        ActivityRecord r = (ActivityRecord)app.adjSource;
13638                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13639                    }
13640                    if (app.adjTarget instanceof ComponentName) {
13641                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13642                    }
13643                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13644                    //        + " lru=" + currApp.lru);
13645                    if (runList == null) {
13646                        runList = new ArrayList<>();
13647                    }
13648                    runList.add(currApp);
13649                }
13650            }
13651        }
13652        return runList;
13653    }
13654
13655    @Override
13656    public List<ApplicationInfo> getRunningExternalApplications() {
13657        enforceNotIsolatedCaller("getRunningExternalApplications");
13658        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13659        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13660        if (runningApps != null && runningApps.size() > 0) {
13661            Set<String> extList = new HashSet<String>();
13662            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13663                if (app.pkgList != null) {
13664                    for (String pkg : app.pkgList) {
13665                        extList.add(pkg);
13666                    }
13667                }
13668            }
13669            IPackageManager pm = AppGlobals.getPackageManager();
13670            for (String pkg : extList) {
13671                try {
13672                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13673                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13674                        retList.add(info);
13675                    }
13676                } catch (RemoteException e) {
13677                }
13678            }
13679        }
13680        return retList;
13681    }
13682
13683    @Override
13684    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13685        enforceNotIsolatedCaller("getMyMemoryState");
13686        synchronized (this) {
13687            ProcessRecord proc;
13688            synchronized (mPidsSelfLocked) {
13689                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13690            }
13691            fillInProcMemInfo(proc, outInfo);
13692        }
13693    }
13694
13695    @Override
13696    public int getMemoryTrimLevel() {
13697        enforceNotIsolatedCaller("getMyMemoryState");
13698        synchronized (this) {
13699            return mLastMemoryLevel;
13700        }
13701    }
13702
13703    @Override
13704    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13705            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13706        (new ActivityManagerShellCommand(this, false)).exec(
13707                this, in, out, err, args, resultReceiver);
13708    }
13709
13710    @Override
13711    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13712        if (checkCallingPermission(android.Manifest.permission.DUMP)
13713                != PackageManager.PERMISSION_GRANTED) {
13714            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13715                    + Binder.getCallingPid()
13716                    + ", uid=" + Binder.getCallingUid()
13717                    + " without permission "
13718                    + android.Manifest.permission.DUMP);
13719            return;
13720        }
13721
13722        boolean dumpAll = false;
13723        boolean dumpClient = false;
13724        String dumpPackage = null;
13725
13726        int opti = 0;
13727        while (opti < args.length) {
13728            String opt = args[opti];
13729            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13730                break;
13731            }
13732            opti++;
13733            if ("-a".equals(opt)) {
13734                dumpAll = true;
13735            } else if ("-c".equals(opt)) {
13736                dumpClient = true;
13737            } else if ("-p".equals(opt)) {
13738                if (opti < args.length) {
13739                    dumpPackage = args[opti];
13740                    opti++;
13741                } else {
13742                    pw.println("Error: -p option requires package argument");
13743                    return;
13744                }
13745                dumpClient = true;
13746            } else if ("-h".equals(opt)) {
13747                ActivityManagerShellCommand.dumpHelp(pw, true);
13748                return;
13749            } else {
13750                pw.println("Unknown argument: " + opt + "; use -h for help");
13751            }
13752        }
13753
13754        long origId = Binder.clearCallingIdentity();
13755        boolean more = false;
13756        // Is the caller requesting to dump a particular piece of data?
13757        if (opti < args.length) {
13758            String cmd = args[opti];
13759            opti++;
13760            if ("activities".equals(cmd) || "a".equals(cmd)) {
13761                synchronized (this) {
13762                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13763                }
13764            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13765                synchronized (this) {
13766                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13767                }
13768            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13769                String[] newArgs;
13770                String name;
13771                if (opti >= args.length) {
13772                    name = null;
13773                    newArgs = EMPTY_STRING_ARRAY;
13774                } else {
13775                    dumpPackage = args[opti];
13776                    opti++;
13777                    newArgs = new String[args.length - opti];
13778                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13779                            args.length - opti);
13780                }
13781                synchronized (this) {
13782                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13783                }
13784            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13785                String[] newArgs;
13786                String name;
13787                if (opti >= args.length) {
13788                    name = null;
13789                    newArgs = EMPTY_STRING_ARRAY;
13790                } else {
13791                    dumpPackage = args[opti];
13792                    opti++;
13793                    newArgs = new String[args.length - opti];
13794                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13795                            args.length - opti);
13796                }
13797                synchronized (this) {
13798                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13799                }
13800            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13801                String[] newArgs;
13802                String name;
13803                if (opti >= args.length) {
13804                    name = null;
13805                    newArgs = EMPTY_STRING_ARRAY;
13806                } else {
13807                    dumpPackage = args[opti];
13808                    opti++;
13809                    newArgs = new String[args.length - opti];
13810                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13811                            args.length - opti);
13812                }
13813                synchronized (this) {
13814                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13815                }
13816            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13817                synchronized (this) {
13818                    dumpOomLocked(fd, pw, args, opti, true);
13819                }
13820            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13821                synchronized (this) {
13822                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13823                }
13824            } else if ("provider".equals(cmd)) {
13825                String[] newArgs;
13826                String name;
13827                if (opti >= args.length) {
13828                    name = null;
13829                    newArgs = EMPTY_STRING_ARRAY;
13830                } else {
13831                    name = args[opti];
13832                    opti++;
13833                    newArgs = new String[args.length - opti];
13834                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13835                }
13836                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13837                    pw.println("No providers match: " + name);
13838                    pw.println("Use -h for help.");
13839                }
13840            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13841                synchronized (this) {
13842                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13843                }
13844            } else if ("service".equals(cmd)) {
13845                String[] newArgs;
13846                String name;
13847                if (opti >= args.length) {
13848                    name = null;
13849                    newArgs = EMPTY_STRING_ARRAY;
13850                } else {
13851                    name = args[opti];
13852                    opti++;
13853                    newArgs = new String[args.length - opti];
13854                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13855                            args.length - opti);
13856                }
13857                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13858                    pw.println("No services match: " + name);
13859                    pw.println("Use -h for help.");
13860                }
13861            } else if ("package".equals(cmd)) {
13862                String[] newArgs;
13863                if (opti >= args.length) {
13864                    pw.println("package: no package name specified");
13865                    pw.println("Use -h for help.");
13866                } else {
13867                    dumpPackage = args[opti];
13868                    opti++;
13869                    newArgs = new String[args.length - opti];
13870                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13871                            args.length - opti);
13872                    args = newArgs;
13873                    opti = 0;
13874                    more = true;
13875                }
13876            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13877                synchronized (this) {
13878                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13879                }
13880            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13881                if (dumpClient) {
13882                    ActiveServices.ServiceDumper dumper;
13883                    synchronized (this) {
13884                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13885                                dumpPackage);
13886                    }
13887                    dumper.dumpWithClient();
13888                } else {
13889                    synchronized (this) {
13890                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13891                                dumpPackage).dumpLocked();
13892                    }
13893                }
13894            } else if ("locks".equals(cmd)) {
13895                LockGuard.dump(fd, pw, args);
13896            } else {
13897                // Dumping a single activity?
13898                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13899                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13900                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13901                    if (res < 0) {
13902                        pw.println("Bad activity command, or no activities match: " + cmd);
13903                        pw.println("Use -h for help.");
13904                    }
13905                }
13906            }
13907            if (!more) {
13908                Binder.restoreCallingIdentity(origId);
13909                return;
13910            }
13911        }
13912
13913        // No piece of data specified, dump everything.
13914        if (dumpClient) {
13915            ActiveServices.ServiceDumper sdumper;
13916            synchronized (this) {
13917                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13918                pw.println();
13919                if (dumpAll) {
13920                    pw.println("-------------------------------------------------------------------------------");
13921                }
13922                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13923                pw.println();
13924                if (dumpAll) {
13925                    pw.println("-------------------------------------------------------------------------------");
13926                }
13927                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13928                pw.println();
13929                if (dumpAll) {
13930                    pw.println("-------------------------------------------------------------------------------");
13931                }
13932                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13933                pw.println();
13934                if (dumpAll) {
13935                    pw.println("-------------------------------------------------------------------------------");
13936                }
13937                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13938                        dumpPackage);
13939            }
13940            sdumper.dumpWithClient();
13941            pw.println();
13942            synchronized (this) {
13943                if (dumpAll) {
13944                    pw.println("-------------------------------------------------------------------------------");
13945                }
13946                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13947                pw.println();
13948                if (dumpAll) {
13949                    pw.println("-------------------------------------------------------------------------------");
13950                }
13951                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13952                if (mAssociations.size() > 0) {
13953                    pw.println();
13954                    if (dumpAll) {
13955                        pw.println("-------------------------------------------------------------------------------");
13956                    }
13957                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13958                }
13959                pw.println();
13960                if (dumpAll) {
13961                    pw.println("-------------------------------------------------------------------------------");
13962                }
13963                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13964            }
13965
13966        } else {
13967            synchronized (this) {
13968                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13969                pw.println();
13970                if (dumpAll) {
13971                    pw.println("-------------------------------------------------------------------------------");
13972                }
13973                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13974                pw.println();
13975                if (dumpAll) {
13976                    pw.println("-------------------------------------------------------------------------------");
13977                }
13978                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13979                pw.println();
13980                if (dumpAll) {
13981                    pw.println("-------------------------------------------------------------------------------");
13982                }
13983                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13984                pw.println();
13985                if (dumpAll) {
13986                    pw.println("-------------------------------------------------------------------------------");
13987                }
13988                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13989                        .dumpLocked();
13990                pw.println();
13991                if (dumpAll) {
13992                    pw.println("-------------------------------------------------------------------------------");
13993                }
13994                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13995                pw.println();
13996                if (dumpAll) {
13997                    pw.println("-------------------------------------------------------------------------------");
13998                }
13999                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14000                if (mAssociations.size() > 0) {
14001                    pw.println();
14002                    if (dumpAll) {
14003                        pw.println("-------------------------------------------------------------------------------");
14004                    }
14005                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14006                }
14007                pw.println();
14008                if (dumpAll) {
14009                    pw.println("-------------------------------------------------------------------------------");
14010                }
14011                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14012            }
14013        }
14014        Binder.restoreCallingIdentity(origId);
14015    }
14016
14017    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14018            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14019        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14020
14021        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14022                dumpPackage);
14023        boolean needSep = printedAnything;
14024
14025        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14026                dumpPackage, needSep, "  mFocusedActivity: ");
14027        if (printed) {
14028            printedAnything = true;
14029            needSep = false;
14030        }
14031
14032        if (dumpPackage == null) {
14033            if (needSep) {
14034                pw.println();
14035            }
14036            needSep = true;
14037            printedAnything = true;
14038            mStackSupervisor.dump(pw, "  ");
14039        }
14040
14041        if (!printedAnything) {
14042            pw.println("  (nothing)");
14043        }
14044    }
14045
14046    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14047            int opti, boolean dumpAll, String dumpPackage) {
14048        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14049
14050        boolean printedAnything = false;
14051
14052        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14053            boolean printedHeader = false;
14054
14055            final int N = mRecentTasks.size();
14056            for (int i=0; i<N; i++) {
14057                TaskRecord tr = mRecentTasks.get(i);
14058                if (dumpPackage != null) {
14059                    if (tr.realActivity == null ||
14060                            !dumpPackage.equals(tr.realActivity)) {
14061                        continue;
14062                    }
14063                }
14064                if (!printedHeader) {
14065                    pw.println("  Recent tasks:");
14066                    printedHeader = true;
14067                    printedAnything = true;
14068                }
14069                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14070                        pw.println(tr);
14071                if (dumpAll) {
14072                    mRecentTasks.get(i).dump(pw, "    ");
14073                }
14074            }
14075        }
14076
14077        if (!printedAnything) {
14078            pw.println("  (nothing)");
14079        }
14080    }
14081
14082    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14083            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14084        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14085
14086        int dumpUid = 0;
14087        if (dumpPackage != null) {
14088            IPackageManager pm = AppGlobals.getPackageManager();
14089            try {
14090                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14091            } catch (RemoteException e) {
14092            }
14093        }
14094
14095        boolean printedAnything = false;
14096
14097        final long now = SystemClock.uptimeMillis();
14098
14099        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14100            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14101                    = mAssociations.valueAt(i1);
14102            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14103                SparseArray<ArrayMap<String, Association>> sourceUids
14104                        = targetComponents.valueAt(i2);
14105                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14106                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14107                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14108                        Association ass = sourceProcesses.valueAt(i4);
14109                        if (dumpPackage != null) {
14110                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14111                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14112                                continue;
14113                            }
14114                        }
14115                        printedAnything = true;
14116                        pw.print("  ");
14117                        pw.print(ass.mTargetProcess);
14118                        pw.print("/");
14119                        UserHandle.formatUid(pw, ass.mTargetUid);
14120                        pw.print(" <- ");
14121                        pw.print(ass.mSourceProcess);
14122                        pw.print("/");
14123                        UserHandle.formatUid(pw, ass.mSourceUid);
14124                        pw.println();
14125                        pw.print("    via ");
14126                        pw.print(ass.mTargetComponent.flattenToShortString());
14127                        pw.println();
14128                        pw.print("    ");
14129                        long dur = ass.mTime;
14130                        if (ass.mNesting > 0) {
14131                            dur += now - ass.mStartTime;
14132                        }
14133                        TimeUtils.formatDuration(dur, pw);
14134                        pw.print(" (");
14135                        pw.print(ass.mCount);
14136                        pw.print(" times)");
14137                        pw.print("  ");
14138                        for (int i=0; i<ass.mStateTimes.length; i++) {
14139                            long amt = ass.mStateTimes[i];
14140                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14141                                amt += now - ass.mLastStateUptime;
14142                            }
14143                            if (amt != 0) {
14144                                pw.print(" ");
14145                                pw.print(ProcessList.makeProcStateString(
14146                                            i + ActivityManager.MIN_PROCESS_STATE));
14147                                pw.print("=");
14148                                TimeUtils.formatDuration(amt, pw);
14149                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14150                                    pw.print("*");
14151                                }
14152                            }
14153                        }
14154                        pw.println();
14155                        if (ass.mNesting > 0) {
14156                            pw.print("    Currently active: ");
14157                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14158                            pw.println();
14159                        }
14160                    }
14161                }
14162            }
14163
14164        }
14165
14166        if (!printedAnything) {
14167            pw.println("  (nothing)");
14168        }
14169    }
14170
14171    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14172            String header, boolean needSep) {
14173        boolean printed = false;
14174        int whichAppId = -1;
14175        if (dumpPackage != null) {
14176            try {
14177                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14178                        dumpPackage, 0);
14179                whichAppId = UserHandle.getAppId(info.uid);
14180            } catch (NameNotFoundException e) {
14181                e.printStackTrace();
14182            }
14183        }
14184        for (int i=0; i<uids.size(); i++) {
14185            UidRecord uidRec = uids.valueAt(i);
14186            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14187                continue;
14188            }
14189            if (!printed) {
14190                printed = true;
14191                if (needSep) {
14192                    pw.println();
14193                }
14194                pw.print("  ");
14195                pw.println(header);
14196                needSep = true;
14197            }
14198            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14199            pw.print(": "); pw.println(uidRec);
14200        }
14201        return printed;
14202    }
14203
14204    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14205            int opti, boolean dumpAll, String dumpPackage) {
14206        boolean needSep = false;
14207        boolean printedAnything = false;
14208        int numPers = 0;
14209
14210        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14211
14212        if (dumpAll) {
14213            final int NP = mProcessNames.getMap().size();
14214            for (int ip=0; ip<NP; ip++) {
14215                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14216                final int NA = procs.size();
14217                for (int ia=0; ia<NA; ia++) {
14218                    ProcessRecord r = procs.valueAt(ia);
14219                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14220                        continue;
14221                    }
14222                    if (!needSep) {
14223                        pw.println("  All known processes:");
14224                        needSep = true;
14225                        printedAnything = true;
14226                    }
14227                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14228                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14229                        pw.print(" "); pw.println(r);
14230                    r.dump(pw, "    ");
14231                    if (r.persistent) {
14232                        numPers++;
14233                    }
14234                }
14235            }
14236        }
14237
14238        if (mIsolatedProcesses.size() > 0) {
14239            boolean printed = false;
14240            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14241                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14242                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14243                    continue;
14244                }
14245                if (!printed) {
14246                    if (needSep) {
14247                        pw.println();
14248                    }
14249                    pw.println("  Isolated process list (sorted by uid):");
14250                    printedAnything = true;
14251                    printed = true;
14252                    needSep = true;
14253                }
14254                pw.println(String.format("%sIsolated #%2d: %s",
14255                        "    ", i, r.toString()));
14256            }
14257        }
14258
14259        if (mActiveUids.size() > 0) {
14260            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14261                printedAnything = needSep = true;
14262            }
14263        }
14264        if (mValidateUids.size() > 0) {
14265            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14266                printedAnything = needSep = true;
14267            }
14268        }
14269
14270        if (mLruProcesses.size() > 0) {
14271            if (needSep) {
14272                pw.println();
14273            }
14274            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14275                    pw.print(" total, non-act at ");
14276                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14277                    pw.print(", non-svc at ");
14278                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14279                    pw.println("):");
14280            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14281            needSep = true;
14282            printedAnything = true;
14283        }
14284
14285        if (dumpAll || dumpPackage != null) {
14286            synchronized (mPidsSelfLocked) {
14287                boolean printed = false;
14288                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14289                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14290                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14291                        continue;
14292                    }
14293                    if (!printed) {
14294                        if (needSep) pw.println();
14295                        needSep = true;
14296                        pw.println("  PID mappings:");
14297                        printed = true;
14298                        printedAnything = true;
14299                    }
14300                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14301                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14302                }
14303            }
14304        }
14305
14306        if (mForegroundProcesses.size() > 0) {
14307            synchronized (mPidsSelfLocked) {
14308                boolean printed = false;
14309                for (int i=0; i<mForegroundProcesses.size(); i++) {
14310                    ProcessRecord r = mPidsSelfLocked.get(
14311                            mForegroundProcesses.valueAt(i).pid);
14312                    if (dumpPackage != null && (r == null
14313                            || !r.pkgList.containsKey(dumpPackage))) {
14314                        continue;
14315                    }
14316                    if (!printed) {
14317                        if (needSep) pw.println();
14318                        needSep = true;
14319                        pw.println("  Foreground Processes:");
14320                        printed = true;
14321                        printedAnything = true;
14322                    }
14323                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14324                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14325                }
14326            }
14327        }
14328
14329        if (mPersistentStartingProcesses.size() > 0) {
14330            if (needSep) pw.println();
14331            needSep = true;
14332            printedAnything = true;
14333            pw.println("  Persisent processes that are starting:");
14334            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14335                    "Starting Norm", "Restarting PERS", dumpPackage);
14336        }
14337
14338        if (mRemovedProcesses.size() > 0) {
14339            if (needSep) pw.println();
14340            needSep = true;
14341            printedAnything = true;
14342            pw.println("  Processes that are being removed:");
14343            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14344                    "Removed Norm", "Removed PERS", dumpPackage);
14345        }
14346
14347        if (mProcessesOnHold.size() > 0) {
14348            if (needSep) pw.println();
14349            needSep = true;
14350            printedAnything = true;
14351            pw.println("  Processes that are on old until the system is ready:");
14352            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14353                    "OnHold Norm", "OnHold PERS", dumpPackage);
14354        }
14355
14356        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14357
14358        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14359        if (needSep) {
14360            printedAnything = true;
14361        }
14362
14363        if (dumpPackage == null) {
14364            pw.println();
14365            needSep = false;
14366            mUserController.dump(pw, dumpAll);
14367        }
14368        if (mHomeProcess != null && (dumpPackage == null
14369                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14370            if (needSep) {
14371                pw.println();
14372                needSep = false;
14373            }
14374            pw.println("  mHomeProcess: " + mHomeProcess);
14375        }
14376        if (mPreviousProcess != null && (dumpPackage == null
14377                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14378            if (needSep) {
14379                pw.println();
14380                needSep = false;
14381            }
14382            pw.println("  mPreviousProcess: " + mPreviousProcess);
14383        }
14384        if (dumpAll) {
14385            StringBuilder sb = new StringBuilder(128);
14386            sb.append("  mPreviousProcessVisibleTime: ");
14387            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14388            pw.println(sb);
14389        }
14390        if (mHeavyWeightProcess != null && (dumpPackage == null
14391                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14392            if (needSep) {
14393                pw.println();
14394                needSep = false;
14395            }
14396            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14397        }
14398        if (dumpPackage == null) {
14399            pw.println("  mConfiguration: " + mConfiguration);
14400        }
14401        if (dumpAll) {
14402            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14403            if (mCompatModePackages.getPackages().size() > 0) {
14404                boolean printed = false;
14405                for (Map.Entry<String, Integer> entry
14406                        : mCompatModePackages.getPackages().entrySet()) {
14407                    String pkg = entry.getKey();
14408                    int mode = entry.getValue();
14409                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14410                        continue;
14411                    }
14412                    if (!printed) {
14413                        pw.println("  mScreenCompatPackages:");
14414                        printed = true;
14415                    }
14416                    pw.print("    "); pw.print(pkg); pw.print(": ");
14417                            pw.print(mode); pw.println();
14418                }
14419            }
14420        }
14421        if (dumpPackage == null) {
14422            pw.println("  mWakefulness="
14423                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14424            pw.println("  mSleepTokens=" + mSleepTokens);
14425            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14426                    + lockScreenShownToString());
14427            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14428            if (mRunningVoice != null) {
14429                pw.println("  mRunningVoice=" + mRunningVoice);
14430                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14431            }
14432        }
14433        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14434                || mOrigWaitForDebugger) {
14435            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14436                    || dumpPackage.equals(mOrigDebugApp)) {
14437                if (needSep) {
14438                    pw.println();
14439                    needSep = false;
14440                }
14441                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14442                        + " mDebugTransient=" + mDebugTransient
14443                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14444            }
14445        }
14446        if (mCurAppTimeTracker != null) {
14447            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14448        }
14449        if (mMemWatchProcesses.getMap().size() > 0) {
14450            pw.println("  Mem watch processes:");
14451            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14452                    = mMemWatchProcesses.getMap();
14453            for (int i=0; i<procs.size(); i++) {
14454                final String proc = procs.keyAt(i);
14455                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14456                for (int j=0; j<uids.size(); j++) {
14457                    if (needSep) {
14458                        pw.println();
14459                        needSep = false;
14460                    }
14461                    StringBuilder sb = new StringBuilder();
14462                    sb.append("    ").append(proc).append('/');
14463                    UserHandle.formatUid(sb, uids.keyAt(j));
14464                    Pair<Long, String> val = uids.valueAt(j);
14465                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14466                    if (val.second != null) {
14467                        sb.append(", report to ").append(val.second);
14468                    }
14469                    pw.println(sb.toString());
14470                }
14471            }
14472            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14473            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14474            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14475                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14476        }
14477        if (mTrackAllocationApp != null) {
14478            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14479                if (needSep) {
14480                    pw.println();
14481                    needSep = false;
14482                }
14483                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14484            }
14485        }
14486        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14487                || mProfileFd != null) {
14488            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14489                if (needSep) {
14490                    pw.println();
14491                    needSep = false;
14492                }
14493                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14494                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14495                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14496                        + mAutoStopProfiler);
14497                pw.println("  mProfileType=" + mProfileType);
14498            }
14499        }
14500        if (mNativeDebuggingApp != null) {
14501            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14502                if (needSep) {
14503                    pw.println();
14504                    needSep = false;
14505                }
14506                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14507            }
14508        }
14509        if (dumpPackage == null) {
14510            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14511                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14512                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14513            }
14514            if (mController != null) {
14515                pw.println("  mController=" + mController
14516                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14517            }
14518            if (dumpAll) {
14519                pw.println("  Total persistent processes: " + numPers);
14520                pw.println("  mProcessesReady=" + mProcessesReady
14521                        + " mSystemReady=" + mSystemReady
14522                        + " mBooted=" + mBooted
14523                        + " mFactoryTest=" + mFactoryTest);
14524                pw.println("  mBooting=" + mBooting
14525                        + " mCallFinishBooting=" + mCallFinishBooting
14526                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14527                pw.print("  mLastPowerCheckRealtime=");
14528                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14529                        pw.println("");
14530                pw.print("  mLastPowerCheckUptime=");
14531                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14532                        pw.println("");
14533                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14534                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14535                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14536                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14537                        + " (" + mLruProcesses.size() + " total)"
14538                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14539                        + " mNumServiceProcs=" + mNumServiceProcs
14540                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14541                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14542                        + " mLastMemoryLevel=" + mLastMemoryLevel
14543                        + " mLastNumProcesses=" + mLastNumProcesses);
14544                long now = SystemClock.uptimeMillis();
14545                pw.print("  mLastIdleTime=");
14546                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14547                        pw.print(" mLowRamSinceLastIdle=");
14548                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14549                        pw.println();
14550            }
14551        }
14552
14553        if (!printedAnything) {
14554            pw.println("  (nothing)");
14555        }
14556    }
14557
14558    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14559            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14560        if (mProcessesToGc.size() > 0) {
14561            boolean printed = false;
14562            long now = SystemClock.uptimeMillis();
14563            for (int i=0; i<mProcessesToGc.size(); i++) {
14564                ProcessRecord proc = mProcessesToGc.get(i);
14565                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14566                    continue;
14567                }
14568                if (!printed) {
14569                    if (needSep) pw.println();
14570                    needSep = true;
14571                    pw.println("  Processes that are waiting to GC:");
14572                    printed = true;
14573                }
14574                pw.print("    Process "); pw.println(proc);
14575                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14576                        pw.print(", last gced=");
14577                        pw.print(now-proc.lastRequestedGc);
14578                        pw.print(" ms ago, last lowMem=");
14579                        pw.print(now-proc.lastLowMemory);
14580                        pw.println(" ms ago");
14581
14582            }
14583        }
14584        return needSep;
14585    }
14586
14587    void printOomLevel(PrintWriter pw, String name, int adj) {
14588        pw.print("    ");
14589        if (adj >= 0) {
14590            pw.print(' ');
14591            if (adj < 10) pw.print(' ');
14592        } else {
14593            if (adj > -10) pw.print(' ');
14594        }
14595        pw.print(adj);
14596        pw.print(": ");
14597        pw.print(name);
14598        pw.print(" (");
14599        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14600        pw.println(")");
14601    }
14602
14603    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14604            int opti, boolean dumpAll) {
14605        boolean needSep = false;
14606
14607        if (mLruProcesses.size() > 0) {
14608            if (needSep) pw.println();
14609            needSep = true;
14610            pw.println("  OOM levels:");
14611            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14612            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14613            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14614            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14615            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14616            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14617            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14618            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14619            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14620            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14621            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14622            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14623            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14624            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14625
14626            if (needSep) pw.println();
14627            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14628                    pw.print(" total, non-act at ");
14629                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14630                    pw.print(", non-svc at ");
14631                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14632                    pw.println("):");
14633            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14634            needSep = true;
14635        }
14636
14637        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14638
14639        pw.println();
14640        pw.println("  mHomeProcess: " + mHomeProcess);
14641        pw.println("  mPreviousProcess: " + mPreviousProcess);
14642        if (mHeavyWeightProcess != null) {
14643            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14644        }
14645
14646        return true;
14647    }
14648
14649    /**
14650     * There are three ways to call this:
14651     *  - no provider specified: dump all the providers
14652     *  - a flattened component name that matched an existing provider was specified as the
14653     *    first arg: dump that one provider
14654     *  - the first arg isn't the flattened component name of an existing provider:
14655     *    dump all providers whose component contains the first arg as a substring
14656     */
14657    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14658            int opti, boolean dumpAll) {
14659        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14660    }
14661
14662    static class ItemMatcher {
14663        ArrayList<ComponentName> components;
14664        ArrayList<String> strings;
14665        ArrayList<Integer> objects;
14666        boolean all;
14667
14668        ItemMatcher() {
14669            all = true;
14670        }
14671
14672        void build(String name) {
14673            ComponentName componentName = ComponentName.unflattenFromString(name);
14674            if (componentName != null) {
14675                if (components == null) {
14676                    components = new ArrayList<ComponentName>();
14677                }
14678                components.add(componentName);
14679                all = false;
14680            } else {
14681                int objectId = 0;
14682                // Not a '/' separated full component name; maybe an object ID?
14683                try {
14684                    objectId = Integer.parseInt(name, 16);
14685                    if (objects == null) {
14686                        objects = new ArrayList<Integer>();
14687                    }
14688                    objects.add(objectId);
14689                    all = false;
14690                } catch (RuntimeException e) {
14691                    // Not an integer; just do string match.
14692                    if (strings == null) {
14693                        strings = new ArrayList<String>();
14694                    }
14695                    strings.add(name);
14696                    all = false;
14697                }
14698            }
14699        }
14700
14701        int build(String[] args, int opti) {
14702            for (; opti<args.length; opti++) {
14703                String name = args[opti];
14704                if ("--".equals(name)) {
14705                    return opti+1;
14706                }
14707                build(name);
14708            }
14709            return opti;
14710        }
14711
14712        boolean match(Object object, ComponentName comp) {
14713            if (all) {
14714                return true;
14715            }
14716            if (components != null) {
14717                for (int i=0; i<components.size(); i++) {
14718                    if (components.get(i).equals(comp)) {
14719                        return true;
14720                    }
14721                }
14722            }
14723            if (objects != null) {
14724                for (int i=0; i<objects.size(); i++) {
14725                    if (System.identityHashCode(object) == objects.get(i)) {
14726                        return true;
14727                    }
14728                }
14729            }
14730            if (strings != null) {
14731                String flat = comp.flattenToString();
14732                for (int i=0; i<strings.size(); i++) {
14733                    if (flat.contains(strings.get(i))) {
14734                        return true;
14735                    }
14736                }
14737            }
14738            return false;
14739        }
14740    }
14741
14742    /**
14743     * There are three things that cmd can be:
14744     *  - a flattened component name that matches an existing activity
14745     *  - the cmd arg isn't the flattened component name of an existing activity:
14746     *    dump all activity whose component contains the cmd as a substring
14747     *  - A hex number of the ActivityRecord object instance.
14748     */
14749    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14750            int opti, boolean dumpAll) {
14751        ArrayList<ActivityRecord> activities;
14752
14753        synchronized (this) {
14754            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14755        }
14756
14757        if (activities.size() <= 0) {
14758            return false;
14759        }
14760
14761        String[] newArgs = new String[args.length - opti];
14762        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14763
14764        TaskRecord lastTask = null;
14765        boolean needSep = false;
14766        for (int i=activities.size()-1; i>=0; i--) {
14767            ActivityRecord r = activities.get(i);
14768            if (needSep) {
14769                pw.println();
14770            }
14771            needSep = true;
14772            synchronized (this) {
14773                if (lastTask != r.task) {
14774                    lastTask = r.task;
14775                    pw.print("TASK "); pw.print(lastTask.affinity);
14776                            pw.print(" id="); pw.println(lastTask.taskId);
14777                    if (dumpAll) {
14778                        lastTask.dump(pw, "  ");
14779                    }
14780                }
14781            }
14782            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14783        }
14784        return true;
14785    }
14786
14787    /**
14788     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14789     * there is a thread associated with the activity.
14790     */
14791    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14792            final ActivityRecord r, String[] args, boolean dumpAll) {
14793        String innerPrefix = prefix + "  ";
14794        synchronized (this) {
14795            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14796                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14797                    pw.print(" pid=");
14798                    if (r.app != null) pw.println(r.app.pid);
14799                    else pw.println("(not running)");
14800            if (dumpAll) {
14801                r.dump(pw, innerPrefix);
14802            }
14803        }
14804        if (r.app != null && r.app.thread != null) {
14805            // flush anything that is already in the PrintWriter since the thread is going
14806            // to write to the file descriptor directly
14807            pw.flush();
14808            try {
14809                TransferPipe tp = new TransferPipe();
14810                try {
14811                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14812                            r.appToken, innerPrefix, args);
14813                    tp.go(fd);
14814                } finally {
14815                    tp.kill();
14816                }
14817            } catch (IOException e) {
14818                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14819            } catch (RemoteException e) {
14820                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14821            }
14822        }
14823    }
14824
14825    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14826            int opti, boolean dumpAll, String dumpPackage) {
14827        boolean needSep = false;
14828        boolean onlyHistory = false;
14829        boolean printedAnything = false;
14830
14831        if ("history".equals(dumpPackage)) {
14832            if (opti < args.length && "-s".equals(args[opti])) {
14833                dumpAll = false;
14834            }
14835            onlyHistory = true;
14836            dumpPackage = null;
14837        }
14838
14839        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14840        if (!onlyHistory && dumpAll) {
14841            if (mRegisteredReceivers.size() > 0) {
14842                boolean printed = false;
14843                Iterator it = mRegisteredReceivers.values().iterator();
14844                while (it.hasNext()) {
14845                    ReceiverList r = (ReceiverList)it.next();
14846                    if (dumpPackage != null && (r.app == null ||
14847                            !dumpPackage.equals(r.app.info.packageName))) {
14848                        continue;
14849                    }
14850                    if (!printed) {
14851                        pw.println("  Registered Receivers:");
14852                        needSep = true;
14853                        printed = true;
14854                        printedAnything = true;
14855                    }
14856                    pw.print("  * "); pw.println(r);
14857                    r.dump(pw, "    ");
14858                }
14859            }
14860
14861            if (mReceiverResolver.dump(pw, needSep ?
14862                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14863                    "    ", dumpPackage, false, false)) {
14864                needSep = true;
14865                printedAnything = true;
14866            }
14867        }
14868
14869        for (BroadcastQueue q : mBroadcastQueues) {
14870            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14871            printedAnything |= needSep;
14872        }
14873
14874        needSep = true;
14875
14876        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14877            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14878                if (needSep) {
14879                    pw.println();
14880                }
14881                needSep = true;
14882                printedAnything = true;
14883                pw.print("  Sticky broadcasts for user ");
14884                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14885                StringBuilder sb = new StringBuilder(128);
14886                for (Map.Entry<String, ArrayList<Intent>> ent
14887                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14888                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14889                    if (dumpAll) {
14890                        pw.println(":");
14891                        ArrayList<Intent> intents = ent.getValue();
14892                        final int N = intents.size();
14893                        for (int i=0; i<N; i++) {
14894                            sb.setLength(0);
14895                            sb.append("    Intent: ");
14896                            intents.get(i).toShortString(sb, false, true, false, false);
14897                            pw.println(sb.toString());
14898                            Bundle bundle = intents.get(i).getExtras();
14899                            if (bundle != null) {
14900                                pw.print("      ");
14901                                pw.println(bundle.toString());
14902                            }
14903                        }
14904                    } else {
14905                        pw.println("");
14906                    }
14907                }
14908            }
14909        }
14910
14911        if (!onlyHistory && dumpAll) {
14912            pw.println();
14913            for (BroadcastQueue queue : mBroadcastQueues) {
14914                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14915                        + queue.mBroadcastsScheduled);
14916            }
14917            pw.println("  mHandler:");
14918            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14919            needSep = true;
14920            printedAnything = true;
14921        }
14922
14923        if (!printedAnything) {
14924            pw.println("  (nothing)");
14925        }
14926    }
14927
14928    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14929            int opti, boolean dumpAll, String dumpPackage) {
14930        boolean needSep;
14931        boolean printedAnything = false;
14932
14933        ItemMatcher matcher = new ItemMatcher();
14934        matcher.build(args, opti);
14935
14936        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14937
14938        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14939        printedAnything |= needSep;
14940
14941        if (mLaunchingProviders.size() > 0) {
14942            boolean printed = false;
14943            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14944                ContentProviderRecord r = mLaunchingProviders.get(i);
14945                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14946                    continue;
14947                }
14948                if (!printed) {
14949                    if (needSep) pw.println();
14950                    needSep = true;
14951                    pw.println("  Launching content providers:");
14952                    printed = true;
14953                    printedAnything = true;
14954                }
14955                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14956                        pw.println(r);
14957            }
14958        }
14959
14960        if (!printedAnything) {
14961            pw.println("  (nothing)");
14962        }
14963    }
14964
14965    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14966            int opti, boolean dumpAll, String dumpPackage) {
14967        boolean needSep = false;
14968        boolean printedAnything = false;
14969
14970        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14971
14972        if (mGrantedUriPermissions.size() > 0) {
14973            boolean printed = false;
14974            int dumpUid = -2;
14975            if (dumpPackage != null) {
14976                try {
14977                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14978                            MATCH_UNINSTALLED_PACKAGES, 0);
14979                } catch (NameNotFoundException e) {
14980                    dumpUid = -1;
14981                }
14982            }
14983            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14984                int uid = mGrantedUriPermissions.keyAt(i);
14985                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14986                    continue;
14987                }
14988                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14989                if (!printed) {
14990                    if (needSep) pw.println();
14991                    needSep = true;
14992                    pw.println("  Granted Uri Permissions:");
14993                    printed = true;
14994                    printedAnything = true;
14995                }
14996                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14997                for (UriPermission perm : perms.values()) {
14998                    pw.print("    "); pw.println(perm);
14999                    if (dumpAll) {
15000                        perm.dump(pw, "      ");
15001                    }
15002                }
15003            }
15004        }
15005
15006        if (!printedAnything) {
15007            pw.println("  (nothing)");
15008        }
15009    }
15010
15011    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15012            int opti, boolean dumpAll, String dumpPackage) {
15013        boolean printed = false;
15014
15015        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15016
15017        if (mIntentSenderRecords.size() > 0) {
15018            Iterator<WeakReference<PendingIntentRecord>> it
15019                    = mIntentSenderRecords.values().iterator();
15020            while (it.hasNext()) {
15021                WeakReference<PendingIntentRecord> ref = it.next();
15022                PendingIntentRecord rec = ref != null ? ref.get(): null;
15023                if (dumpPackage != null && (rec == null
15024                        || !dumpPackage.equals(rec.key.packageName))) {
15025                    continue;
15026                }
15027                printed = true;
15028                if (rec != null) {
15029                    pw.print("  * "); pw.println(rec);
15030                    if (dumpAll) {
15031                        rec.dump(pw, "    ");
15032                    }
15033                } else {
15034                    pw.print("  * "); pw.println(ref);
15035                }
15036            }
15037        }
15038
15039        if (!printed) {
15040            pw.println("  (nothing)");
15041        }
15042    }
15043
15044    private static final int dumpProcessList(PrintWriter pw,
15045            ActivityManagerService service, List list,
15046            String prefix, String normalLabel, String persistentLabel,
15047            String dumpPackage) {
15048        int numPers = 0;
15049        final int N = list.size()-1;
15050        for (int i=N; i>=0; i--) {
15051            ProcessRecord r = (ProcessRecord)list.get(i);
15052            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15053                continue;
15054            }
15055            pw.println(String.format("%s%s #%2d: %s",
15056                    prefix, (r.persistent ? persistentLabel : normalLabel),
15057                    i, r.toString()));
15058            if (r.persistent) {
15059                numPers++;
15060            }
15061        }
15062        return numPers;
15063    }
15064
15065    private static final boolean dumpProcessOomList(PrintWriter pw,
15066            ActivityManagerService service, List<ProcessRecord> origList,
15067            String prefix, String normalLabel, String persistentLabel,
15068            boolean inclDetails, String dumpPackage) {
15069
15070        ArrayList<Pair<ProcessRecord, Integer>> list
15071                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15072        for (int i=0; i<origList.size(); i++) {
15073            ProcessRecord r = origList.get(i);
15074            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15075                continue;
15076            }
15077            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15078        }
15079
15080        if (list.size() <= 0) {
15081            return false;
15082        }
15083
15084        Comparator<Pair<ProcessRecord, Integer>> comparator
15085                = new Comparator<Pair<ProcessRecord, Integer>>() {
15086            @Override
15087            public int compare(Pair<ProcessRecord, Integer> object1,
15088                    Pair<ProcessRecord, Integer> object2) {
15089                if (object1.first.setAdj != object2.first.setAdj) {
15090                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15091                }
15092                if (object1.first.setProcState != object2.first.setProcState) {
15093                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15094                }
15095                if (object1.second.intValue() != object2.second.intValue()) {
15096                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15097                }
15098                return 0;
15099            }
15100        };
15101
15102        Collections.sort(list, comparator);
15103
15104        final long curRealtime = SystemClock.elapsedRealtime();
15105        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15106        final long curUptime = SystemClock.uptimeMillis();
15107        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15108
15109        for (int i=list.size()-1; i>=0; i--) {
15110            ProcessRecord r = list.get(i).first;
15111            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15112            char schedGroup;
15113            switch (r.setSchedGroup) {
15114                case ProcessList.SCHED_GROUP_BACKGROUND:
15115                    schedGroup = 'B';
15116                    break;
15117                case ProcessList.SCHED_GROUP_DEFAULT:
15118                    schedGroup = 'F';
15119                    break;
15120                case ProcessList.SCHED_GROUP_TOP_APP:
15121                    schedGroup = 'T';
15122                    break;
15123                default:
15124                    schedGroup = '?';
15125                    break;
15126            }
15127            char foreground;
15128            if (r.foregroundActivities) {
15129                foreground = 'A';
15130            } else if (r.foregroundServices) {
15131                foreground = 'S';
15132            } else {
15133                foreground = ' ';
15134            }
15135            String procState = ProcessList.makeProcStateString(r.curProcState);
15136            pw.print(prefix);
15137            pw.print(r.persistent ? persistentLabel : normalLabel);
15138            pw.print(" #");
15139            int num = (origList.size()-1)-list.get(i).second;
15140            if (num < 10) pw.print(' ');
15141            pw.print(num);
15142            pw.print(": ");
15143            pw.print(oomAdj);
15144            pw.print(' ');
15145            pw.print(schedGroup);
15146            pw.print('/');
15147            pw.print(foreground);
15148            pw.print('/');
15149            pw.print(procState);
15150            pw.print(" trm:");
15151            if (r.trimMemoryLevel < 10) pw.print(' ');
15152            pw.print(r.trimMemoryLevel);
15153            pw.print(' ');
15154            pw.print(r.toShortString());
15155            pw.print(" (");
15156            pw.print(r.adjType);
15157            pw.println(')');
15158            if (r.adjSource != null || r.adjTarget != null) {
15159                pw.print(prefix);
15160                pw.print("    ");
15161                if (r.adjTarget instanceof ComponentName) {
15162                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15163                } else if (r.adjTarget != null) {
15164                    pw.print(r.adjTarget.toString());
15165                } else {
15166                    pw.print("{null}");
15167                }
15168                pw.print("<=");
15169                if (r.adjSource instanceof ProcessRecord) {
15170                    pw.print("Proc{");
15171                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15172                    pw.println("}");
15173                } else if (r.adjSource != null) {
15174                    pw.println(r.adjSource.toString());
15175                } else {
15176                    pw.println("{null}");
15177                }
15178            }
15179            if (inclDetails) {
15180                pw.print(prefix);
15181                pw.print("    ");
15182                pw.print("oom: max="); pw.print(r.maxAdj);
15183                pw.print(" curRaw="); pw.print(r.curRawAdj);
15184                pw.print(" setRaw="); pw.print(r.setRawAdj);
15185                pw.print(" cur="); pw.print(r.curAdj);
15186                pw.print(" set="); pw.println(r.setAdj);
15187                pw.print(prefix);
15188                pw.print("    ");
15189                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15190                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15191                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15192                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15193                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15194                pw.println();
15195                pw.print(prefix);
15196                pw.print("    ");
15197                pw.print("cached="); pw.print(r.cached);
15198                pw.print(" empty="); pw.print(r.empty);
15199                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15200
15201                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15202                    if (r.lastWakeTime != 0) {
15203                        long wtime;
15204                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15205                        synchronized (stats) {
15206                            wtime = stats.getProcessWakeTime(r.info.uid,
15207                                    r.pid, curRealtime);
15208                        }
15209                        long timeUsed = wtime - r.lastWakeTime;
15210                        pw.print(prefix);
15211                        pw.print("    ");
15212                        pw.print("keep awake over ");
15213                        TimeUtils.formatDuration(realtimeSince, pw);
15214                        pw.print(" used ");
15215                        TimeUtils.formatDuration(timeUsed, pw);
15216                        pw.print(" (");
15217                        pw.print((timeUsed*100)/realtimeSince);
15218                        pw.println("%)");
15219                    }
15220                    if (r.lastCpuTime != 0) {
15221                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15222                        pw.print(prefix);
15223                        pw.print("    ");
15224                        pw.print("run cpu over ");
15225                        TimeUtils.formatDuration(uptimeSince, pw);
15226                        pw.print(" used ");
15227                        TimeUtils.formatDuration(timeUsed, pw);
15228                        pw.print(" (");
15229                        pw.print((timeUsed*100)/uptimeSince);
15230                        pw.println("%)");
15231                    }
15232                }
15233            }
15234        }
15235        return true;
15236    }
15237
15238    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15239            String[] args) {
15240        ArrayList<ProcessRecord> procs;
15241        synchronized (this) {
15242            if (args != null && args.length > start
15243                    && args[start].charAt(0) != '-') {
15244                procs = new ArrayList<ProcessRecord>();
15245                int pid = -1;
15246                try {
15247                    pid = Integer.parseInt(args[start]);
15248                } catch (NumberFormatException e) {
15249                }
15250                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15251                    ProcessRecord proc = mLruProcesses.get(i);
15252                    if (proc.pid == pid) {
15253                        procs.add(proc);
15254                    } else if (allPkgs && proc.pkgList != null
15255                            && proc.pkgList.containsKey(args[start])) {
15256                        procs.add(proc);
15257                    } else if (proc.processName.equals(args[start])) {
15258                        procs.add(proc);
15259                    }
15260                }
15261                if (procs.size() <= 0) {
15262                    return null;
15263                }
15264            } else {
15265                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15266            }
15267        }
15268        return procs;
15269    }
15270
15271    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15272            PrintWriter pw, String[] args) {
15273        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15274        if (procs == null) {
15275            pw.println("No process found for: " + args[0]);
15276            return;
15277        }
15278
15279        long uptime = SystemClock.uptimeMillis();
15280        long realtime = SystemClock.elapsedRealtime();
15281        pw.println("Applications Graphics Acceleration Info:");
15282        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15283
15284        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15285            ProcessRecord r = procs.get(i);
15286            if (r.thread != null) {
15287                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15288                pw.flush();
15289                try {
15290                    TransferPipe tp = new TransferPipe();
15291                    try {
15292                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15293                        tp.go(fd);
15294                    } finally {
15295                        tp.kill();
15296                    }
15297                } catch (IOException e) {
15298                    pw.println("Failure while dumping the app: " + r);
15299                    pw.flush();
15300                } catch (RemoteException e) {
15301                    pw.println("Got a RemoteException while dumping the app " + r);
15302                    pw.flush();
15303                }
15304            }
15305        }
15306    }
15307
15308    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15309        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15310        if (procs == null) {
15311            pw.println("No process found for: " + args[0]);
15312            return;
15313        }
15314
15315        pw.println("Applications Database Info:");
15316
15317        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15318            ProcessRecord r = procs.get(i);
15319            if (r.thread != null) {
15320                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15321                pw.flush();
15322                try {
15323                    TransferPipe tp = new TransferPipe();
15324                    try {
15325                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15326                        tp.go(fd);
15327                    } finally {
15328                        tp.kill();
15329                    }
15330                } catch (IOException e) {
15331                    pw.println("Failure while dumping the app: " + r);
15332                    pw.flush();
15333                } catch (RemoteException e) {
15334                    pw.println("Got a RemoteException while dumping the app " + r);
15335                    pw.flush();
15336                }
15337            }
15338        }
15339    }
15340
15341    final static class MemItem {
15342        final boolean isProc;
15343        final String label;
15344        final String shortLabel;
15345        final long pss;
15346        final long swapPss;
15347        final int id;
15348        final boolean hasActivities;
15349        ArrayList<MemItem> subitems;
15350
15351        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15352                boolean _hasActivities) {
15353            isProc = true;
15354            label = _label;
15355            shortLabel = _shortLabel;
15356            pss = _pss;
15357            swapPss = _swapPss;
15358            id = _id;
15359            hasActivities = _hasActivities;
15360        }
15361
15362        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15363            isProc = false;
15364            label = _label;
15365            shortLabel = _shortLabel;
15366            pss = _pss;
15367            swapPss = _swapPss;
15368            id = _id;
15369            hasActivities = false;
15370        }
15371    }
15372
15373    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15374            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15375        if (sort && !isCompact) {
15376            Collections.sort(items, new Comparator<MemItem>() {
15377                @Override
15378                public int compare(MemItem lhs, MemItem rhs) {
15379                    if (lhs.pss < rhs.pss) {
15380                        return 1;
15381                    } else if (lhs.pss > rhs.pss) {
15382                        return -1;
15383                    }
15384                    return 0;
15385                }
15386            });
15387        }
15388
15389        for (int i=0; i<items.size(); i++) {
15390            MemItem mi = items.get(i);
15391            if (!isCompact) {
15392                if (dumpSwapPss) {
15393                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15394                            mi.label, stringifyKBSize(mi.swapPss));
15395                } else {
15396                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15397                }
15398            } else if (mi.isProc) {
15399                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15400                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15401                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15402                pw.println(mi.hasActivities ? ",a" : ",e");
15403            } else {
15404                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15405                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15406            }
15407            if (mi.subitems != null) {
15408                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15409                        true, isCompact, dumpSwapPss);
15410            }
15411        }
15412    }
15413
15414    // These are in KB.
15415    static final long[] DUMP_MEM_BUCKETS = new long[] {
15416        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15417        120*1024, 160*1024, 200*1024,
15418        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15419        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15420    };
15421
15422    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15423            boolean stackLike) {
15424        int start = label.lastIndexOf('.');
15425        if (start >= 0) start++;
15426        else start = 0;
15427        int end = label.length();
15428        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15429            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15430                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15431                out.append(bucket);
15432                out.append(stackLike ? "MB." : "MB ");
15433                out.append(label, start, end);
15434                return;
15435            }
15436        }
15437        out.append(memKB/1024);
15438        out.append(stackLike ? "MB." : "MB ");
15439        out.append(label, start, end);
15440    }
15441
15442    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15443            ProcessList.NATIVE_ADJ,
15444            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15445            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15446            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15447            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15448            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15449            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15450    };
15451    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15452            "Native",
15453            "System", "Persistent", "Persistent Service", "Foreground",
15454            "Visible", "Perceptible",
15455            "Heavy Weight", "Backup",
15456            "A Services", "Home",
15457            "Previous", "B Services", "Cached"
15458    };
15459    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15460            "native",
15461            "sys", "pers", "persvc", "fore",
15462            "vis", "percept",
15463            "heavy", "backup",
15464            "servicea", "home",
15465            "prev", "serviceb", "cached"
15466    };
15467
15468    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15469            long realtime, boolean isCheckinRequest, boolean isCompact) {
15470        if (isCompact) {
15471            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15472        }
15473        if (isCheckinRequest || isCompact) {
15474            // short checkin version
15475            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15476        } else {
15477            pw.println("Applications Memory Usage (in Kilobytes):");
15478            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15479        }
15480    }
15481
15482    private static final int KSM_SHARED = 0;
15483    private static final int KSM_SHARING = 1;
15484    private static final int KSM_UNSHARED = 2;
15485    private static final int KSM_VOLATILE = 3;
15486
15487    private final long[] getKsmInfo() {
15488        long[] longOut = new long[4];
15489        final int[] SINGLE_LONG_FORMAT = new int[] {
15490            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15491        };
15492        long[] longTmp = new long[1];
15493        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15494                SINGLE_LONG_FORMAT, null, longTmp, null);
15495        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15496        longTmp[0] = 0;
15497        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15498                SINGLE_LONG_FORMAT, null, longTmp, null);
15499        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15500        longTmp[0] = 0;
15501        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15502                SINGLE_LONG_FORMAT, null, longTmp, null);
15503        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15504        longTmp[0] = 0;
15505        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15506                SINGLE_LONG_FORMAT, null, longTmp, null);
15507        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15508        return longOut;
15509    }
15510
15511    private static String stringifySize(long size, int order) {
15512        Locale locale = Locale.US;
15513        switch (order) {
15514            case 1:
15515                return String.format(locale, "%,13d", size);
15516            case 1024:
15517                return String.format(locale, "%,9dK", size / 1024);
15518            case 1024 * 1024:
15519                return String.format(locale, "%,5dM", size / 1024 / 1024);
15520            case 1024 * 1024 * 1024:
15521                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15522            default:
15523                throw new IllegalArgumentException("Invalid size order");
15524        }
15525    }
15526
15527    private static String stringifyKBSize(long size) {
15528        return stringifySize(size * 1024, 1024);
15529    }
15530
15531    // Update this version number in case you change the 'compact' format
15532    private static final int MEMINFO_COMPACT_VERSION = 1;
15533
15534    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15535            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15536        boolean dumpDetails = false;
15537        boolean dumpFullDetails = false;
15538        boolean dumpDalvik = false;
15539        boolean dumpSummaryOnly = false;
15540        boolean dumpUnreachable = false;
15541        boolean oomOnly = false;
15542        boolean isCompact = false;
15543        boolean localOnly = false;
15544        boolean packages = false;
15545        boolean isCheckinRequest = false;
15546        boolean dumpSwapPss = false;
15547
15548        int opti = 0;
15549        while (opti < args.length) {
15550            String opt = args[opti];
15551            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15552                break;
15553            }
15554            opti++;
15555            if ("-a".equals(opt)) {
15556                dumpDetails = true;
15557                dumpFullDetails = true;
15558                dumpDalvik = true;
15559                dumpSwapPss = true;
15560            } else if ("-d".equals(opt)) {
15561                dumpDalvik = true;
15562            } else if ("-c".equals(opt)) {
15563                isCompact = true;
15564            } else if ("-s".equals(opt)) {
15565                dumpDetails = true;
15566                dumpSummaryOnly = true;
15567            } else if ("-S".equals(opt)) {
15568                dumpSwapPss = true;
15569            } else if ("--unreachable".equals(opt)) {
15570                dumpUnreachable = true;
15571            } else if ("--oom".equals(opt)) {
15572                oomOnly = true;
15573            } else if ("--local".equals(opt)) {
15574                localOnly = true;
15575            } else if ("--package".equals(opt)) {
15576                packages = true;
15577            } else if ("--checkin".equals(opt)) {
15578                isCheckinRequest = true;
15579
15580            } else if ("-h".equals(opt)) {
15581                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15582                pw.println("  -a: include all available information for each process.");
15583                pw.println("  -d: include dalvik details.");
15584                pw.println("  -c: dump in a compact machine-parseable representation.");
15585                pw.println("  -s: dump only summary of application memory usage.");
15586                pw.println("  -S: dump also SwapPss.");
15587                pw.println("  --oom: only show processes organized by oom adj.");
15588                pw.println("  --local: only collect details locally, don't call process.");
15589                pw.println("  --package: interpret process arg as package, dumping all");
15590                pw.println("             processes that have loaded that package.");
15591                pw.println("  --checkin: dump data for a checkin");
15592                pw.println("If [process] is specified it can be the name or ");
15593                pw.println("pid of a specific process to dump.");
15594                return;
15595            } else {
15596                pw.println("Unknown argument: " + opt + "; use -h for help");
15597            }
15598        }
15599
15600        long uptime = SystemClock.uptimeMillis();
15601        long realtime = SystemClock.elapsedRealtime();
15602        final long[] tmpLong = new long[1];
15603
15604        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15605        if (procs == null) {
15606            // No Java processes.  Maybe they want to print a native process.
15607            if (args != null && args.length > opti
15608                    && args[opti].charAt(0) != '-') {
15609                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15610                        = new ArrayList<ProcessCpuTracker.Stats>();
15611                updateCpuStatsNow();
15612                int findPid = -1;
15613                try {
15614                    findPid = Integer.parseInt(args[opti]);
15615                } catch (NumberFormatException e) {
15616                }
15617                synchronized (mProcessCpuTracker) {
15618                    final int N = mProcessCpuTracker.countStats();
15619                    for (int i=0; i<N; i++) {
15620                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15621                        if (st.pid == findPid || (st.baseName != null
15622                                && st.baseName.equals(args[opti]))) {
15623                            nativeProcs.add(st);
15624                        }
15625                    }
15626                }
15627                if (nativeProcs.size() > 0) {
15628                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15629                            isCompact);
15630                    Debug.MemoryInfo mi = null;
15631                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15632                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15633                        final int pid = r.pid;
15634                        if (!isCheckinRequest && dumpDetails) {
15635                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15636                        }
15637                        if (mi == null) {
15638                            mi = new Debug.MemoryInfo();
15639                        }
15640                        if (dumpDetails || (!brief && !oomOnly)) {
15641                            Debug.getMemoryInfo(pid, mi);
15642                        } else {
15643                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15644                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15645                        }
15646                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15647                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15648                        if (isCheckinRequest) {
15649                            pw.println();
15650                        }
15651                    }
15652                    return;
15653                }
15654            }
15655            pw.println("No process found for: " + args[opti]);
15656            return;
15657        }
15658
15659        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15660            dumpDetails = true;
15661        }
15662
15663        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15664
15665        String[] innerArgs = new String[args.length-opti];
15666        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15667
15668        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15669        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15670        long nativePss = 0;
15671        long nativeSwapPss = 0;
15672        long dalvikPss = 0;
15673        long dalvikSwapPss = 0;
15674        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15675                EmptyArray.LONG;
15676        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15677                EmptyArray.LONG;
15678        long otherPss = 0;
15679        long otherSwapPss = 0;
15680        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15681        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15682
15683        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15684        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15685        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15686                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15687
15688        long totalPss = 0;
15689        long totalSwapPss = 0;
15690        long cachedPss = 0;
15691        long cachedSwapPss = 0;
15692        boolean hasSwapPss = false;
15693
15694        Debug.MemoryInfo mi = null;
15695        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15696            final ProcessRecord r = procs.get(i);
15697            final IApplicationThread thread;
15698            final int pid;
15699            final int oomAdj;
15700            final boolean hasActivities;
15701            synchronized (this) {
15702                thread = r.thread;
15703                pid = r.pid;
15704                oomAdj = r.getSetAdjWithServices();
15705                hasActivities = r.activities.size() > 0;
15706            }
15707            if (thread != null) {
15708                if (!isCheckinRequest && dumpDetails) {
15709                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15710                }
15711                if (mi == null) {
15712                    mi = new Debug.MemoryInfo();
15713                }
15714                if (dumpDetails || (!brief && !oomOnly)) {
15715                    Debug.getMemoryInfo(pid, mi);
15716                    hasSwapPss = mi.hasSwappedOutPss;
15717                } else {
15718                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15719                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15720                }
15721                if (dumpDetails) {
15722                    if (localOnly) {
15723                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15724                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15725                        if (isCheckinRequest) {
15726                            pw.println();
15727                        }
15728                    } else {
15729                        try {
15730                            pw.flush();
15731                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15732                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15733                        } catch (RemoteException e) {
15734                            if (!isCheckinRequest) {
15735                                pw.println("Got RemoteException!");
15736                                pw.flush();
15737                            }
15738                        }
15739                    }
15740                }
15741
15742                final long myTotalPss = mi.getTotalPss();
15743                final long myTotalUss = mi.getTotalUss();
15744                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15745
15746                synchronized (this) {
15747                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15748                        // Record this for posterity if the process has been stable.
15749                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15750                    }
15751                }
15752
15753                if (!isCheckinRequest && mi != null) {
15754                    totalPss += myTotalPss;
15755                    totalSwapPss += myTotalSwapPss;
15756                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15757                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15758                            myTotalSwapPss, pid, hasActivities);
15759                    procMems.add(pssItem);
15760                    procMemsMap.put(pid, pssItem);
15761
15762                    nativePss += mi.nativePss;
15763                    nativeSwapPss += mi.nativeSwappedOutPss;
15764                    dalvikPss += mi.dalvikPss;
15765                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15766                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15767                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15768                        dalvikSubitemSwapPss[j] +=
15769                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15770                    }
15771                    otherPss += mi.otherPss;
15772                    otherSwapPss += mi.otherSwappedOutPss;
15773                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15774                        long mem = mi.getOtherPss(j);
15775                        miscPss[j] += mem;
15776                        otherPss -= mem;
15777                        mem = mi.getOtherSwappedOutPss(j);
15778                        miscSwapPss[j] += mem;
15779                        otherSwapPss -= mem;
15780                    }
15781
15782                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15783                        cachedPss += myTotalPss;
15784                        cachedSwapPss += myTotalSwapPss;
15785                    }
15786
15787                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15788                        if (oomIndex == (oomPss.length - 1)
15789                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15790                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15791                            oomPss[oomIndex] += myTotalPss;
15792                            oomSwapPss[oomIndex] += myTotalSwapPss;
15793                            if (oomProcs[oomIndex] == null) {
15794                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15795                            }
15796                            oomProcs[oomIndex].add(pssItem);
15797                            break;
15798                        }
15799                    }
15800                }
15801            }
15802        }
15803
15804        long nativeProcTotalPss = 0;
15805
15806        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15807            // If we are showing aggregations, also look for native processes to
15808            // include so that our aggregations are more accurate.
15809            updateCpuStatsNow();
15810            mi = null;
15811            synchronized (mProcessCpuTracker) {
15812                final int N = mProcessCpuTracker.countStats();
15813                for (int i=0; i<N; i++) {
15814                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15815                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15816                        if (mi == null) {
15817                            mi = new Debug.MemoryInfo();
15818                        }
15819                        if (!brief && !oomOnly) {
15820                            Debug.getMemoryInfo(st.pid, mi);
15821                        } else {
15822                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15823                            mi.nativePrivateDirty = (int)tmpLong[0];
15824                        }
15825
15826                        final long myTotalPss = mi.getTotalPss();
15827                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15828                        totalPss += myTotalPss;
15829                        nativeProcTotalPss += myTotalPss;
15830
15831                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15832                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15833                        procMems.add(pssItem);
15834
15835                        nativePss += mi.nativePss;
15836                        nativeSwapPss += mi.nativeSwappedOutPss;
15837                        dalvikPss += mi.dalvikPss;
15838                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15839                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15840                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15841                            dalvikSubitemSwapPss[j] +=
15842                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15843                        }
15844                        otherPss += mi.otherPss;
15845                        otherSwapPss += mi.otherSwappedOutPss;
15846                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15847                            long mem = mi.getOtherPss(j);
15848                            miscPss[j] += mem;
15849                            otherPss -= mem;
15850                            mem = mi.getOtherSwappedOutPss(j);
15851                            miscSwapPss[j] += mem;
15852                            otherSwapPss -= mem;
15853                        }
15854                        oomPss[0] += myTotalPss;
15855                        oomSwapPss[0] += myTotalSwapPss;
15856                        if (oomProcs[0] == null) {
15857                            oomProcs[0] = new ArrayList<MemItem>();
15858                        }
15859                        oomProcs[0].add(pssItem);
15860                    }
15861                }
15862            }
15863
15864            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15865
15866            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15867            final MemItem dalvikItem =
15868                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15869            if (dalvikSubitemPss.length > 0) {
15870                dalvikItem.subitems = new ArrayList<MemItem>();
15871                for (int j=0; j<dalvikSubitemPss.length; j++) {
15872                    final String name = Debug.MemoryInfo.getOtherLabel(
15873                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15874                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15875                                    dalvikSubitemSwapPss[j], j));
15876                }
15877            }
15878            catMems.add(dalvikItem);
15879            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15880            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15881                String label = Debug.MemoryInfo.getOtherLabel(j);
15882                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15883            }
15884
15885            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15886            for (int j=0; j<oomPss.length; j++) {
15887                if (oomPss[j] != 0) {
15888                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15889                            : DUMP_MEM_OOM_LABEL[j];
15890                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15891                            DUMP_MEM_OOM_ADJ[j]);
15892                    item.subitems = oomProcs[j];
15893                    oomMems.add(item);
15894                }
15895            }
15896
15897            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15898            if (!brief && !oomOnly && !isCompact) {
15899                pw.println();
15900                pw.println("Total PSS by process:");
15901                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15902                pw.println();
15903            }
15904            if (!isCompact) {
15905                pw.println("Total PSS by OOM adjustment:");
15906            }
15907            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15908            if (!brief && !oomOnly) {
15909                PrintWriter out = categoryPw != null ? categoryPw : pw;
15910                if (!isCompact) {
15911                    out.println();
15912                    out.println("Total PSS by category:");
15913                }
15914                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15915            }
15916            if (!isCompact) {
15917                pw.println();
15918            }
15919            MemInfoReader memInfo = new MemInfoReader();
15920            memInfo.readMemInfo();
15921            if (nativeProcTotalPss > 0) {
15922                synchronized (this) {
15923                    final long cachedKb = memInfo.getCachedSizeKb();
15924                    final long freeKb = memInfo.getFreeSizeKb();
15925                    final long zramKb = memInfo.getZramTotalSizeKb();
15926                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15927                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15928                            kernelKb*1024, nativeProcTotalPss*1024);
15929                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15930                            nativeProcTotalPss);
15931                }
15932            }
15933            if (!brief) {
15934                if (!isCompact) {
15935                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15936                    pw.print(" (status ");
15937                    switch (mLastMemoryLevel) {
15938                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15939                            pw.println("normal)");
15940                            break;
15941                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15942                            pw.println("moderate)");
15943                            break;
15944                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15945                            pw.println("low)");
15946                            break;
15947                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15948                            pw.println("critical)");
15949                            break;
15950                        default:
15951                            pw.print(mLastMemoryLevel);
15952                            pw.println(")");
15953                            break;
15954                    }
15955                    pw.print(" Free RAM: ");
15956                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15957                            + memInfo.getFreeSizeKb()));
15958                    pw.print(" (");
15959                    pw.print(stringifyKBSize(cachedPss));
15960                    pw.print(" cached pss + ");
15961                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15962                    pw.print(" cached kernel + ");
15963                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15964                    pw.println(" free)");
15965                } else {
15966                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15967                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15968                            + memInfo.getFreeSizeKb()); pw.print(",");
15969                    pw.println(totalPss - cachedPss);
15970                }
15971            }
15972            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15973                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15974                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15975            if (!isCompact) {
15976                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15977                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15978                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15979                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15980                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15981            } else {
15982                pw.print("lostram,"); pw.println(lostRAM);
15983            }
15984            if (!brief) {
15985                if (memInfo.getZramTotalSizeKb() != 0) {
15986                    if (!isCompact) {
15987                        pw.print("     ZRAM: ");
15988                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15989                                pw.print(" physical used for ");
15990                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15991                                        - memInfo.getSwapFreeSizeKb()));
15992                                pw.print(" in swap (");
15993                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15994                                pw.println(" total swap)");
15995                    } else {
15996                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15997                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15998                                pw.println(memInfo.getSwapFreeSizeKb());
15999                    }
16000                }
16001                final long[] ksm = getKsmInfo();
16002                if (!isCompact) {
16003                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16004                            || ksm[KSM_VOLATILE] != 0) {
16005                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16006                                pw.print(" saved from shared ");
16007                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16008                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16009                                pw.print(" unshared; ");
16010                                pw.print(stringifyKBSize(
16011                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16012                    }
16013                    pw.print("   Tuning: ");
16014                    pw.print(ActivityManager.staticGetMemoryClass());
16015                    pw.print(" (large ");
16016                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16017                    pw.print("), oom ");
16018                    pw.print(stringifySize(
16019                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16020                    pw.print(", restore limit ");
16021                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16022                    if (ActivityManager.isLowRamDeviceStatic()) {
16023                        pw.print(" (low-ram)");
16024                    }
16025                    if (ActivityManager.isHighEndGfx()) {
16026                        pw.print(" (high-end-gfx)");
16027                    }
16028                    pw.println();
16029                } else {
16030                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16031                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16032                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16033                    pw.print("tuning,");
16034                    pw.print(ActivityManager.staticGetMemoryClass());
16035                    pw.print(',');
16036                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16037                    pw.print(',');
16038                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16039                    if (ActivityManager.isLowRamDeviceStatic()) {
16040                        pw.print(",low-ram");
16041                    }
16042                    if (ActivityManager.isHighEndGfx()) {
16043                        pw.print(",high-end-gfx");
16044                    }
16045                    pw.println();
16046                }
16047            }
16048        }
16049    }
16050
16051    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16052            long memtrack, String name) {
16053        sb.append("  ");
16054        sb.append(ProcessList.makeOomAdjString(oomAdj));
16055        sb.append(' ');
16056        sb.append(ProcessList.makeProcStateString(procState));
16057        sb.append(' ');
16058        ProcessList.appendRamKb(sb, pss);
16059        sb.append(": ");
16060        sb.append(name);
16061        if (memtrack > 0) {
16062            sb.append(" (");
16063            sb.append(stringifyKBSize(memtrack));
16064            sb.append(" memtrack)");
16065        }
16066    }
16067
16068    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16069        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16070        sb.append(" (pid ");
16071        sb.append(mi.pid);
16072        sb.append(") ");
16073        sb.append(mi.adjType);
16074        sb.append('\n');
16075        if (mi.adjReason != null) {
16076            sb.append("                      ");
16077            sb.append(mi.adjReason);
16078            sb.append('\n');
16079        }
16080    }
16081
16082    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16083        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16084        for (int i=0, N=memInfos.size(); i<N; i++) {
16085            ProcessMemInfo mi = memInfos.get(i);
16086            infoMap.put(mi.pid, mi);
16087        }
16088        updateCpuStatsNow();
16089        long[] memtrackTmp = new long[1];
16090        synchronized (mProcessCpuTracker) {
16091            final int N = mProcessCpuTracker.countStats();
16092            for (int i=0; i<N; i++) {
16093                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16094                if (st.vsize > 0) {
16095                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16096                    if (pss > 0) {
16097                        if (infoMap.indexOfKey(st.pid) < 0) {
16098                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16099                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16100                            mi.pss = pss;
16101                            mi.memtrack = memtrackTmp[0];
16102                            memInfos.add(mi);
16103                        }
16104                    }
16105                }
16106            }
16107        }
16108
16109        long totalPss = 0;
16110        long totalMemtrack = 0;
16111        for (int i=0, N=memInfos.size(); i<N; i++) {
16112            ProcessMemInfo mi = memInfos.get(i);
16113            if (mi.pss == 0) {
16114                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16115                mi.memtrack = memtrackTmp[0];
16116            }
16117            totalPss += mi.pss;
16118            totalMemtrack += mi.memtrack;
16119        }
16120        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16121            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16122                if (lhs.oomAdj != rhs.oomAdj) {
16123                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16124                }
16125                if (lhs.pss != rhs.pss) {
16126                    return lhs.pss < rhs.pss ? 1 : -1;
16127                }
16128                return 0;
16129            }
16130        });
16131
16132        StringBuilder tag = new StringBuilder(128);
16133        StringBuilder stack = new StringBuilder(128);
16134        tag.append("Low on memory -- ");
16135        appendMemBucket(tag, totalPss, "total", false);
16136        appendMemBucket(stack, totalPss, "total", true);
16137
16138        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16139        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16140        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16141
16142        boolean firstLine = true;
16143        int lastOomAdj = Integer.MIN_VALUE;
16144        long extraNativeRam = 0;
16145        long extraNativeMemtrack = 0;
16146        long cachedPss = 0;
16147        for (int i=0, N=memInfos.size(); i<N; i++) {
16148            ProcessMemInfo mi = memInfos.get(i);
16149
16150            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16151                cachedPss += mi.pss;
16152            }
16153
16154            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16155                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16156                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16157                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16158                if (lastOomAdj != mi.oomAdj) {
16159                    lastOomAdj = mi.oomAdj;
16160                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16161                        tag.append(" / ");
16162                    }
16163                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16164                        if (firstLine) {
16165                            stack.append(":");
16166                            firstLine = false;
16167                        }
16168                        stack.append("\n\t at ");
16169                    } else {
16170                        stack.append("$");
16171                    }
16172                } else {
16173                    tag.append(" ");
16174                    stack.append("$");
16175                }
16176                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16177                    appendMemBucket(tag, mi.pss, mi.name, false);
16178                }
16179                appendMemBucket(stack, mi.pss, mi.name, true);
16180                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16181                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16182                    stack.append("(");
16183                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16184                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16185                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16186                            stack.append(":");
16187                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16188                        }
16189                    }
16190                    stack.append(")");
16191                }
16192            }
16193
16194            appendMemInfo(fullNativeBuilder, mi);
16195            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16196                // The short form only has native processes that are >= 512K.
16197                if (mi.pss >= 512) {
16198                    appendMemInfo(shortNativeBuilder, mi);
16199                } else {
16200                    extraNativeRam += mi.pss;
16201                    extraNativeMemtrack += mi.memtrack;
16202                }
16203            } else {
16204                // Short form has all other details, but if we have collected RAM
16205                // from smaller native processes let's dump a summary of that.
16206                if (extraNativeRam > 0) {
16207                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16208                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16209                    shortNativeBuilder.append('\n');
16210                    extraNativeRam = 0;
16211                }
16212                appendMemInfo(fullJavaBuilder, mi);
16213            }
16214        }
16215
16216        fullJavaBuilder.append("           ");
16217        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16218        fullJavaBuilder.append(": TOTAL");
16219        if (totalMemtrack > 0) {
16220            fullJavaBuilder.append(" (");
16221            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16222            fullJavaBuilder.append(" memtrack)");
16223        } else {
16224        }
16225        fullJavaBuilder.append("\n");
16226
16227        MemInfoReader memInfo = new MemInfoReader();
16228        memInfo.readMemInfo();
16229        final long[] infos = memInfo.getRawInfo();
16230
16231        StringBuilder memInfoBuilder = new StringBuilder(1024);
16232        Debug.getMemInfo(infos);
16233        memInfoBuilder.append("  MemInfo: ");
16234        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16235        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16236        memInfoBuilder.append(stringifyKBSize(
16237                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16238        memInfoBuilder.append(stringifyKBSize(
16239                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16240        memInfoBuilder.append(stringifyKBSize(
16241                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16242        memInfoBuilder.append("           ");
16243        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16244        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16245        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16246        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16247        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16248            memInfoBuilder.append("  ZRAM: ");
16249            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16250            memInfoBuilder.append(" RAM, ");
16251            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16252            memInfoBuilder.append(" swap total, ");
16253            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16254            memInfoBuilder.append(" swap free\n");
16255        }
16256        final long[] ksm = getKsmInfo();
16257        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16258                || ksm[KSM_VOLATILE] != 0) {
16259            memInfoBuilder.append("  KSM: ");
16260            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16261            memInfoBuilder.append(" saved from shared ");
16262            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16263            memInfoBuilder.append("\n       ");
16264            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16265            memInfoBuilder.append(" unshared; ");
16266            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16267            memInfoBuilder.append(" volatile\n");
16268        }
16269        memInfoBuilder.append("  Free RAM: ");
16270        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16271                + memInfo.getFreeSizeKb()));
16272        memInfoBuilder.append("\n");
16273        memInfoBuilder.append("  Used RAM: ");
16274        memInfoBuilder.append(stringifyKBSize(
16275                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16276        memInfoBuilder.append("\n");
16277        memInfoBuilder.append("  Lost RAM: ");
16278        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16279                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16280                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16281        memInfoBuilder.append("\n");
16282        Slog.i(TAG, "Low on memory:");
16283        Slog.i(TAG, shortNativeBuilder.toString());
16284        Slog.i(TAG, fullJavaBuilder.toString());
16285        Slog.i(TAG, memInfoBuilder.toString());
16286
16287        StringBuilder dropBuilder = new StringBuilder(1024);
16288        /*
16289        StringWriter oomSw = new StringWriter();
16290        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16291        StringWriter catSw = new StringWriter();
16292        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16293        String[] emptyArgs = new String[] { };
16294        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16295        oomPw.flush();
16296        String oomString = oomSw.toString();
16297        */
16298        dropBuilder.append("Low on memory:");
16299        dropBuilder.append(stack);
16300        dropBuilder.append('\n');
16301        dropBuilder.append(fullNativeBuilder);
16302        dropBuilder.append(fullJavaBuilder);
16303        dropBuilder.append('\n');
16304        dropBuilder.append(memInfoBuilder);
16305        dropBuilder.append('\n');
16306        /*
16307        dropBuilder.append(oomString);
16308        dropBuilder.append('\n');
16309        */
16310        StringWriter catSw = new StringWriter();
16311        synchronized (ActivityManagerService.this) {
16312            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16313            String[] emptyArgs = new String[] { };
16314            catPw.println();
16315            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16316            catPw.println();
16317            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16318                    false, null).dumpLocked();
16319            catPw.println();
16320            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16321            catPw.flush();
16322        }
16323        dropBuilder.append(catSw.toString());
16324        addErrorToDropBox("lowmem", null, "system_server", null,
16325                null, tag.toString(), dropBuilder.toString(), null, null);
16326        //Slog.i(TAG, "Sent to dropbox:");
16327        //Slog.i(TAG, dropBuilder.toString());
16328        synchronized (ActivityManagerService.this) {
16329            long now = SystemClock.uptimeMillis();
16330            if (mLastMemUsageReportTime < now) {
16331                mLastMemUsageReportTime = now;
16332            }
16333        }
16334    }
16335
16336    /**
16337     * Searches array of arguments for the specified string
16338     * @param args array of argument strings
16339     * @param value value to search for
16340     * @return true if the value is contained in the array
16341     */
16342    private static boolean scanArgs(String[] args, String value) {
16343        if (args != null) {
16344            for (String arg : args) {
16345                if (value.equals(arg)) {
16346                    return true;
16347                }
16348            }
16349        }
16350        return false;
16351    }
16352
16353    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16354            ContentProviderRecord cpr, boolean always) {
16355        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16356
16357        if (!inLaunching || always) {
16358            synchronized (cpr) {
16359                cpr.launchingApp = null;
16360                cpr.notifyAll();
16361            }
16362            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16363            String names[] = cpr.info.authority.split(";");
16364            for (int j = 0; j < names.length; j++) {
16365                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16366            }
16367        }
16368
16369        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16370            ContentProviderConnection conn = cpr.connections.get(i);
16371            if (conn.waiting) {
16372                // If this connection is waiting for the provider, then we don't
16373                // need to mess with its process unless we are always removing
16374                // or for some reason the provider is not currently launching.
16375                if (inLaunching && !always) {
16376                    continue;
16377                }
16378            }
16379            ProcessRecord capp = conn.client;
16380            conn.dead = true;
16381            if (conn.stableCount > 0) {
16382                if (!capp.persistent && capp.thread != null
16383                        && capp.pid != 0
16384                        && capp.pid != MY_PID) {
16385                    capp.kill("depends on provider "
16386                            + cpr.name.flattenToShortString()
16387                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16388                }
16389            } else if (capp.thread != null && conn.provider.provider != null) {
16390                try {
16391                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16392                } catch (RemoteException e) {
16393                }
16394                // In the protocol here, we don't expect the client to correctly
16395                // clean up this connection, we'll just remove it.
16396                cpr.connections.remove(i);
16397                if (conn.client.conProviders.remove(conn)) {
16398                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16399                }
16400            }
16401        }
16402
16403        if (inLaunching && always) {
16404            mLaunchingProviders.remove(cpr);
16405        }
16406        return inLaunching;
16407    }
16408
16409    /**
16410     * Main code for cleaning up a process when it has gone away.  This is
16411     * called both as a result of the process dying, or directly when stopping
16412     * a process when running in single process mode.
16413     *
16414     * @return Returns true if the given process has been restarted, so the
16415     * app that was passed in must remain on the process lists.
16416     */
16417    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16418            boolean restarting, boolean allowRestart, int index) {
16419        if (index >= 0) {
16420            removeLruProcessLocked(app);
16421            ProcessList.remove(app.pid);
16422        }
16423
16424        mProcessesToGc.remove(app);
16425        mPendingPssProcesses.remove(app);
16426
16427        // Dismiss any open dialogs.
16428        if (app.crashDialog != null && !app.forceCrashReport) {
16429            app.crashDialog.dismiss();
16430            app.crashDialog = null;
16431        }
16432        if (app.anrDialog != null) {
16433            app.anrDialog.dismiss();
16434            app.anrDialog = null;
16435        }
16436        if (app.waitDialog != null) {
16437            app.waitDialog.dismiss();
16438            app.waitDialog = null;
16439        }
16440
16441        app.crashing = false;
16442        app.notResponding = false;
16443
16444        app.resetPackageList(mProcessStats);
16445        app.unlinkDeathRecipient();
16446        app.makeInactive(mProcessStats);
16447        app.waitingToKill = null;
16448        app.forcingToForeground = null;
16449        updateProcessForegroundLocked(app, false, false);
16450        app.foregroundActivities = false;
16451        app.hasShownUi = false;
16452        app.treatLikeActivity = false;
16453        app.hasAboveClient = false;
16454        app.hasClientActivities = false;
16455
16456        mServices.killServicesLocked(app, allowRestart);
16457
16458        boolean restart = false;
16459
16460        // Remove published content providers.
16461        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16462            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16463            final boolean always = app.bad || !allowRestart;
16464            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16465            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16466                // We left the provider in the launching list, need to
16467                // restart it.
16468                restart = true;
16469            }
16470
16471            cpr.provider = null;
16472            cpr.proc = null;
16473        }
16474        app.pubProviders.clear();
16475
16476        // Take care of any launching providers waiting for this process.
16477        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16478            restart = true;
16479        }
16480
16481        // Unregister from connected content providers.
16482        if (!app.conProviders.isEmpty()) {
16483            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16484                ContentProviderConnection conn = app.conProviders.get(i);
16485                conn.provider.connections.remove(conn);
16486                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16487                        conn.provider.name);
16488            }
16489            app.conProviders.clear();
16490        }
16491
16492        // At this point there may be remaining entries in mLaunchingProviders
16493        // where we were the only one waiting, so they are no longer of use.
16494        // Look for these and clean up if found.
16495        // XXX Commented out for now.  Trying to figure out a way to reproduce
16496        // the actual situation to identify what is actually going on.
16497        if (false) {
16498            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16499                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16500                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16501                    synchronized (cpr) {
16502                        cpr.launchingApp = null;
16503                        cpr.notifyAll();
16504                    }
16505                }
16506            }
16507        }
16508
16509        skipCurrentReceiverLocked(app);
16510
16511        // Unregister any receivers.
16512        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16513            removeReceiverLocked(app.receivers.valueAt(i));
16514        }
16515        app.receivers.clear();
16516
16517        // If the app is undergoing backup, tell the backup manager about it
16518        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16519            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16520                    + mBackupTarget.appInfo + " died during backup");
16521            try {
16522                IBackupManager bm = IBackupManager.Stub.asInterface(
16523                        ServiceManager.getService(Context.BACKUP_SERVICE));
16524                bm.agentDisconnected(app.info.packageName);
16525            } catch (RemoteException e) {
16526                // can't happen; backup manager is local
16527            }
16528        }
16529
16530        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16531            ProcessChangeItem item = mPendingProcessChanges.get(i);
16532            if (item.pid == app.pid) {
16533                mPendingProcessChanges.remove(i);
16534                mAvailProcessChanges.add(item);
16535            }
16536        }
16537        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16538                null).sendToTarget();
16539
16540        // If the caller is restarting this app, then leave it in its
16541        // current lists and let the caller take care of it.
16542        if (restarting) {
16543            return false;
16544        }
16545
16546        if (!app.persistent || app.isolated) {
16547            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16548                    "Removing non-persistent process during cleanup: " + app);
16549            removeProcessNameLocked(app.processName, app.uid);
16550            if (mHeavyWeightProcess == app) {
16551                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16552                        mHeavyWeightProcess.userId, 0));
16553                mHeavyWeightProcess = null;
16554            }
16555        } else if (!app.removed) {
16556            // This app is persistent, so we need to keep its record around.
16557            // If it is not already on the pending app list, add it there
16558            // and start a new process for it.
16559            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16560                mPersistentStartingProcesses.add(app);
16561                restart = true;
16562            }
16563        }
16564        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16565                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16566        mProcessesOnHold.remove(app);
16567
16568        if (app == mHomeProcess) {
16569            mHomeProcess = null;
16570        }
16571        if (app == mPreviousProcess) {
16572            mPreviousProcess = null;
16573        }
16574
16575        if (restart && !app.isolated) {
16576            // We have components that still need to be running in the
16577            // process, so re-launch it.
16578            if (index < 0) {
16579                ProcessList.remove(app.pid);
16580            }
16581            addProcessNameLocked(app);
16582            startProcessLocked(app, "restart", app.processName);
16583            return true;
16584        } else if (app.pid > 0 && app.pid != MY_PID) {
16585            // Goodbye!
16586            boolean removed;
16587            synchronized (mPidsSelfLocked) {
16588                mPidsSelfLocked.remove(app.pid);
16589                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16590            }
16591            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16592            if (app.isolated) {
16593                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16594            }
16595            app.setPid(0);
16596        }
16597        return false;
16598    }
16599
16600    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16601        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16602            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16603            if (cpr.launchingApp == app) {
16604                return true;
16605            }
16606        }
16607        return false;
16608    }
16609
16610    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16611        // Look through the content providers we are waiting to have launched,
16612        // and if any run in this process then either schedule a restart of
16613        // the process or kill the client waiting for it if this process has
16614        // gone bad.
16615        boolean restart = false;
16616        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16617            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16618            if (cpr.launchingApp == app) {
16619                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16620                    restart = true;
16621                } else {
16622                    removeDyingProviderLocked(app, cpr, true);
16623                }
16624            }
16625        }
16626        return restart;
16627    }
16628
16629    // =========================================================
16630    // SERVICES
16631    // =========================================================
16632
16633    @Override
16634    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16635            int flags) {
16636        enforceNotIsolatedCaller("getServices");
16637        synchronized (this) {
16638            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16639        }
16640    }
16641
16642    @Override
16643    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16644        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16645        synchronized (this) {
16646            return mServices.getRunningServiceControlPanelLocked(name);
16647        }
16648    }
16649
16650    @Override
16651    public ComponentName startService(IApplicationThread caller, Intent service,
16652            String resolvedType, String callingPackage, int userId)
16653            throws TransactionTooLargeException {
16654        enforceNotIsolatedCaller("startService");
16655        // Refuse possible leaked file descriptors
16656        if (service != null && service.hasFileDescriptors() == true) {
16657            throw new IllegalArgumentException("File descriptors passed in Intent");
16658        }
16659
16660        if (callingPackage == null) {
16661            throw new IllegalArgumentException("callingPackage cannot be null");
16662        }
16663
16664        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16665                "startService: " + service + " type=" + resolvedType);
16666        synchronized(this) {
16667            final int callingPid = Binder.getCallingPid();
16668            final int callingUid = Binder.getCallingUid();
16669            final long origId = Binder.clearCallingIdentity();
16670            ComponentName res = mServices.startServiceLocked(caller, service,
16671                    resolvedType, callingPid, callingUid, callingPackage, userId);
16672            Binder.restoreCallingIdentity(origId);
16673            return res;
16674        }
16675    }
16676
16677    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16678            String callingPackage, int userId)
16679            throws TransactionTooLargeException {
16680        synchronized(this) {
16681            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16682                    "startServiceInPackage: " + service + " type=" + resolvedType);
16683            final long origId = Binder.clearCallingIdentity();
16684            ComponentName res = mServices.startServiceLocked(null, service,
16685                    resolvedType, -1, uid, callingPackage, userId);
16686            Binder.restoreCallingIdentity(origId);
16687            return res;
16688        }
16689    }
16690
16691    @Override
16692    public int stopService(IApplicationThread caller, Intent service,
16693            String resolvedType, int userId) {
16694        enforceNotIsolatedCaller("stopService");
16695        // Refuse possible leaked file descriptors
16696        if (service != null && service.hasFileDescriptors() == true) {
16697            throw new IllegalArgumentException("File descriptors passed in Intent");
16698        }
16699
16700        synchronized(this) {
16701            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16702        }
16703    }
16704
16705    @Override
16706    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16707        enforceNotIsolatedCaller("peekService");
16708        // Refuse possible leaked file descriptors
16709        if (service != null && service.hasFileDescriptors() == true) {
16710            throw new IllegalArgumentException("File descriptors passed in Intent");
16711        }
16712
16713        if (callingPackage == null) {
16714            throw new IllegalArgumentException("callingPackage cannot be null");
16715        }
16716
16717        synchronized(this) {
16718            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16719        }
16720    }
16721
16722    @Override
16723    public boolean stopServiceToken(ComponentName className, IBinder token,
16724            int startId) {
16725        synchronized(this) {
16726            return mServices.stopServiceTokenLocked(className, token, startId);
16727        }
16728    }
16729
16730    @Override
16731    public void setServiceForeground(ComponentName className, IBinder token,
16732            int id, Notification notification, int flags) {
16733        synchronized(this) {
16734            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16735        }
16736    }
16737
16738    @Override
16739    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16740            boolean requireFull, String name, String callerPackage) {
16741        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16742                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16743    }
16744
16745    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16746            String className, int flags) {
16747        boolean result = false;
16748        // For apps that don't have pre-defined UIDs, check for permission
16749        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16750            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16751                if (ActivityManager.checkUidPermission(
16752                        INTERACT_ACROSS_USERS,
16753                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16754                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16755                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16756                            + " requests FLAG_SINGLE_USER, but app does not hold "
16757                            + INTERACT_ACROSS_USERS;
16758                    Slog.w(TAG, msg);
16759                    throw new SecurityException(msg);
16760                }
16761                // Permission passed
16762                result = true;
16763            }
16764        } else if ("system".equals(componentProcessName)) {
16765            result = true;
16766        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16767            // Phone app and persistent apps are allowed to export singleuser providers.
16768            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16769                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16770        }
16771        if (DEBUG_MU) Slog.v(TAG_MU,
16772                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16773                + Integer.toHexString(flags) + ") = " + result);
16774        return result;
16775    }
16776
16777    /**
16778     * Checks to see if the caller is in the same app as the singleton
16779     * component, or the component is in a special app. It allows special apps
16780     * to export singleton components but prevents exporting singleton
16781     * components for regular apps.
16782     */
16783    boolean isValidSingletonCall(int callingUid, int componentUid) {
16784        int componentAppId = UserHandle.getAppId(componentUid);
16785        return UserHandle.isSameApp(callingUid, componentUid)
16786                || componentAppId == Process.SYSTEM_UID
16787                || componentAppId == Process.PHONE_UID
16788                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16789                        == PackageManager.PERMISSION_GRANTED;
16790    }
16791
16792    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16793            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16794            int userId) throws TransactionTooLargeException {
16795        enforceNotIsolatedCaller("bindService");
16796
16797        // Refuse possible leaked file descriptors
16798        if (service != null && service.hasFileDescriptors() == true) {
16799            throw new IllegalArgumentException("File descriptors passed in Intent");
16800        }
16801
16802        if (callingPackage == null) {
16803            throw new IllegalArgumentException("callingPackage cannot be null");
16804        }
16805
16806        synchronized(this) {
16807            return mServices.bindServiceLocked(caller, token, service,
16808                    resolvedType, connection, flags, callingPackage, userId);
16809        }
16810    }
16811
16812    public boolean unbindService(IServiceConnection connection) {
16813        synchronized (this) {
16814            return mServices.unbindServiceLocked(connection);
16815        }
16816    }
16817
16818    public void publishService(IBinder token, Intent intent, IBinder service) {
16819        // Refuse possible leaked file descriptors
16820        if (intent != null && intent.hasFileDescriptors() == true) {
16821            throw new IllegalArgumentException("File descriptors passed in Intent");
16822        }
16823
16824        synchronized(this) {
16825            if (!(token instanceof ServiceRecord)) {
16826                throw new IllegalArgumentException("Invalid service token");
16827            }
16828            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16829        }
16830    }
16831
16832    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16833        // Refuse possible leaked file descriptors
16834        if (intent != null && intent.hasFileDescriptors() == true) {
16835            throw new IllegalArgumentException("File descriptors passed in Intent");
16836        }
16837
16838        synchronized(this) {
16839            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16840        }
16841    }
16842
16843    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16844        synchronized(this) {
16845            if (!(token instanceof ServiceRecord)) {
16846                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16847                throw new IllegalArgumentException("Invalid service token");
16848            }
16849            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16850        }
16851    }
16852
16853    // =========================================================
16854    // BACKUP AND RESTORE
16855    // =========================================================
16856
16857    // Cause the target app to be launched if necessary and its backup agent
16858    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16859    // activity manager to announce its creation.
16860    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16861        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16862                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16863        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16864
16865        synchronized(this) {
16866            // !!! TODO: currently no check here that we're already bound
16867            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16868            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16869            synchronized (stats) {
16870                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16871            }
16872
16873            // Backup agent is now in use, its package can't be stopped.
16874            try {
16875                AppGlobals.getPackageManager().setPackageStoppedState(
16876                        app.packageName, false, UserHandle.getUserId(app.uid));
16877            } catch (RemoteException e) {
16878            } catch (IllegalArgumentException e) {
16879                Slog.w(TAG, "Failed trying to unstop package "
16880                        + app.packageName + ": " + e);
16881            }
16882
16883            BackupRecord r = new BackupRecord(ss, app, backupMode);
16884            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16885                    ? new ComponentName(app.packageName, app.backupAgentName)
16886                    : new ComponentName("android", "FullBackupAgent");
16887            // startProcessLocked() returns existing proc's record if it's already running
16888            ProcessRecord proc = startProcessLocked(app.processName, app,
16889                    false, 0, "backup", hostingName, false, false, false);
16890            if (proc == null) {
16891                Slog.e(TAG, "Unable to start backup agent process " + r);
16892                return false;
16893            }
16894
16895            // If the app is a regular app (uid >= 10000) and not the system server or phone
16896            // process, etc, then mark it as being in full backup so that certain calls to the
16897            // process can be blocked. This is not reset to false anywhere because we kill the
16898            // process after the full backup is done and the ProcessRecord will vaporize anyway.
16899            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16900                proc.inFullBackup = true;
16901            }
16902            r.app = proc;
16903            mBackupTarget = r;
16904            mBackupAppName = app.packageName;
16905
16906            // Try not to kill the process during backup
16907            updateOomAdjLocked(proc);
16908
16909            // If the process is already attached, schedule the creation of the backup agent now.
16910            // If it is not yet live, this will be done when it attaches to the framework.
16911            if (proc.thread != null) {
16912                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16913                try {
16914                    proc.thread.scheduleCreateBackupAgent(app,
16915                            compatibilityInfoForPackageLocked(app), backupMode);
16916                } catch (RemoteException e) {
16917                    // Will time out on the backup manager side
16918                }
16919            } else {
16920                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16921            }
16922            // Invariants: at this point, the target app process exists and the application
16923            // is either already running or in the process of coming up.  mBackupTarget and
16924            // mBackupAppName describe the app, so that when it binds back to the AM we
16925            // know that it's scheduled for a backup-agent operation.
16926        }
16927
16928        return true;
16929    }
16930
16931    @Override
16932    public void clearPendingBackup() {
16933        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16934        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16935
16936        synchronized (this) {
16937            mBackupTarget = null;
16938            mBackupAppName = null;
16939        }
16940    }
16941
16942    // A backup agent has just come up
16943    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16944        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16945                + " = " + agent);
16946
16947        synchronized(this) {
16948            if (!agentPackageName.equals(mBackupAppName)) {
16949                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16950                return;
16951            }
16952        }
16953
16954        long oldIdent = Binder.clearCallingIdentity();
16955        try {
16956            IBackupManager bm = IBackupManager.Stub.asInterface(
16957                    ServiceManager.getService(Context.BACKUP_SERVICE));
16958            bm.agentConnected(agentPackageName, agent);
16959        } catch (RemoteException e) {
16960            // can't happen; the backup manager service is local
16961        } catch (Exception e) {
16962            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16963            e.printStackTrace();
16964        } finally {
16965            Binder.restoreCallingIdentity(oldIdent);
16966        }
16967    }
16968
16969    // done with this agent
16970    public void unbindBackupAgent(ApplicationInfo appInfo) {
16971        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16972        if (appInfo == null) {
16973            Slog.w(TAG, "unbind backup agent for null app");
16974            return;
16975        }
16976
16977        synchronized(this) {
16978            try {
16979                if (mBackupAppName == null) {
16980                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16981                    return;
16982                }
16983
16984                if (!mBackupAppName.equals(appInfo.packageName)) {
16985                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16986                    return;
16987                }
16988
16989                // Not backing this app up any more; reset its OOM adjustment
16990                final ProcessRecord proc = mBackupTarget.app;
16991                updateOomAdjLocked(proc);
16992
16993                // If the app crashed during backup, 'thread' will be null here
16994                if (proc.thread != null) {
16995                    try {
16996                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16997                                compatibilityInfoForPackageLocked(appInfo));
16998                    } catch (Exception e) {
16999                        Slog.e(TAG, "Exception when unbinding backup agent:");
17000                        e.printStackTrace();
17001                    }
17002                }
17003            } finally {
17004                mBackupTarget = null;
17005                mBackupAppName = null;
17006            }
17007        }
17008    }
17009    // =========================================================
17010    // BROADCASTS
17011    // =========================================================
17012
17013    boolean isPendingBroadcastProcessLocked(int pid) {
17014        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17015                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17016    }
17017
17018    void skipPendingBroadcastLocked(int pid) {
17019            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17020            for (BroadcastQueue queue : mBroadcastQueues) {
17021                queue.skipPendingBroadcastLocked(pid);
17022            }
17023    }
17024
17025    // The app just attached; send any pending broadcasts that it should receive
17026    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17027        boolean didSomething = false;
17028        for (BroadcastQueue queue : mBroadcastQueues) {
17029            didSomething |= queue.sendPendingBroadcastsLocked(app);
17030        }
17031        return didSomething;
17032    }
17033
17034    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17035            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17036        enforceNotIsolatedCaller("registerReceiver");
17037        ArrayList<Intent> stickyIntents = null;
17038        ProcessRecord callerApp = null;
17039        int callingUid;
17040        int callingPid;
17041        synchronized(this) {
17042            if (caller != null) {
17043                callerApp = getRecordForAppLocked(caller);
17044                if (callerApp == null) {
17045                    throw new SecurityException(
17046                            "Unable to find app for caller " + caller
17047                            + " (pid=" + Binder.getCallingPid()
17048                            + ") when registering receiver " + receiver);
17049                }
17050                if (callerApp.info.uid != Process.SYSTEM_UID &&
17051                        !callerApp.pkgList.containsKey(callerPackage) &&
17052                        !"android".equals(callerPackage)) {
17053                    throw new SecurityException("Given caller package " + callerPackage
17054                            + " is not running in process " + callerApp);
17055                }
17056                callingUid = callerApp.info.uid;
17057                callingPid = callerApp.pid;
17058            } else {
17059                callerPackage = null;
17060                callingUid = Binder.getCallingUid();
17061                callingPid = Binder.getCallingPid();
17062            }
17063
17064            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17065                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17066
17067            Iterator<String> actions = filter.actionsIterator();
17068            if (actions == null) {
17069                ArrayList<String> noAction = new ArrayList<String>(1);
17070                noAction.add(null);
17071                actions = noAction.iterator();
17072            }
17073
17074            // Collect stickies of users
17075            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17076            while (actions.hasNext()) {
17077                String action = actions.next();
17078                for (int id : userIds) {
17079                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17080                    if (stickies != null) {
17081                        ArrayList<Intent> intents = stickies.get(action);
17082                        if (intents != null) {
17083                            if (stickyIntents == null) {
17084                                stickyIntents = new ArrayList<Intent>();
17085                            }
17086                            stickyIntents.addAll(intents);
17087                        }
17088                    }
17089                }
17090            }
17091        }
17092
17093        ArrayList<Intent> allSticky = null;
17094        if (stickyIntents != null) {
17095            final ContentResolver resolver = mContext.getContentResolver();
17096            // Look for any matching sticky broadcasts...
17097            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17098                Intent intent = stickyIntents.get(i);
17099                // If intent has scheme "content", it will need to acccess
17100                // provider that needs to lock mProviderMap in ActivityThread
17101                // and also it may need to wait application response, so we
17102                // cannot lock ActivityManagerService here.
17103                if (filter.match(resolver, intent, true, TAG) >= 0) {
17104                    if (allSticky == null) {
17105                        allSticky = new ArrayList<Intent>();
17106                    }
17107                    allSticky.add(intent);
17108                }
17109            }
17110        }
17111
17112        // The first sticky in the list is returned directly back to the client.
17113        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17114        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17115        if (receiver == null) {
17116            return sticky;
17117        }
17118
17119        synchronized (this) {
17120            if (callerApp != null && (callerApp.thread == null
17121                    || callerApp.thread.asBinder() != caller.asBinder())) {
17122                // Original caller already died
17123                return null;
17124            }
17125            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17126            if (rl == null) {
17127                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17128                        userId, receiver);
17129                if (rl.app != null) {
17130                    rl.app.receivers.add(rl);
17131                } else {
17132                    try {
17133                        receiver.asBinder().linkToDeath(rl, 0);
17134                    } catch (RemoteException e) {
17135                        return sticky;
17136                    }
17137                    rl.linkedToDeath = true;
17138                }
17139                mRegisteredReceivers.put(receiver.asBinder(), rl);
17140            } else if (rl.uid != callingUid) {
17141                throw new IllegalArgumentException(
17142                        "Receiver requested to register for uid " + callingUid
17143                        + " was previously registered for uid " + rl.uid);
17144            } else if (rl.pid != callingPid) {
17145                throw new IllegalArgumentException(
17146                        "Receiver requested to register for pid " + callingPid
17147                        + " was previously registered for pid " + rl.pid);
17148            } else if (rl.userId != userId) {
17149                throw new IllegalArgumentException(
17150                        "Receiver requested to register for user " + userId
17151                        + " was previously registered for user " + rl.userId);
17152            }
17153            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17154                    permission, callingUid, userId);
17155            rl.add(bf);
17156            if (!bf.debugCheck()) {
17157                Slog.w(TAG, "==> For Dynamic broadcast");
17158            }
17159            mReceiverResolver.addFilter(bf);
17160
17161            // Enqueue broadcasts for all existing stickies that match
17162            // this filter.
17163            if (allSticky != null) {
17164                ArrayList receivers = new ArrayList();
17165                receivers.add(bf);
17166
17167                final int stickyCount = allSticky.size();
17168                for (int i = 0; i < stickyCount; i++) {
17169                    Intent intent = allSticky.get(i);
17170                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17171                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17172                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17173                            null, 0, null, null, false, true, true, -1);
17174                    queue.enqueueParallelBroadcastLocked(r);
17175                    queue.scheduleBroadcastsLocked();
17176                }
17177            }
17178
17179            return sticky;
17180        }
17181    }
17182
17183    public void unregisterReceiver(IIntentReceiver receiver) {
17184        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17185
17186        final long origId = Binder.clearCallingIdentity();
17187        try {
17188            boolean doTrim = false;
17189
17190            synchronized(this) {
17191                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17192                if (rl != null) {
17193                    final BroadcastRecord r = rl.curBroadcast;
17194                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17195                        final boolean doNext = r.queue.finishReceiverLocked(
17196                                r, r.resultCode, r.resultData, r.resultExtras,
17197                                r.resultAbort, false);
17198                        if (doNext) {
17199                            doTrim = true;
17200                            r.queue.processNextBroadcast(false);
17201                        }
17202                    }
17203
17204                    if (rl.app != null) {
17205                        rl.app.receivers.remove(rl);
17206                    }
17207                    removeReceiverLocked(rl);
17208                    if (rl.linkedToDeath) {
17209                        rl.linkedToDeath = false;
17210                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17211                    }
17212                }
17213            }
17214
17215            // If we actually concluded any broadcasts, we might now be able
17216            // to trim the recipients' apps from our working set
17217            if (doTrim) {
17218                trimApplications();
17219                return;
17220            }
17221
17222        } finally {
17223            Binder.restoreCallingIdentity(origId);
17224        }
17225    }
17226
17227    void removeReceiverLocked(ReceiverList rl) {
17228        mRegisteredReceivers.remove(rl.receiver.asBinder());
17229        for (int i = rl.size() - 1; i >= 0; i--) {
17230            mReceiverResolver.removeFilter(rl.get(i));
17231        }
17232    }
17233
17234    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17235        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17236            ProcessRecord r = mLruProcesses.get(i);
17237            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17238                try {
17239                    r.thread.dispatchPackageBroadcast(cmd, packages);
17240                } catch (RemoteException ex) {
17241                }
17242            }
17243        }
17244    }
17245
17246    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17247            int callingUid, int[] users) {
17248        // TODO: come back and remove this assumption to triage all broadcasts
17249        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17250
17251        List<ResolveInfo> receivers = null;
17252        try {
17253            HashSet<ComponentName> singleUserReceivers = null;
17254            boolean scannedFirstReceivers = false;
17255            for (int user : users) {
17256                // Skip users that have Shell restrictions, with exception of always permitted
17257                // Shell broadcasts
17258                if (callingUid == Process.SHELL_UID
17259                        && mUserController.hasUserRestriction(
17260                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17261                        && !isPermittedShellBroadcast(intent)) {
17262                    continue;
17263                }
17264                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17265                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17266                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17267                    // If this is not the system user, we need to check for
17268                    // any receivers that should be filtered out.
17269                    for (int i=0; i<newReceivers.size(); i++) {
17270                        ResolveInfo ri = newReceivers.get(i);
17271                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17272                            newReceivers.remove(i);
17273                            i--;
17274                        }
17275                    }
17276                }
17277                if (newReceivers != null && newReceivers.size() == 0) {
17278                    newReceivers = null;
17279                }
17280                if (receivers == null) {
17281                    receivers = newReceivers;
17282                } else if (newReceivers != null) {
17283                    // We need to concatenate the additional receivers
17284                    // found with what we have do far.  This would be easy,
17285                    // but we also need to de-dup any receivers that are
17286                    // singleUser.
17287                    if (!scannedFirstReceivers) {
17288                        // Collect any single user receivers we had already retrieved.
17289                        scannedFirstReceivers = true;
17290                        for (int i=0; i<receivers.size(); i++) {
17291                            ResolveInfo ri = receivers.get(i);
17292                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17293                                ComponentName cn = new ComponentName(
17294                                        ri.activityInfo.packageName, ri.activityInfo.name);
17295                                if (singleUserReceivers == null) {
17296                                    singleUserReceivers = new HashSet<ComponentName>();
17297                                }
17298                                singleUserReceivers.add(cn);
17299                            }
17300                        }
17301                    }
17302                    // Add the new results to the existing results, tracking
17303                    // and de-dupping single user receivers.
17304                    for (int i=0; i<newReceivers.size(); i++) {
17305                        ResolveInfo ri = newReceivers.get(i);
17306                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17307                            ComponentName cn = new ComponentName(
17308                                    ri.activityInfo.packageName, ri.activityInfo.name);
17309                            if (singleUserReceivers == null) {
17310                                singleUserReceivers = new HashSet<ComponentName>();
17311                            }
17312                            if (!singleUserReceivers.contains(cn)) {
17313                                singleUserReceivers.add(cn);
17314                                receivers.add(ri);
17315                            }
17316                        } else {
17317                            receivers.add(ri);
17318                        }
17319                    }
17320                }
17321            }
17322        } catch (RemoteException ex) {
17323            // pm is in same process, this will never happen.
17324        }
17325        return receivers;
17326    }
17327
17328    private boolean isPermittedShellBroadcast(Intent intent) {
17329        // remote bugreport should always be allowed to be taken
17330        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17331    }
17332
17333    final int broadcastIntentLocked(ProcessRecord callerApp,
17334            String callerPackage, Intent intent, String resolvedType,
17335            IIntentReceiver resultTo, int resultCode, String resultData,
17336            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17337            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17338        intent = new Intent(intent);
17339
17340        // By default broadcasts do not go to stopped apps.
17341        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17342
17343        // If we have not finished booting, don't allow this to launch new processes.
17344        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17345            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17346        }
17347
17348        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17349                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17350                + " ordered=" + ordered + " userid=" + userId);
17351        if ((resultTo != null) && !ordered) {
17352            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17353        }
17354
17355        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17356                ALLOW_NON_FULL, "broadcast", callerPackage);
17357
17358        // Make sure that the user who is receiving this broadcast is running.
17359        // If not, we will just skip it. Make an exception for shutdown broadcasts
17360        // and upgrade steps.
17361
17362        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17363            if ((callingUid != Process.SYSTEM_UID
17364                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17365                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17366                Slog.w(TAG, "Skipping broadcast of " + intent
17367                        + ": user " + userId + " is stopped");
17368                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17369            }
17370        }
17371
17372        BroadcastOptions brOptions = null;
17373        if (bOptions != null) {
17374            brOptions = new BroadcastOptions(bOptions);
17375            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17376                // See if the caller is allowed to do this.  Note we are checking against
17377                // the actual real caller (not whoever provided the operation as say a
17378                // PendingIntent), because that who is actually supplied the arguments.
17379                if (checkComponentPermission(
17380                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17381                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17382                        != PackageManager.PERMISSION_GRANTED) {
17383                    String msg = "Permission Denial: " + intent.getAction()
17384                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17385                            + ", uid=" + callingUid + ")"
17386                            + " requires "
17387                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17388                    Slog.w(TAG, msg);
17389                    throw new SecurityException(msg);
17390                }
17391            }
17392        }
17393
17394        // Verify that protected broadcasts are only being sent by system code,
17395        // and that system code is only sending protected broadcasts.
17396        final String action = intent.getAction();
17397        final boolean isProtectedBroadcast;
17398        try {
17399            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17400        } catch (RemoteException e) {
17401            Slog.w(TAG, "Remote exception", e);
17402            return ActivityManager.BROADCAST_SUCCESS;
17403        }
17404
17405        final boolean isCallerSystem;
17406        switch (UserHandle.getAppId(callingUid)) {
17407            case Process.ROOT_UID:
17408            case Process.SYSTEM_UID:
17409            case Process.PHONE_UID:
17410            case Process.BLUETOOTH_UID:
17411            case Process.NFC_UID:
17412                isCallerSystem = true;
17413                break;
17414            default:
17415                isCallerSystem = (callerApp != null) && callerApp.persistent;
17416                break;
17417        }
17418
17419        if (isCallerSystem) {
17420            if (isProtectedBroadcast
17421                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17422                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17423                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17424                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17425                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17426                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17427                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17428                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17429                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17430                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17431                // Broadcast is either protected, or it's a public action that
17432                // we've relaxed, so it's fine for system internals to send.
17433            } else {
17434                // The vast majority of broadcasts sent from system internals
17435                // should be protected to avoid security holes, so yell loudly
17436                // to ensure we examine these cases.
17437                if (callerApp != null) {
17438                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17439                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17440                            new Throwable());
17441                } else {
17442                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17443                            + " from system uid " + UserHandle.formatUid(callingUid)
17444                            + " pkg " + callerPackage,
17445                            new Throwable());
17446                }
17447            }
17448
17449        } else {
17450            if (isProtectedBroadcast) {
17451                String msg = "Permission Denial: not allowed to send broadcast "
17452                        + action + " from pid="
17453                        + callingPid + ", uid=" + callingUid;
17454                Slog.w(TAG, msg);
17455                throw new SecurityException(msg);
17456
17457            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17458                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17459                // Special case for compatibility: we don't want apps to send this,
17460                // but historically it has not been protected and apps may be using it
17461                // to poke their own app widget.  So, instead of making it protected,
17462                // just limit it to the caller.
17463                if (callerPackage == null) {
17464                    String msg = "Permission Denial: not allowed to send broadcast "
17465                            + action + " from unknown caller.";
17466                    Slog.w(TAG, msg);
17467                    throw new SecurityException(msg);
17468                } else if (intent.getComponent() != null) {
17469                    // They are good enough to send to an explicit component...  verify
17470                    // it is being sent to the calling app.
17471                    if (!intent.getComponent().getPackageName().equals(
17472                            callerPackage)) {
17473                        String msg = "Permission Denial: not allowed to send broadcast "
17474                                + action + " to "
17475                                + intent.getComponent().getPackageName() + " from "
17476                                + callerPackage;
17477                        Slog.w(TAG, msg);
17478                        throw new SecurityException(msg);
17479                    }
17480                } else {
17481                    // Limit broadcast to their own package.
17482                    intent.setPackage(callerPackage);
17483                }
17484            }
17485        }
17486
17487        if (action != null) {
17488            switch (action) {
17489                case Intent.ACTION_UID_REMOVED:
17490                case Intent.ACTION_PACKAGE_REMOVED:
17491                case Intent.ACTION_PACKAGE_CHANGED:
17492                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17493                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17494                case Intent.ACTION_PACKAGES_SUSPENDED:
17495                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17496                    // Handle special intents: if this broadcast is from the package
17497                    // manager about a package being removed, we need to remove all of
17498                    // its activities from the history stack.
17499                    if (checkComponentPermission(
17500                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17501                            callingPid, callingUid, -1, true)
17502                            != PackageManager.PERMISSION_GRANTED) {
17503                        String msg = "Permission Denial: " + intent.getAction()
17504                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17505                                + ", uid=" + callingUid + ")"
17506                                + " requires "
17507                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17508                        Slog.w(TAG, msg);
17509                        throw new SecurityException(msg);
17510                    }
17511                    switch (action) {
17512                        case Intent.ACTION_UID_REMOVED:
17513                            final Bundle intentExtras = intent.getExtras();
17514                            final int uid = intentExtras != null
17515                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17516                            if (uid >= 0) {
17517                                mBatteryStatsService.removeUid(uid);
17518                                mAppOpsService.uidRemoved(uid);
17519                            }
17520                            break;
17521                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17522                            // If resources are unavailable just force stop all those packages
17523                            // and flush the attribute cache as well.
17524                            String list[] =
17525                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17526                            if (list != null && list.length > 0) {
17527                                for (int i = 0; i < list.length; i++) {
17528                                    forceStopPackageLocked(list[i], -1, false, true, true,
17529                                            false, false, userId, "storage unmount");
17530                                }
17531                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17532                                sendPackageBroadcastLocked(
17533                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17534                                        userId);
17535                            }
17536                            break;
17537                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17538                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17539                            break;
17540                        case Intent.ACTION_PACKAGE_REMOVED:
17541                        case Intent.ACTION_PACKAGE_CHANGED:
17542                            Uri data = intent.getData();
17543                            String ssp;
17544                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17545                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17546                                final boolean replacing =
17547                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17548                                final boolean killProcess =
17549                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17550                                final boolean fullUninstall = removed && !replacing;
17551                                if (killProcess) {
17552                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17553                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17554                                            false, true, true, false, fullUninstall, userId,
17555                                            removed ? "pkg removed" : "pkg changed");
17556                                }
17557                                if (removed) {
17558                                    final int cmd = killProcess
17559                                            ? IApplicationThread.PACKAGE_REMOVED
17560                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17561                                    sendPackageBroadcastLocked(cmd,
17562                                            new String[] {ssp}, userId);
17563                                    if (fullUninstall) {
17564                                        mAppOpsService.packageRemoved(
17565                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17566
17567                                        // Remove all permissions granted from/to this package
17568                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17569
17570                                        removeTasksByPackageNameLocked(ssp, userId);
17571                                        mBatteryStatsService.notePackageUninstalled(ssp);
17572                                    }
17573                                } else {
17574                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17575                                            intent.getStringArrayExtra(
17576                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17577                                }
17578                            }
17579                            break;
17580                        case Intent.ACTION_PACKAGES_SUSPENDED:
17581                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17582                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17583                                    intent.getAction());
17584                            final String[] packageNames = intent.getStringArrayExtra(
17585                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17586                            final int userHandle = intent.getIntExtra(
17587                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17588
17589                            synchronized(ActivityManagerService.this) {
17590                                mRecentTasks.onPackagesSuspendedChanged(
17591                                        packageNames, suspended, userHandle);
17592                            }
17593                            break;
17594                    }
17595                    break;
17596                case Intent.ACTION_PACKAGE_REPLACED:
17597                {
17598                    final Uri data = intent.getData();
17599                    final String ssp;
17600                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17601                        final ApplicationInfo aInfo =
17602                                getPackageManagerInternalLocked().getApplicationInfo(
17603                                        ssp,
17604                                        userId);
17605                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17606                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17607                                new String[] {ssp}, userId);
17608                    }
17609                    break;
17610                }
17611                case Intent.ACTION_PACKAGE_ADDED:
17612                {
17613                    // Special case for adding a package: by default turn on compatibility mode.
17614                    Uri data = intent.getData();
17615                    String ssp;
17616                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17617                        final boolean replacing =
17618                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17619                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17620
17621                        try {
17622                            ApplicationInfo ai = AppGlobals.getPackageManager().
17623                                    getApplicationInfo(ssp, 0, 0);
17624                            mBatteryStatsService.notePackageInstalled(ssp,
17625                                    ai != null ? ai.versionCode : 0);
17626                        } catch (RemoteException e) {
17627                        }
17628                    }
17629                    break;
17630                }
17631                case Intent.ACTION_TIMEZONE_CHANGED:
17632                    // If this is the time zone changed action, queue up a message that will reset
17633                    // the timezone of all currently running processes. This message will get
17634                    // queued up before the broadcast happens.
17635                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17636                    break;
17637                case Intent.ACTION_TIME_CHANGED:
17638                    // If the user set the time, let all running processes know.
17639                    final int is24Hour =
17640                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17641                                    : 0;
17642                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17643                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17644                    synchronized (stats) {
17645                        stats.noteCurrentTimeChangedLocked();
17646                    }
17647                    break;
17648                case Intent.ACTION_CLEAR_DNS_CACHE:
17649                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17650                    break;
17651                case Proxy.PROXY_CHANGE_ACTION:
17652                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17653                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17654                    break;
17655                case android.hardware.Camera.ACTION_NEW_PICTURE:
17656                case android.hardware.Camera.ACTION_NEW_VIDEO:
17657                    // These broadcasts are no longer allowed by the system, since they can
17658                    // cause significant thrashing at a crictical point (using the camera).
17659                    // Apps should use JobScehduler to monitor for media provider changes.
17660                    Slog.w(TAG, action + " no longer allowed; dropping from "
17661                            + UserHandle.formatUid(callingUid));
17662                    // Lie; we don't want to crash the app.
17663                    return ActivityManager.BROADCAST_SUCCESS;
17664            }
17665        }
17666
17667        // Add to the sticky list if requested.
17668        if (sticky) {
17669            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17670                    callingPid, callingUid)
17671                    != PackageManager.PERMISSION_GRANTED) {
17672                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17673                        + callingPid + ", uid=" + callingUid
17674                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17675                Slog.w(TAG, msg);
17676                throw new SecurityException(msg);
17677            }
17678            if (requiredPermissions != null && requiredPermissions.length > 0) {
17679                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17680                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17681                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17682            }
17683            if (intent.getComponent() != null) {
17684                throw new SecurityException(
17685                        "Sticky broadcasts can't target a specific component");
17686            }
17687            // We use userId directly here, since the "all" target is maintained
17688            // as a separate set of sticky broadcasts.
17689            if (userId != UserHandle.USER_ALL) {
17690                // But first, if this is not a broadcast to all users, then
17691                // make sure it doesn't conflict with an existing broadcast to
17692                // all users.
17693                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17694                        UserHandle.USER_ALL);
17695                if (stickies != null) {
17696                    ArrayList<Intent> list = stickies.get(intent.getAction());
17697                    if (list != null) {
17698                        int N = list.size();
17699                        int i;
17700                        for (i=0; i<N; i++) {
17701                            if (intent.filterEquals(list.get(i))) {
17702                                throw new IllegalArgumentException(
17703                                        "Sticky broadcast " + intent + " for user "
17704                                        + userId + " conflicts with existing global broadcast");
17705                            }
17706                        }
17707                    }
17708                }
17709            }
17710            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17711            if (stickies == null) {
17712                stickies = new ArrayMap<>();
17713                mStickyBroadcasts.put(userId, stickies);
17714            }
17715            ArrayList<Intent> list = stickies.get(intent.getAction());
17716            if (list == null) {
17717                list = new ArrayList<>();
17718                stickies.put(intent.getAction(), list);
17719            }
17720            final int stickiesCount = list.size();
17721            int i;
17722            for (i = 0; i < stickiesCount; i++) {
17723                if (intent.filterEquals(list.get(i))) {
17724                    // This sticky already exists, replace it.
17725                    list.set(i, new Intent(intent));
17726                    break;
17727                }
17728            }
17729            if (i >= stickiesCount) {
17730                list.add(new Intent(intent));
17731            }
17732        }
17733
17734        int[] users;
17735        if (userId == UserHandle.USER_ALL) {
17736            // Caller wants broadcast to go to all started users.
17737            users = mUserController.getStartedUserArrayLocked();
17738        } else {
17739            // Caller wants broadcast to go to one specific user.
17740            users = new int[] {userId};
17741        }
17742
17743        // Figure out who all will receive this broadcast.
17744        List receivers = null;
17745        List<BroadcastFilter> registeredReceivers = null;
17746        // Need to resolve the intent to interested receivers...
17747        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17748                 == 0) {
17749            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17750        }
17751        if (intent.getComponent() == null) {
17752            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17753                // Query one target user at a time, excluding shell-restricted users
17754                for (int i = 0; i < users.length; i++) {
17755                    if (mUserController.hasUserRestriction(
17756                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17757                        continue;
17758                    }
17759                    List<BroadcastFilter> registeredReceiversForUser =
17760                            mReceiverResolver.queryIntent(intent,
17761                                    resolvedType, false, users[i]);
17762                    if (registeredReceivers == null) {
17763                        registeredReceivers = registeredReceiversForUser;
17764                    } else if (registeredReceiversForUser != null) {
17765                        registeredReceivers.addAll(registeredReceiversForUser);
17766                    }
17767                }
17768            } else {
17769                registeredReceivers = mReceiverResolver.queryIntent(intent,
17770                        resolvedType, false, userId);
17771            }
17772        }
17773
17774        final boolean replacePending =
17775                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17776
17777        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17778                + " replacePending=" + replacePending);
17779
17780        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17781        if (!ordered && NR > 0) {
17782            // If we are not serializing this broadcast, then send the
17783            // registered receivers separately so they don't wait for the
17784            // components to be launched.
17785            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17786            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17787                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17788                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17789                    resultExtras, ordered, sticky, false, userId);
17790            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17791            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17792            if (!replaced) {
17793                queue.enqueueParallelBroadcastLocked(r);
17794                queue.scheduleBroadcastsLocked();
17795            }
17796            registeredReceivers = null;
17797            NR = 0;
17798        }
17799
17800        // Merge into one list.
17801        int ir = 0;
17802        if (receivers != null) {
17803            // A special case for PACKAGE_ADDED: do not allow the package
17804            // being added to see this broadcast.  This prevents them from
17805            // using this as a back door to get run as soon as they are
17806            // installed.  Maybe in the future we want to have a special install
17807            // broadcast or such for apps, but we'd like to deliberately make
17808            // this decision.
17809            String skipPackages[] = null;
17810            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17811                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17812                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17813                Uri data = intent.getData();
17814                if (data != null) {
17815                    String pkgName = data.getSchemeSpecificPart();
17816                    if (pkgName != null) {
17817                        skipPackages = new String[] { pkgName };
17818                    }
17819                }
17820            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17821                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17822            }
17823            if (skipPackages != null && (skipPackages.length > 0)) {
17824                for (String skipPackage : skipPackages) {
17825                    if (skipPackage != null) {
17826                        int NT = receivers.size();
17827                        for (int it=0; it<NT; it++) {
17828                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17829                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17830                                receivers.remove(it);
17831                                it--;
17832                                NT--;
17833                            }
17834                        }
17835                    }
17836                }
17837            }
17838
17839            int NT = receivers != null ? receivers.size() : 0;
17840            int it = 0;
17841            ResolveInfo curt = null;
17842            BroadcastFilter curr = null;
17843            while (it < NT && ir < NR) {
17844                if (curt == null) {
17845                    curt = (ResolveInfo)receivers.get(it);
17846                }
17847                if (curr == null) {
17848                    curr = registeredReceivers.get(ir);
17849                }
17850                if (curr.getPriority() >= curt.priority) {
17851                    // Insert this broadcast record into the final list.
17852                    receivers.add(it, curr);
17853                    ir++;
17854                    curr = null;
17855                    it++;
17856                    NT++;
17857                } else {
17858                    // Skip to the next ResolveInfo in the final list.
17859                    it++;
17860                    curt = null;
17861                }
17862            }
17863        }
17864        while (ir < NR) {
17865            if (receivers == null) {
17866                receivers = new ArrayList();
17867            }
17868            receivers.add(registeredReceivers.get(ir));
17869            ir++;
17870        }
17871
17872        if ((receivers != null && receivers.size() > 0)
17873                || resultTo != null) {
17874            BroadcastQueue queue = broadcastQueueForIntent(intent);
17875            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17876                    callerPackage, callingPid, callingUid, resolvedType,
17877                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17878                    resultData, resultExtras, ordered, sticky, false, userId);
17879
17880            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17881                    + ": prev had " + queue.mOrderedBroadcasts.size());
17882            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17883                    "Enqueueing broadcast " + r.intent.getAction());
17884
17885            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17886            if (!replaced) {
17887                queue.enqueueOrderedBroadcastLocked(r);
17888                queue.scheduleBroadcastsLocked();
17889            }
17890        }
17891
17892        return ActivityManager.BROADCAST_SUCCESS;
17893    }
17894
17895    final Intent verifyBroadcastLocked(Intent intent) {
17896        // Refuse possible leaked file descriptors
17897        if (intent != null && intent.hasFileDescriptors() == true) {
17898            throw new IllegalArgumentException("File descriptors passed in Intent");
17899        }
17900
17901        int flags = intent.getFlags();
17902
17903        if (!mProcessesReady) {
17904            // if the caller really truly claims to know what they're doing, go
17905            // ahead and allow the broadcast without launching any receivers
17906            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17907                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17908            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17909                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17910                        + " before boot completion");
17911                throw new IllegalStateException("Cannot broadcast before boot completed");
17912            }
17913        }
17914
17915        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17916            throw new IllegalArgumentException(
17917                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17918        }
17919
17920        return intent;
17921    }
17922
17923    public final int broadcastIntent(IApplicationThread caller,
17924            Intent intent, String resolvedType, IIntentReceiver resultTo,
17925            int resultCode, String resultData, Bundle resultExtras,
17926            String[] requiredPermissions, int appOp, Bundle bOptions,
17927            boolean serialized, boolean sticky, int userId) {
17928        enforceNotIsolatedCaller("broadcastIntent");
17929        synchronized(this) {
17930            intent = verifyBroadcastLocked(intent);
17931
17932            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17933            final int callingPid = Binder.getCallingPid();
17934            final int callingUid = Binder.getCallingUid();
17935            final long origId = Binder.clearCallingIdentity();
17936            int res = broadcastIntentLocked(callerApp,
17937                    callerApp != null ? callerApp.info.packageName : null,
17938                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17939                    requiredPermissions, appOp, bOptions, serialized, sticky,
17940                    callingPid, callingUid, userId);
17941            Binder.restoreCallingIdentity(origId);
17942            return res;
17943        }
17944    }
17945
17946
17947    int broadcastIntentInPackage(String packageName, int uid,
17948            Intent intent, String resolvedType, IIntentReceiver resultTo,
17949            int resultCode, String resultData, Bundle resultExtras,
17950            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17951            int userId) {
17952        synchronized(this) {
17953            intent = verifyBroadcastLocked(intent);
17954
17955            final long origId = Binder.clearCallingIdentity();
17956            String[] requiredPermissions = requiredPermission == null ? null
17957                    : new String[] {requiredPermission};
17958            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17959                    resultTo, resultCode, resultData, resultExtras,
17960                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17961                    sticky, -1, uid, userId);
17962            Binder.restoreCallingIdentity(origId);
17963            return res;
17964        }
17965    }
17966
17967    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17968        // Refuse possible leaked file descriptors
17969        if (intent != null && intent.hasFileDescriptors() == true) {
17970            throw new IllegalArgumentException("File descriptors passed in Intent");
17971        }
17972
17973        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17974                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17975
17976        synchronized(this) {
17977            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17978                    != PackageManager.PERMISSION_GRANTED) {
17979                String msg = "Permission Denial: unbroadcastIntent() from pid="
17980                        + Binder.getCallingPid()
17981                        + ", uid=" + Binder.getCallingUid()
17982                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17983                Slog.w(TAG, msg);
17984                throw new SecurityException(msg);
17985            }
17986            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17987            if (stickies != null) {
17988                ArrayList<Intent> list = stickies.get(intent.getAction());
17989                if (list != null) {
17990                    int N = list.size();
17991                    int i;
17992                    for (i=0; i<N; i++) {
17993                        if (intent.filterEquals(list.get(i))) {
17994                            list.remove(i);
17995                            break;
17996                        }
17997                    }
17998                    if (list.size() <= 0) {
17999                        stickies.remove(intent.getAction());
18000                    }
18001                }
18002                if (stickies.size() <= 0) {
18003                    mStickyBroadcasts.remove(userId);
18004                }
18005            }
18006        }
18007    }
18008
18009    void backgroundServicesFinishedLocked(int userId) {
18010        for (BroadcastQueue queue : mBroadcastQueues) {
18011            queue.backgroundServicesFinishedLocked(userId);
18012        }
18013    }
18014
18015    public void finishReceiver(IBinder who, int resultCode, String resultData,
18016            Bundle resultExtras, boolean resultAbort, int flags) {
18017        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18018
18019        // Refuse possible leaked file descriptors
18020        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18021            throw new IllegalArgumentException("File descriptors passed in Bundle");
18022        }
18023
18024        final long origId = Binder.clearCallingIdentity();
18025        try {
18026            boolean doNext = false;
18027            BroadcastRecord r;
18028
18029            synchronized(this) {
18030                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18031                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18032                r = queue.getMatchingOrderedReceiver(who);
18033                if (r != null) {
18034                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18035                        resultData, resultExtras, resultAbort, true);
18036                }
18037            }
18038
18039            if (doNext) {
18040                r.queue.processNextBroadcast(false);
18041            }
18042            trimApplications();
18043        } finally {
18044            Binder.restoreCallingIdentity(origId);
18045        }
18046    }
18047
18048    // =========================================================
18049    // INSTRUMENTATION
18050    // =========================================================
18051
18052    public boolean startInstrumentation(ComponentName className,
18053            String profileFile, int flags, Bundle arguments,
18054            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18055            int userId, String abiOverride) {
18056        enforceNotIsolatedCaller("startInstrumentation");
18057        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18058                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18059        // Refuse possible leaked file descriptors
18060        if (arguments != null && arguments.hasFileDescriptors()) {
18061            throw new IllegalArgumentException("File descriptors passed in Bundle");
18062        }
18063
18064        synchronized(this) {
18065            InstrumentationInfo ii = null;
18066            ApplicationInfo ai = null;
18067            try {
18068                ii = mContext.getPackageManager().getInstrumentationInfo(
18069                    className, STOCK_PM_FLAGS);
18070                ai = AppGlobals.getPackageManager().getApplicationInfo(
18071                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18072            } catch (PackageManager.NameNotFoundException e) {
18073            } catch (RemoteException e) {
18074            }
18075            if (ii == null) {
18076                reportStartInstrumentationFailureLocked(watcher, className,
18077                        "Unable to find instrumentation info for: " + className);
18078                return false;
18079            }
18080            if (ai == null) {
18081                reportStartInstrumentationFailureLocked(watcher, className,
18082                        "Unable to find instrumentation target package: " + ii.targetPackage);
18083                return false;
18084            }
18085            if (!ai.hasCode()) {
18086                reportStartInstrumentationFailureLocked(watcher, className,
18087                        "Instrumentation target has no code: " + ii.targetPackage);
18088                return false;
18089            }
18090
18091            int match = mContext.getPackageManager().checkSignatures(
18092                    ii.targetPackage, ii.packageName);
18093            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18094                String msg = "Permission Denial: starting instrumentation "
18095                        + className + " from pid="
18096                        + Binder.getCallingPid()
18097                        + ", uid=" + Binder.getCallingPid()
18098                        + " not allowed because package " + ii.packageName
18099                        + " does not have a signature matching the target "
18100                        + ii.targetPackage;
18101                reportStartInstrumentationFailureLocked(watcher, className, msg);
18102                throw new SecurityException(msg);
18103            }
18104
18105            final long origId = Binder.clearCallingIdentity();
18106            // Instrumentation can kill and relaunch even persistent processes
18107            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18108                    "start instr");
18109            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18110            app.instrumentationClass = className;
18111            app.instrumentationInfo = ai;
18112            app.instrumentationProfileFile = profileFile;
18113            app.instrumentationArguments = arguments;
18114            app.instrumentationWatcher = watcher;
18115            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18116            app.instrumentationResultClass = className;
18117            Binder.restoreCallingIdentity(origId);
18118        }
18119
18120        return true;
18121    }
18122
18123    /**
18124     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18125     * error to the logs, but if somebody is watching, send the report there too.  This enables
18126     * the "am" command to report errors with more information.
18127     *
18128     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18129     * @param cn The component name of the instrumentation.
18130     * @param report The error report.
18131     */
18132    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18133            ComponentName cn, String report) {
18134        Slog.w(TAG, report);
18135        if (watcher != null) {
18136            Bundle results = new Bundle();
18137            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18138            results.putString("Error", report);
18139            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18140        }
18141    }
18142
18143    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18144        if (app.instrumentationWatcher != null) {
18145            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18146                    app.instrumentationClass, resultCode, results);
18147        }
18148
18149        // Can't call out of the system process with a lock held, so post a message.
18150        if (app.instrumentationUiAutomationConnection != null) {
18151            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18152                    app.instrumentationUiAutomationConnection).sendToTarget();
18153        }
18154
18155        app.instrumentationWatcher = null;
18156        app.instrumentationUiAutomationConnection = null;
18157        app.instrumentationClass = null;
18158        app.instrumentationInfo = null;
18159        app.instrumentationProfileFile = null;
18160        app.instrumentationArguments = null;
18161
18162        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18163                "finished inst");
18164    }
18165
18166    public void finishInstrumentation(IApplicationThread target,
18167            int resultCode, Bundle results) {
18168        int userId = UserHandle.getCallingUserId();
18169        // Refuse possible leaked file descriptors
18170        if (results != null && results.hasFileDescriptors()) {
18171            throw new IllegalArgumentException("File descriptors passed in Intent");
18172        }
18173
18174        synchronized(this) {
18175            ProcessRecord app = getRecordForAppLocked(target);
18176            if (app == null) {
18177                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18178                return;
18179            }
18180            final long origId = Binder.clearCallingIdentity();
18181            finishInstrumentationLocked(app, resultCode, results);
18182            Binder.restoreCallingIdentity(origId);
18183        }
18184    }
18185
18186    // =========================================================
18187    // CONFIGURATION
18188    // =========================================================
18189
18190    public ConfigurationInfo getDeviceConfigurationInfo() {
18191        ConfigurationInfo config = new ConfigurationInfo();
18192        synchronized (this) {
18193            config.reqTouchScreen = mConfiguration.touchscreen;
18194            config.reqKeyboardType = mConfiguration.keyboard;
18195            config.reqNavigation = mConfiguration.navigation;
18196            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18197                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18198                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18199            }
18200            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18201                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18202                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18203            }
18204            config.reqGlEsVersion = GL_ES_VERSION;
18205        }
18206        return config;
18207    }
18208
18209    ActivityStack getFocusedStack() {
18210        return mStackSupervisor.getFocusedStack();
18211    }
18212
18213    @Override
18214    public int getFocusedStackId() throws RemoteException {
18215        ActivityStack focusedStack = getFocusedStack();
18216        if (focusedStack != null) {
18217            return focusedStack.getStackId();
18218        }
18219        return -1;
18220    }
18221
18222    public Configuration getConfiguration() {
18223        Configuration ci;
18224        synchronized(this) {
18225            ci = new Configuration(mConfiguration);
18226            ci.userSetLocale = false;
18227        }
18228        return ci;
18229    }
18230
18231    @Override
18232    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18233        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18234        synchronized (this) {
18235            mSuppressResizeConfigChanges = suppress;
18236        }
18237    }
18238
18239    @Override
18240    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18241        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18242        if (fromStackId == HOME_STACK_ID) {
18243            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18244        }
18245        synchronized (this) {
18246            final long origId = Binder.clearCallingIdentity();
18247            try {
18248                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18249            } finally {
18250                Binder.restoreCallingIdentity(origId);
18251            }
18252        }
18253    }
18254
18255    @Override
18256    public void updatePersistentConfiguration(Configuration values) {
18257        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18258                "updateConfiguration()");
18259        enforceWriteSettingsPermission("updateConfiguration()");
18260        if (values == null) {
18261            throw new NullPointerException("Configuration must not be null");
18262        }
18263
18264        int userId = UserHandle.getCallingUserId();
18265
18266        synchronized(this) {
18267            final long origId = Binder.clearCallingIdentity();
18268            updateConfigurationLocked(values, null, false, true, userId);
18269            Binder.restoreCallingIdentity(origId);
18270        }
18271    }
18272
18273    private void updateFontScaleIfNeeded() {
18274        final int currentUserId;
18275        synchronized(this) {
18276            currentUserId = mUserController.getCurrentUserIdLocked();
18277        }
18278        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18279                FONT_SCALE, 1.0f, currentUserId);
18280        if (mConfiguration.fontScale != scaleFactor) {
18281            final Configuration configuration = mWindowManager.computeNewConfiguration();
18282            configuration.fontScale = scaleFactor;
18283            updatePersistentConfiguration(configuration);
18284        }
18285    }
18286
18287    private void enforceWriteSettingsPermission(String func) {
18288        int uid = Binder.getCallingUid();
18289        if (uid == Process.ROOT_UID) {
18290            return;
18291        }
18292
18293        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18294                Settings.getPackageNameForUid(mContext, uid), false)) {
18295            return;
18296        }
18297
18298        String msg = "Permission Denial: " + func + " from pid="
18299                + Binder.getCallingPid()
18300                + ", uid=" + uid
18301                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18302        Slog.w(TAG, msg);
18303        throw new SecurityException(msg);
18304    }
18305
18306    public void updateConfiguration(Configuration values) {
18307        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18308                "updateConfiguration()");
18309
18310        synchronized(this) {
18311            if (values == null && mWindowManager != null) {
18312                // sentinel: fetch the current configuration from the window manager
18313                values = mWindowManager.computeNewConfiguration();
18314            }
18315
18316            if (mWindowManager != null) {
18317                mProcessList.applyDisplaySize(mWindowManager);
18318            }
18319
18320            final long origId = Binder.clearCallingIdentity();
18321            if (values != null) {
18322                Settings.System.clearConfiguration(values);
18323            }
18324            updateConfigurationLocked(values, null, false);
18325            Binder.restoreCallingIdentity(origId);
18326        }
18327    }
18328
18329    void updateUserConfigurationLocked() {
18330        Configuration configuration = new Configuration(mConfiguration);
18331        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18332                mUserController.getCurrentUserIdLocked());
18333        updateConfigurationLocked(configuration, null, false);
18334    }
18335
18336    boolean updateConfigurationLocked(Configuration values,
18337            ActivityRecord starting, boolean initLocale) {
18338        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18339        return updateConfigurationLocked(values, starting, initLocale, false,
18340                UserHandle.USER_NULL);
18341    }
18342
18343    // To cache the list of supported system locales
18344    private String[] mSupportedSystemLocales = null;
18345
18346    /**
18347     * Do either or both things: (1) change the current configuration, and (2)
18348     * make sure the given activity is running with the (now) current
18349     * configuration.  Returns true if the activity has been left running, or
18350     * false if <var>starting</var> is being destroyed to match the new
18351     * configuration.
18352     *
18353     * @param userId is only used when persistent parameter is set to true to persist configuration
18354     *               for that particular user
18355     */
18356    private boolean updateConfigurationLocked(Configuration values,
18357            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18358        int changes = 0;
18359
18360        if (mWindowManager != null) {
18361            mWindowManager.deferSurfaceLayout();
18362        }
18363        if (values != null) {
18364            Configuration newConfig = new Configuration(mConfiguration);
18365            changes = newConfig.updateFrom(values);
18366            if (changes != 0) {
18367                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18368                        "Updating configuration to: " + values);
18369
18370                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18371
18372                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18373                    final LocaleList locales = values.getLocales();
18374                    int bestLocaleIndex = 0;
18375                    if (locales.size() > 1) {
18376                        if (mSupportedSystemLocales == null) {
18377                            mSupportedSystemLocales =
18378                                    Resources.getSystem().getAssets().getLocales();
18379                        }
18380                        bestLocaleIndex = Math.max(0,
18381                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18382                    }
18383                    SystemProperties.set("persist.sys.locale",
18384                            locales.get(bestLocaleIndex).toLanguageTag());
18385                    LocaleList.setDefault(locales, bestLocaleIndex);
18386                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18387                            locales.get(bestLocaleIndex)));
18388                }
18389
18390                mConfigurationSeq++;
18391                if (mConfigurationSeq <= 0) {
18392                    mConfigurationSeq = 1;
18393                }
18394                newConfig.seq = mConfigurationSeq;
18395                mConfiguration = newConfig;
18396                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18397                mUsageStatsService.reportConfigurationChange(newConfig,
18398                        mUserController.getCurrentUserIdLocked());
18399                //mUsageStatsService.noteStartConfig(newConfig);
18400
18401                final Configuration configCopy = new Configuration(mConfiguration);
18402
18403                // TODO: If our config changes, should we auto dismiss any currently
18404                // showing dialogs?
18405                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18406
18407                AttributeCache ac = AttributeCache.instance();
18408                if (ac != null) {
18409                    ac.updateConfiguration(configCopy);
18410                }
18411
18412                // Make sure all resources in our process are updated
18413                // right now, so that anyone who is going to retrieve
18414                // resource values after we return will be sure to get
18415                // the new ones.  This is especially important during
18416                // boot, where the first config change needs to guarantee
18417                // all resources have that config before following boot
18418                // code is executed.
18419                mSystemThread.applyConfigurationToResources(configCopy);
18420
18421                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18422                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18423                    msg.obj = new Configuration(configCopy);
18424                    msg.arg1 = userId;
18425                    mHandler.sendMessage(msg);
18426                }
18427
18428                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18429                if (isDensityChange) {
18430                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18431                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18432                }
18433
18434                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18435                    ProcessRecord app = mLruProcesses.get(i);
18436                    try {
18437                        if (app.thread != null) {
18438                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18439                                    + app.processName + " new config " + mConfiguration);
18440                            app.thread.scheduleConfigurationChanged(configCopy);
18441                        }
18442                    } catch (Exception e) {
18443                    }
18444                }
18445                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18446                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18447                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18448                        | Intent.FLAG_RECEIVER_FOREGROUND);
18449                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18450                        null, AppOpsManager.OP_NONE, null, false, false,
18451                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18452                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18453                    // Tell the shortcut manager that the system locale changed.  It needs to know
18454                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18455                    // we "push" from here, rather than having the service listen to the broadcast.
18456                    final ShortcutServiceInternal shortcutService =
18457                            LocalServices.getService(ShortcutServiceInternal.class);
18458                    if (shortcutService != null) {
18459                        shortcutService.onSystemLocaleChangedNoLock();
18460                    }
18461
18462                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18463                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18464                    if (!mProcessesReady) {
18465                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18466                    }
18467                    broadcastIntentLocked(null, null, intent,
18468                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18469                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18470                }
18471            }
18472            // Update the configuration with WM first and check if any of the stacks need to be
18473            // resized due to the configuration change. If so, resize the stacks now and do any
18474            // relaunches if necessary. This way we don't need to relaunch again below in
18475            // ensureActivityConfigurationLocked().
18476            if (mWindowManager != null) {
18477                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18478                if (resizedStacks != null) {
18479                    for (int stackId : resizedStacks) {
18480                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18481                        mStackSupervisor.resizeStackLocked(
18482                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18483                    }
18484                }
18485            }
18486        }
18487
18488        boolean kept = true;
18489        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18490        // mainStack is null during startup.
18491        if (mainStack != null) {
18492            if (changes != 0 && starting == null) {
18493                // If the configuration changed, and the caller is not already
18494                // in the process of starting an activity, then find the top
18495                // activity to check if its configuration needs to change.
18496                starting = mainStack.topRunningActivityLocked();
18497            }
18498
18499            if (starting != null) {
18500                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18501                // And we need to make sure at this point that all other activities
18502                // are made visible with the correct configuration.
18503                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18504                        !PRESERVE_WINDOWS);
18505            }
18506        }
18507        if (mWindowManager != null) {
18508            mWindowManager.continueSurfaceLayout();
18509        }
18510        return kept;
18511    }
18512
18513    /**
18514     * Decide based on the configuration whether we should shouw the ANR,
18515     * crash, etc dialogs.  The idea is that if there is no affordnace to
18516     * press the on-screen buttons, we shouldn't show the dialog.
18517     *
18518     * A thought: SystemUI might also want to get told about this, the Power
18519     * dialog / global actions also might want different behaviors.
18520     */
18521    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18522        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18523                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18524                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18525        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18526                                    == Configuration.UI_MODE_TYPE_CAR);
18527        return inputMethodExists && uiIsNotCarType && !inVrMode;
18528    }
18529
18530    @Override
18531    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18532        synchronized (this) {
18533            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18534            if (srec != null) {
18535                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18536            }
18537        }
18538        return false;
18539    }
18540
18541    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18542            Intent resultData) {
18543
18544        synchronized (this) {
18545            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18546            if (r != null) {
18547                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18548            }
18549            return false;
18550        }
18551    }
18552
18553    public int getLaunchedFromUid(IBinder activityToken) {
18554        ActivityRecord srec;
18555        synchronized (this) {
18556            srec = ActivityRecord.forTokenLocked(activityToken);
18557        }
18558        if (srec == null) {
18559            return -1;
18560        }
18561        return srec.launchedFromUid;
18562    }
18563
18564    public String getLaunchedFromPackage(IBinder activityToken) {
18565        ActivityRecord srec;
18566        synchronized (this) {
18567            srec = ActivityRecord.forTokenLocked(activityToken);
18568        }
18569        if (srec == null) {
18570            return null;
18571        }
18572        return srec.launchedFromPackage;
18573    }
18574
18575    // =========================================================
18576    // LIFETIME MANAGEMENT
18577    // =========================================================
18578
18579    // Returns which broadcast queue the app is the current [or imminent] receiver
18580    // on, or 'null' if the app is not an active broadcast recipient.
18581    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18582        BroadcastRecord r = app.curReceiver;
18583        if (r != null) {
18584            return r.queue;
18585        }
18586
18587        // It's not the current receiver, but it might be starting up to become one
18588        synchronized (this) {
18589            for (BroadcastQueue queue : mBroadcastQueues) {
18590                r = queue.mPendingBroadcast;
18591                if (r != null && r.curApp == app) {
18592                    // found it; report which queue it's in
18593                    return queue;
18594                }
18595            }
18596        }
18597
18598        return null;
18599    }
18600
18601    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18602            int targetUid, ComponentName targetComponent, String targetProcess) {
18603        if (!mTrackingAssociations) {
18604            return null;
18605        }
18606        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18607                = mAssociations.get(targetUid);
18608        if (components == null) {
18609            components = new ArrayMap<>();
18610            mAssociations.put(targetUid, components);
18611        }
18612        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18613        if (sourceUids == null) {
18614            sourceUids = new SparseArray<>();
18615            components.put(targetComponent, sourceUids);
18616        }
18617        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18618        if (sourceProcesses == null) {
18619            sourceProcesses = new ArrayMap<>();
18620            sourceUids.put(sourceUid, sourceProcesses);
18621        }
18622        Association ass = sourceProcesses.get(sourceProcess);
18623        if (ass == null) {
18624            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18625                    targetProcess);
18626            sourceProcesses.put(sourceProcess, ass);
18627        }
18628        ass.mCount++;
18629        ass.mNesting++;
18630        if (ass.mNesting == 1) {
18631            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18632            ass.mLastState = sourceState;
18633        }
18634        return ass;
18635    }
18636
18637    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18638            ComponentName targetComponent) {
18639        if (!mTrackingAssociations) {
18640            return;
18641        }
18642        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18643                = mAssociations.get(targetUid);
18644        if (components == null) {
18645            return;
18646        }
18647        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18648        if (sourceUids == null) {
18649            return;
18650        }
18651        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18652        if (sourceProcesses == null) {
18653            return;
18654        }
18655        Association ass = sourceProcesses.get(sourceProcess);
18656        if (ass == null || ass.mNesting <= 0) {
18657            return;
18658        }
18659        ass.mNesting--;
18660        if (ass.mNesting == 0) {
18661            long uptime = SystemClock.uptimeMillis();
18662            ass.mTime += uptime - ass.mStartTime;
18663            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18664                    += uptime - ass.mLastStateUptime;
18665            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18666        }
18667    }
18668
18669    private void noteUidProcessState(final int uid, final int state) {
18670        mBatteryStatsService.noteUidProcessState(uid, state);
18671        if (mTrackingAssociations) {
18672            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18673                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18674                        = mAssociations.valueAt(i1);
18675                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18676                    SparseArray<ArrayMap<String, Association>> sourceUids
18677                            = targetComponents.valueAt(i2);
18678                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18679                    if (sourceProcesses != null) {
18680                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18681                            Association ass = sourceProcesses.valueAt(i4);
18682                            if (ass.mNesting >= 1) {
18683                                // currently associated
18684                                long uptime = SystemClock.uptimeMillis();
18685                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18686                                        += uptime - ass.mLastStateUptime;
18687                                ass.mLastState = state;
18688                                ass.mLastStateUptime = uptime;
18689                            }
18690                        }
18691                    }
18692                }
18693            }
18694        }
18695    }
18696
18697    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18698            boolean doingAll, long now) {
18699        if (mAdjSeq == app.adjSeq) {
18700            // This adjustment has already been computed.
18701            return app.curRawAdj;
18702        }
18703
18704        if (app.thread == null) {
18705            app.adjSeq = mAdjSeq;
18706            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18707            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18708            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18709        }
18710
18711        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18712        app.adjSource = null;
18713        app.adjTarget = null;
18714        app.empty = false;
18715        app.cached = false;
18716
18717        final int activitiesSize = app.activities.size();
18718
18719        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18720            // The max adjustment doesn't allow this app to be anything
18721            // below foreground, so it is not worth doing work for it.
18722            app.adjType = "fixed";
18723            app.adjSeq = mAdjSeq;
18724            app.curRawAdj = app.maxAdj;
18725            app.foregroundActivities = false;
18726            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18727            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18728            // System processes can do UI, and when they do we want to have
18729            // them trim their memory after the user leaves the UI.  To
18730            // facilitate this, here we need to determine whether or not it
18731            // is currently showing UI.
18732            app.systemNoUi = true;
18733            if (app == TOP_APP) {
18734                app.systemNoUi = false;
18735                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18736                app.adjType = "pers-top-activity";
18737            } else if (activitiesSize > 0) {
18738                for (int j = 0; j < activitiesSize; j++) {
18739                    final ActivityRecord r = app.activities.get(j);
18740                    if (r.visible) {
18741                        app.systemNoUi = false;
18742                    }
18743                }
18744            }
18745            if (!app.systemNoUi) {
18746                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18747            }
18748            return (app.curAdj=app.maxAdj);
18749        }
18750
18751        app.systemNoUi = false;
18752
18753        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18754
18755        // Determine the importance of the process, starting with most
18756        // important to least, and assign an appropriate OOM adjustment.
18757        int adj;
18758        int schedGroup;
18759        int procState;
18760        boolean foregroundActivities = false;
18761        BroadcastQueue queue;
18762        if (app == TOP_APP) {
18763            // The last app on the list is the foreground app.
18764            adj = ProcessList.FOREGROUND_APP_ADJ;
18765            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18766            app.adjType = "top-activity";
18767            foregroundActivities = true;
18768            procState = PROCESS_STATE_CUR_TOP;
18769        } else if (app.instrumentationClass != null) {
18770            // Don't want to kill running instrumentation.
18771            adj = ProcessList.FOREGROUND_APP_ADJ;
18772            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18773            app.adjType = "instrumentation";
18774            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18775        } else if ((queue = isReceivingBroadcast(app)) != null) {
18776            // An app that is currently receiving a broadcast also
18777            // counts as being in the foreground for OOM killer purposes.
18778            // It's placed in a sched group based on the nature of the
18779            // broadcast as reflected by which queue it's active in.
18780            adj = ProcessList.FOREGROUND_APP_ADJ;
18781            schedGroup = (queue == mFgBroadcastQueue)
18782                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18783            app.adjType = "broadcast";
18784            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18785        } else if (app.executingServices.size() > 0) {
18786            // An app that is currently executing a service callback also
18787            // counts as being in the foreground.
18788            adj = ProcessList.FOREGROUND_APP_ADJ;
18789            schedGroup = app.execServicesFg ?
18790                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18791            app.adjType = "exec-service";
18792            procState = ActivityManager.PROCESS_STATE_SERVICE;
18793            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18794        } else {
18795            // As far as we know the process is empty.  We may change our mind later.
18796            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18797            // At this point we don't actually know the adjustment.  Use the cached adj
18798            // value that the caller wants us to.
18799            adj = cachedAdj;
18800            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18801            app.cached = true;
18802            app.empty = true;
18803            app.adjType = "cch-empty";
18804        }
18805
18806        // Examine all activities if not already foreground.
18807        if (!foregroundActivities && activitiesSize > 0) {
18808            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18809            for (int j = 0; j < activitiesSize; j++) {
18810                final ActivityRecord r = app.activities.get(j);
18811                if (r.app != app) {
18812                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18813                            + " instead of expected " + app);
18814                    if (r.app == null || (r.app.uid == app.uid)) {
18815                        // Only fix things up when they look sane
18816                        r.app = app;
18817                    } else {
18818                        continue;
18819                    }
18820                }
18821                if (r.visible) {
18822                    // App has a visible activity; only upgrade adjustment.
18823                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18824                        adj = ProcessList.VISIBLE_APP_ADJ;
18825                        app.adjType = "visible";
18826                    }
18827                    if (procState > PROCESS_STATE_CUR_TOP) {
18828                        procState = PROCESS_STATE_CUR_TOP;
18829                    }
18830                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18831                    app.cached = false;
18832                    app.empty = false;
18833                    foregroundActivities = true;
18834                    if (r.task != null && minLayer > 0) {
18835                        final int layer = r.task.mLayerRank;
18836                        if (layer >= 0 && minLayer > layer) {
18837                            minLayer = layer;
18838                        }
18839                    }
18840                    break;
18841                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18842                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18843                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18844                        app.adjType = "pausing";
18845                    }
18846                    if (procState > PROCESS_STATE_CUR_TOP) {
18847                        procState = PROCESS_STATE_CUR_TOP;
18848                    }
18849                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18850                    app.cached = false;
18851                    app.empty = false;
18852                    foregroundActivities = true;
18853                } else if (r.state == ActivityState.STOPPING) {
18854                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18855                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18856                        app.adjType = "stopping";
18857                    }
18858                    // For the process state, we will at this point consider the
18859                    // process to be cached.  It will be cached either as an activity
18860                    // or empty depending on whether the activity is finishing.  We do
18861                    // this so that we can treat the process as cached for purposes of
18862                    // memory trimming (determing current memory level, trim command to
18863                    // send to process) since there can be an arbitrary number of stopping
18864                    // processes and they should soon all go into the cached state.
18865                    if (!r.finishing) {
18866                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18867                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18868                        }
18869                    }
18870                    app.cached = false;
18871                    app.empty = false;
18872                    foregroundActivities = true;
18873                } else {
18874                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18875                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18876                        app.adjType = "cch-act";
18877                    }
18878                }
18879            }
18880            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18881                adj += minLayer;
18882            }
18883        }
18884
18885        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18886                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18887            if (app.foregroundServices) {
18888                // The user is aware of this app, so make it visible.
18889                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18890                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18891                app.cached = false;
18892                app.adjType = "fg-service";
18893                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18894            } else if (app.forcingToForeground != null) {
18895                // The user is aware of this app, so make it visible.
18896                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18897                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18898                app.cached = false;
18899                app.adjType = "force-fg";
18900                app.adjSource = app.forcingToForeground;
18901                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18902            }
18903        }
18904
18905        if (app == mHeavyWeightProcess) {
18906            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18907                // We don't want to kill the current heavy-weight process.
18908                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18909                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18910                app.cached = false;
18911                app.adjType = "heavy";
18912            }
18913            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18914                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18915            }
18916        }
18917
18918        if (app == mHomeProcess) {
18919            if (adj > ProcessList.HOME_APP_ADJ) {
18920                // This process is hosting what we currently consider to be the
18921                // home app, so we don't want to let it go into the background.
18922                adj = ProcessList.HOME_APP_ADJ;
18923                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18924                app.cached = false;
18925                app.adjType = "home";
18926            }
18927            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18928                procState = ActivityManager.PROCESS_STATE_HOME;
18929            }
18930        }
18931
18932        if (app == mPreviousProcess && app.activities.size() > 0) {
18933            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18934                // This was the previous process that showed UI to the user.
18935                // We want to try to keep it around more aggressively, to give
18936                // a good experience around switching between two apps.
18937                adj = ProcessList.PREVIOUS_APP_ADJ;
18938                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18939                app.cached = false;
18940                app.adjType = "previous";
18941            }
18942            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18943                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18944            }
18945        }
18946
18947        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18948                + " reason=" + app.adjType);
18949
18950        // By default, we use the computed adjustment.  It may be changed if
18951        // there are applications dependent on our services or providers, but
18952        // this gives us a baseline and makes sure we don't get into an
18953        // infinite recursion.
18954        app.adjSeq = mAdjSeq;
18955        app.curRawAdj = adj;
18956        app.hasStartedServices = false;
18957
18958        if (mBackupTarget != null && app == mBackupTarget.app) {
18959            // If possible we want to avoid killing apps while they're being backed up
18960            if (adj > ProcessList.BACKUP_APP_ADJ) {
18961                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18962                adj = ProcessList.BACKUP_APP_ADJ;
18963                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18964                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18965                }
18966                app.adjType = "backup";
18967                app.cached = false;
18968            }
18969            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18970                procState = ActivityManager.PROCESS_STATE_BACKUP;
18971            }
18972        }
18973
18974        boolean mayBeTop = false;
18975
18976        for (int is = app.services.size()-1;
18977                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18978                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18979                        || procState > ActivityManager.PROCESS_STATE_TOP);
18980                is--) {
18981            ServiceRecord s = app.services.valueAt(is);
18982            if (s.startRequested) {
18983                app.hasStartedServices = true;
18984                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18985                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18986                }
18987                if (app.hasShownUi && app != mHomeProcess) {
18988                    // If this process has shown some UI, let it immediately
18989                    // go to the LRU list because it may be pretty heavy with
18990                    // UI stuff.  We'll tag it with a label just to help
18991                    // debug and understand what is going on.
18992                    if (adj > ProcessList.SERVICE_ADJ) {
18993                        app.adjType = "cch-started-ui-services";
18994                    }
18995                } else {
18996                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18997                        // This service has seen some activity within
18998                        // recent memory, so we will keep its process ahead
18999                        // of the background processes.
19000                        if (adj > ProcessList.SERVICE_ADJ) {
19001                            adj = ProcessList.SERVICE_ADJ;
19002                            app.adjType = "started-services";
19003                            app.cached = false;
19004                        }
19005                    }
19006                    // If we have let the service slide into the background
19007                    // state, still have some text describing what it is doing
19008                    // even though the service no longer has an impact.
19009                    if (adj > ProcessList.SERVICE_ADJ) {
19010                        app.adjType = "cch-started-services";
19011                    }
19012                }
19013            }
19014            for (int conni = s.connections.size()-1;
19015                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19016                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19017                            || procState > ActivityManager.PROCESS_STATE_TOP);
19018                    conni--) {
19019                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19020                for (int i = 0;
19021                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19022                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19023                                || procState > ActivityManager.PROCESS_STATE_TOP);
19024                        i++) {
19025                    // XXX should compute this based on the max of
19026                    // all connected clients.
19027                    ConnectionRecord cr = clist.get(i);
19028                    if (cr.binding.client == app) {
19029                        // Binding to ourself is not interesting.
19030                        continue;
19031                    }
19032                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19033                        ProcessRecord client = cr.binding.client;
19034                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19035                                TOP_APP, doingAll, now);
19036                        int clientProcState = client.curProcState;
19037                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19038                            // If the other app is cached for any reason, for purposes here
19039                            // we are going to consider it empty.  The specific cached state
19040                            // doesn't propagate except under certain conditions.
19041                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19042                        }
19043                        String adjType = null;
19044                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19045                            // Not doing bind OOM management, so treat
19046                            // this guy more like a started service.
19047                            if (app.hasShownUi && app != mHomeProcess) {
19048                                // If this process has shown some UI, let it immediately
19049                                // go to the LRU list because it may be pretty heavy with
19050                                // UI stuff.  We'll tag it with a label just to help
19051                                // debug and understand what is going on.
19052                                if (adj > clientAdj) {
19053                                    adjType = "cch-bound-ui-services";
19054                                }
19055                                app.cached = false;
19056                                clientAdj = adj;
19057                                clientProcState = procState;
19058                            } else {
19059                                if (now >= (s.lastActivity
19060                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19061                                    // This service has not seen activity within
19062                                    // recent memory, so allow it to drop to the
19063                                    // LRU list if there is no other reason to keep
19064                                    // it around.  We'll also tag it with a label just
19065                                    // to help debug and undertand what is going on.
19066                                    if (adj > clientAdj) {
19067                                        adjType = "cch-bound-services";
19068                                    }
19069                                    clientAdj = adj;
19070                                }
19071                            }
19072                        }
19073                        if (adj > clientAdj) {
19074                            // If this process has recently shown UI, and
19075                            // the process that is binding to it is less
19076                            // important than being visible, then we don't
19077                            // care about the binding as much as we care
19078                            // about letting this process get into the LRU
19079                            // list to be killed and restarted if needed for
19080                            // memory.
19081                            if (app.hasShownUi && app != mHomeProcess
19082                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19083                                adjType = "cch-bound-ui-services";
19084                            } else {
19085                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19086                                        |Context.BIND_IMPORTANT)) != 0) {
19087                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19088                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19089                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19090                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19091                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19092                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19093                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19094                                    adj = clientAdj;
19095                                } else {
19096                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19097                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19098                                    }
19099                                }
19100                                if (!client.cached) {
19101                                    app.cached = false;
19102                                }
19103                                adjType = "service";
19104                            }
19105                        }
19106                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19107                            // This will treat important bound services identically to
19108                            // the top app, which may behave differently than generic
19109                            // foreground work.
19110                            if (client.curSchedGroup > schedGroup) {
19111                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19112                                    schedGroup = client.curSchedGroup;
19113                                } else {
19114                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19115                                }
19116                            }
19117                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19118                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19119                                    // Special handling of clients who are in the top state.
19120                                    // We *may* want to consider this process to be in the
19121                                    // top state as well, but only if there is not another
19122                                    // reason for it to be running.  Being on the top is a
19123                                    // special state, meaning you are specifically running
19124                                    // for the current top app.  If the process is already
19125                                    // running in the background for some other reason, it
19126                                    // is more important to continue considering it to be
19127                                    // in the background state.
19128                                    mayBeTop = true;
19129                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19130                                } else {
19131                                    // Special handling for above-top states (persistent
19132                                    // processes).  These should not bring the current process
19133                                    // into the top state, since they are not on top.  Instead
19134                                    // give them the best state after that.
19135                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19136                                        clientProcState =
19137                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19138                                    } else if (mWakefulness
19139                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19140                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19141                                                    != 0) {
19142                                        clientProcState =
19143                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19144                                    } else {
19145                                        clientProcState =
19146                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19147                                    }
19148                                }
19149                            }
19150                        } else {
19151                            if (clientProcState <
19152                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19153                                clientProcState =
19154                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19155                            }
19156                        }
19157                        if (procState > clientProcState) {
19158                            procState = clientProcState;
19159                        }
19160                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19161                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19162                            app.pendingUiClean = true;
19163                        }
19164                        if (adjType != null) {
19165                            app.adjType = adjType;
19166                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19167                                    .REASON_SERVICE_IN_USE;
19168                            app.adjSource = cr.binding.client;
19169                            app.adjSourceProcState = clientProcState;
19170                            app.adjTarget = s.name;
19171                        }
19172                    }
19173                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19174                        app.treatLikeActivity = true;
19175                    }
19176                    final ActivityRecord a = cr.activity;
19177                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19178                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19179                            (a.visible || a.state == ActivityState.RESUMED ||
19180                             a.state == ActivityState.PAUSING)) {
19181                            adj = ProcessList.FOREGROUND_APP_ADJ;
19182                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19183                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19184                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19185                                } else {
19186                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19187                                }
19188                            }
19189                            app.cached = false;
19190                            app.adjType = "service";
19191                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19192                                    .REASON_SERVICE_IN_USE;
19193                            app.adjSource = a;
19194                            app.adjSourceProcState = procState;
19195                            app.adjTarget = s.name;
19196                        }
19197                    }
19198                }
19199            }
19200        }
19201
19202        for (int provi = app.pubProviders.size()-1;
19203                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19204                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19205                        || procState > ActivityManager.PROCESS_STATE_TOP);
19206                provi--) {
19207            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19208            for (int i = cpr.connections.size()-1;
19209                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19210                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19211                            || procState > ActivityManager.PROCESS_STATE_TOP);
19212                    i--) {
19213                ContentProviderConnection conn = cpr.connections.get(i);
19214                ProcessRecord client = conn.client;
19215                if (client == app) {
19216                    // Being our own client is not interesting.
19217                    continue;
19218                }
19219                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19220                int clientProcState = client.curProcState;
19221                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19222                    // If the other app is cached for any reason, for purposes here
19223                    // we are going to consider it empty.
19224                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19225                }
19226                if (adj > clientAdj) {
19227                    if (app.hasShownUi && app != mHomeProcess
19228                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19229                        app.adjType = "cch-ui-provider";
19230                    } else {
19231                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19232                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19233                        app.adjType = "provider";
19234                    }
19235                    app.cached &= client.cached;
19236                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19237                            .REASON_PROVIDER_IN_USE;
19238                    app.adjSource = client;
19239                    app.adjSourceProcState = clientProcState;
19240                    app.adjTarget = cpr.name;
19241                }
19242                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19243                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19244                        // Special handling of clients who are in the top state.
19245                        // We *may* want to consider this process to be in the
19246                        // top state as well, but only if there is not another
19247                        // reason for it to be running.  Being on the top is a
19248                        // special state, meaning you are specifically running
19249                        // for the current top app.  If the process is already
19250                        // running in the background for some other reason, it
19251                        // is more important to continue considering it to be
19252                        // in the background state.
19253                        mayBeTop = true;
19254                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19255                    } else {
19256                        // Special handling for above-top states (persistent
19257                        // processes).  These should not bring the current process
19258                        // into the top state, since they are not on top.  Instead
19259                        // give them the best state after that.
19260                        clientProcState =
19261                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19262                    }
19263                }
19264                if (procState > clientProcState) {
19265                    procState = clientProcState;
19266                }
19267                if (client.curSchedGroup > schedGroup) {
19268                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19269                }
19270            }
19271            // If the provider has external (non-framework) process
19272            // dependencies, ensure that its adjustment is at least
19273            // FOREGROUND_APP_ADJ.
19274            if (cpr.hasExternalProcessHandles()) {
19275                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19276                    adj = ProcessList.FOREGROUND_APP_ADJ;
19277                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19278                    app.cached = false;
19279                    app.adjType = "provider";
19280                    app.adjTarget = cpr.name;
19281                }
19282                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19283                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19284                }
19285            }
19286        }
19287
19288        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19289            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19290                adj = ProcessList.PREVIOUS_APP_ADJ;
19291                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19292                app.cached = false;
19293                app.adjType = "provider";
19294            }
19295            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19296                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19297            }
19298        }
19299
19300        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19301            // A client of one of our services or providers is in the top state.  We
19302            // *may* want to be in the top state, but not if we are already running in
19303            // the background for some other reason.  For the decision here, we are going
19304            // to pick out a few specific states that we want to remain in when a client
19305            // is top (states that tend to be longer-term) and otherwise allow it to go
19306            // to the top state.
19307            switch (procState) {
19308                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19309                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19310                case ActivityManager.PROCESS_STATE_SERVICE:
19311                    // These all are longer-term states, so pull them up to the top
19312                    // of the background states, but not all the way to the top state.
19313                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19314                    break;
19315                default:
19316                    // Otherwise, top is a better choice, so take it.
19317                    procState = ActivityManager.PROCESS_STATE_TOP;
19318                    break;
19319            }
19320        }
19321
19322        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19323            if (app.hasClientActivities) {
19324                // This is a cached process, but with client activities.  Mark it so.
19325                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19326                app.adjType = "cch-client-act";
19327            } else if (app.treatLikeActivity) {
19328                // This is a cached process, but somebody wants us to treat it like it has
19329                // an activity, okay!
19330                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19331                app.adjType = "cch-as-act";
19332            }
19333        }
19334
19335        if (adj == ProcessList.SERVICE_ADJ) {
19336            if (doingAll) {
19337                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19338                mNewNumServiceProcs++;
19339                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19340                if (!app.serviceb) {
19341                    // This service isn't far enough down on the LRU list to
19342                    // normally be a B service, but if we are low on RAM and it
19343                    // is large we want to force it down since we would prefer to
19344                    // keep launcher over it.
19345                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19346                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19347                        app.serviceHighRam = true;
19348                        app.serviceb = true;
19349                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19350                    } else {
19351                        mNewNumAServiceProcs++;
19352                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19353                    }
19354                } else {
19355                    app.serviceHighRam = false;
19356                }
19357            }
19358            if (app.serviceb) {
19359                adj = ProcessList.SERVICE_B_ADJ;
19360            }
19361        }
19362
19363        app.curRawAdj = adj;
19364
19365        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19366        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19367        if (adj > app.maxAdj) {
19368            adj = app.maxAdj;
19369            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19370                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19371            }
19372        }
19373
19374        // Do final modification to adj.  Everything we do between here and applying
19375        // the final setAdj must be done in this function, because we will also use
19376        // it when computing the final cached adj later.  Note that we don't need to
19377        // worry about this for max adj above, since max adj will always be used to
19378        // keep it out of the cached vaues.
19379        app.curAdj = app.modifyRawOomAdj(adj);
19380        app.curSchedGroup = schedGroup;
19381        app.curProcState = procState;
19382        app.foregroundActivities = foregroundActivities;
19383
19384        return app.curRawAdj;
19385    }
19386
19387    /**
19388     * Record new PSS sample for a process.
19389     */
19390    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19391            long now) {
19392        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19393                swapPss * 1024);
19394        proc.lastPssTime = now;
19395        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19396        if (DEBUG_PSS) Slog.d(TAG_PSS,
19397                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19398                + " state=" + ProcessList.makeProcStateString(procState));
19399        if (proc.initialIdlePss == 0) {
19400            proc.initialIdlePss = pss;
19401        }
19402        proc.lastPss = pss;
19403        proc.lastSwapPss = swapPss;
19404        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19405            proc.lastCachedPss = pss;
19406            proc.lastCachedSwapPss = swapPss;
19407        }
19408
19409        final SparseArray<Pair<Long, String>> watchUids
19410                = mMemWatchProcesses.getMap().get(proc.processName);
19411        Long check = null;
19412        if (watchUids != null) {
19413            Pair<Long, String> val = watchUids.get(proc.uid);
19414            if (val == null) {
19415                val = watchUids.get(0);
19416            }
19417            if (val != null) {
19418                check = val.first;
19419            }
19420        }
19421        if (check != null) {
19422            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19423                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19424                if (!isDebuggable) {
19425                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19426                        isDebuggable = true;
19427                    }
19428                }
19429                if (isDebuggable) {
19430                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19431                    final ProcessRecord myProc = proc;
19432                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19433                    mMemWatchDumpProcName = proc.processName;
19434                    mMemWatchDumpFile = heapdumpFile.toString();
19435                    mMemWatchDumpPid = proc.pid;
19436                    mMemWatchDumpUid = proc.uid;
19437                    BackgroundThread.getHandler().post(new Runnable() {
19438                        @Override
19439                        public void run() {
19440                            revokeUriPermission(ActivityThread.currentActivityThread()
19441                                            .getApplicationThread(),
19442                                    DumpHeapActivity.JAVA_URI,
19443                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19444                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19445                                    UserHandle.myUserId());
19446                            ParcelFileDescriptor fd = null;
19447                            try {
19448                                heapdumpFile.delete();
19449                                fd = ParcelFileDescriptor.open(heapdumpFile,
19450                                        ParcelFileDescriptor.MODE_CREATE |
19451                                                ParcelFileDescriptor.MODE_TRUNCATE |
19452                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19453                                                ParcelFileDescriptor.MODE_APPEND);
19454                                IApplicationThread thread = myProc.thread;
19455                                if (thread != null) {
19456                                    try {
19457                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19458                                                "Requesting dump heap from "
19459                                                + myProc + " to " + heapdumpFile);
19460                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19461                                    } catch (RemoteException e) {
19462                                    }
19463                                }
19464                            } catch (FileNotFoundException e) {
19465                                e.printStackTrace();
19466                            } finally {
19467                                if (fd != null) {
19468                                    try {
19469                                        fd.close();
19470                                    } catch (IOException e) {
19471                                    }
19472                                }
19473                            }
19474                        }
19475                    });
19476                } else {
19477                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19478                            + ", but debugging not enabled");
19479                }
19480            }
19481        }
19482    }
19483
19484    /**
19485     * Schedule PSS collection of a process.
19486     */
19487    void requestPssLocked(ProcessRecord proc, int procState) {
19488        if (mPendingPssProcesses.contains(proc)) {
19489            return;
19490        }
19491        if (mPendingPssProcesses.size() == 0) {
19492            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19493        }
19494        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19495        proc.pssProcState = procState;
19496        mPendingPssProcesses.add(proc);
19497    }
19498
19499    /**
19500     * Schedule PSS collection of all processes.
19501     */
19502    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19503        if (!always) {
19504            if (now < (mLastFullPssTime +
19505                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19506                return;
19507            }
19508        }
19509        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19510        mLastFullPssTime = now;
19511        mFullPssPending = true;
19512        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19513        mPendingPssProcesses.clear();
19514        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19515            ProcessRecord app = mLruProcesses.get(i);
19516            if (app.thread == null
19517                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19518                continue;
19519            }
19520            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19521                app.pssProcState = app.setProcState;
19522                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19523                        mTestPssMode, isSleeping(), now);
19524                mPendingPssProcesses.add(app);
19525            }
19526        }
19527        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19528    }
19529
19530    public void setTestPssMode(boolean enabled) {
19531        synchronized (this) {
19532            mTestPssMode = enabled;
19533            if (enabled) {
19534                // Whenever we enable the mode, we want to take a snapshot all of current
19535                // process mem use.
19536                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19537            }
19538        }
19539    }
19540
19541    /**
19542     * Ask a given process to GC right now.
19543     */
19544    final void performAppGcLocked(ProcessRecord app) {
19545        try {
19546            app.lastRequestedGc = SystemClock.uptimeMillis();
19547            if (app.thread != null) {
19548                if (app.reportLowMemory) {
19549                    app.reportLowMemory = false;
19550                    app.thread.scheduleLowMemory();
19551                } else {
19552                    app.thread.processInBackground();
19553                }
19554            }
19555        } catch (Exception e) {
19556            // whatever.
19557        }
19558    }
19559
19560    /**
19561     * Returns true if things are idle enough to perform GCs.
19562     */
19563    private final boolean canGcNowLocked() {
19564        boolean processingBroadcasts = false;
19565        for (BroadcastQueue q : mBroadcastQueues) {
19566            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19567                processingBroadcasts = true;
19568            }
19569        }
19570        return !processingBroadcasts
19571                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19572    }
19573
19574    /**
19575     * Perform GCs on all processes that are waiting for it, but only
19576     * if things are idle.
19577     */
19578    final void performAppGcsLocked() {
19579        final int N = mProcessesToGc.size();
19580        if (N <= 0) {
19581            return;
19582        }
19583        if (canGcNowLocked()) {
19584            while (mProcessesToGc.size() > 0) {
19585                ProcessRecord proc = mProcessesToGc.remove(0);
19586                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19587                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19588                            <= SystemClock.uptimeMillis()) {
19589                        // To avoid spamming the system, we will GC processes one
19590                        // at a time, waiting a few seconds between each.
19591                        performAppGcLocked(proc);
19592                        scheduleAppGcsLocked();
19593                        return;
19594                    } else {
19595                        // It hasn't been long enough since we last GCed this
19596                        // process...  put it in the list to wait for its time.
19597                        addProcessToGcListLocked(proc);
19598                        break;
19599                    }
19600                }
19601            }
19602
19603            scheduleAppGcsLocked();
19604        }
19605    }
19606
19607    /**
19608     * If all looks good, perform GCs on all processes waiting for them.
19609     */
19610    final void performAppGcsIfAppropriateLocked() {
19611        if (canGcNowLocked()) {
19612            performAppGcsLocked();
19613            return;
19614        }
19615        // Still not idle, wait some more.
19616        scheduleAppGcsLocked();
19617    }
19618
19619    /**
19620     * Schedule the execution of all pending app GCs.
19621     */
19622    final void scheduleAppGcsLocked() {
19623        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19624
19625        if (mProcessesToGc.size() > 0) {
19626            // Schedule a GC for the time to the next process.
19627            ProcessRecord proc = mProcessesToGc.get(0);
19628            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19629
19630            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19631            long now = SystemClock.uptimeMillis();
19632            if (when < (now+GC_TIMEOUT)) {
19633                when = now + GC_TIMEOUT;
19634            }
19635            mHandler.sendMessageAtTime(msg, when);
19636        }
19637    }
19638
19639    /**
19640     * Add a process to the array of processes waiting to be GCed.  Keeps the
19641     * list in sorted order by the last GC time.  The process can't already be
19642     * on the list.
19643     */
19644    final void addProcessToGcListLocked(ProcessRecord proc) {
19645        boolean added = false;
19646        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19647            if (mProcessesToGc.get(i).lastRequestedGc <
19648                    proc.lastRequestedGc) {
19649                added = true;
19650                mProcessesToGc.add(i+1, proc);
19651                break;
19652            }
19653        }
19654        if (!added) {
19655            mProcessesToGc.add(0, proc);
19656        }
19657    }
19658
19659    /**
19660     * Set up to ask a process to GC itself.  This will either do it
19661     * immediately, or put it on the list of processes to gc the next
19662     * time things are idle.
19663     */
19664    final void scheduleAppGcLocked(ProcessRecord app) {
19665        long now = SystemClock.uptimeMillis();
19666        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19667            return;
19668        }
19669        if (!mProcessesToGc.contains(app)) {
19670            addProcessToGcListLocked(app);
19671            scheduleAppGcsLocked();
19672        }
19673    }
19674
19675    final void checkExcessivePowerUsageLocked(boolean doKills) {
19676        updateCpuStatsNow();
19677
19678        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19679        boolean doWakeKills = doKills;
19680        boolean doCpuKills = doKills;
19681        if (mLastPowerCheckRealtime == 0) {
19682            doWakeKills = false;
19683        }
19684        if (mLastPowerCheckUptime == 0) {
19685            doCpuKills = false;
19686        }
19687        if (stats.isScreenOn()) {
19688            doWakeKills = false;
19689        }
19690        final long curRealtime = SystemClock.elapsedRealtime();
19691        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19692        final long curUptime = SystemClock.uptimeMillis();
19693        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19694        mLastPowerCheckRealtime = curRealtime;
19695        mLastPowerCheckUptime = curUptime;
19696        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19697            doWakeKills = false;
19698        }
19699        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19700            doCpuKills = false;
19701        }
19702        int i = mLruProcesses.size();
19703        while (i > 0) {
19704            i--;
19705            ProcessRecord app = mLruProcesses.get(i);
19706            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19707                long wtime;
19708                synchronized (stats) {
19709                    wtime = stats.getProcessWakeTime(app.info.uid,
19710                            app.pid, curRealtime);
19711                }
19712                long wtimeUsed = wtime - app.lastWakeTime;
19713                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19714                if (DEBUG_POWER) {
19715                    StringBuilder sb = new StringBuilder(128);
19716                    sb.append("Wake for ");
19717                    app.toShortString(sb);
19718                    sb.append(": over ");
19719                    TimeUtils.formatDuration(realtimeSince, sb);
19720                    sb.append(" used ");
19721                    TimeUtils.formatDuration(wtimeUsed, sb);
19722                    sb.append(" (");
19723                    sb.append((wtimeUsed*100)/realtimeSince);
19724                    sb.append("%)");
19725                    Slog.i(TAG_POWER, sb.toString());
19726                    sb.setLength(0);
19727                    sb.append("CPU for ");
19728                    app.toShortString(sb);
19729                    sb.append(": over ");
19730                    TimeUtils.formatDuration(uptimeSince, sb);
19731                    sb.append(" used ");
19732                    TimeUtils.formatDuration(cputimeUsed, sb);
19733                    sb.append(" (");
19734                    sb.append((cputimeUsed*100)/uptimeSince);
19735                    sb.append("%)");
19736                    Slog.i(TAG_POWER, sb.toString());
19737                }
19738                // If a process has held a wake lock for more
19739                // than 50% of the time during this period,
19740                // that sounds bad.  Kill!
19741                if (doWakeKills && realtimeSince > 0
19742                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19743                    synchronized (stats) {
19744                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19745                                realtimeSince, wtimeUsed);
19746                    }
19747                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19748                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19749                } else if (doCpuKills && uptimeSince > 0
19750                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19751                    synchronized (stats) {
19752                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19753                                uptimeSince, cputimeUsed);
19754                    }
19755                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19756                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19757                } else {
19758                    app.lastWakeTime = wtime;
19759                    app.lastCpuTime = app.curCpuTime;
19760                }
19761            }
19762        }
19763    }
19764
19765    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19766            long nowElapsed) {
19767        boolean success = true;
19768
19769        if (app.curRawAdj != app.setRawAdj) {
19770            app.setRawAdj = app.curRawAdj;
19771        }
19772
19773        int changes = 0;
19774
19775        if (app.curAdj != app.setAdj) {
19776            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19777            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19778                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19779                    + app.adjType);
19780            app.setAdj = app.curAdj;
19781        }
19782
19783        if (app.setSchedGroup != app.curSchedGroup) {
19784            app.setSchedGroup = app.curSchedGroup;
19785            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19786                    "Setting sched group of " + app.processName
19787                    + " to " + app.curSchedGroup);
19788            if (app.waitingToKill != null && app.curReceiver == null
19789                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19790                app.kill(app.waitingToKill, true);
19791                success = false;
19792            } else {
19793                int processGroup;
19794                switch (app.curSchedGroup) {
19795                    case ProcessList.SCHED_GROUP_BACKGROUND:
19796                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19797                        break;
19798                    case ProcessList.SCHED_GROUP_TOP_APP:
19799                        processGroup = Process.THREAD_GROUP_TOP_APP;
19800                        break;
19801                    default:
19802                        processGroup = Process.THREAD_GROUP_DEFAULT;
19803                        break;
19804                }
19805                if (true) {
19806                    long oldId = Binder.clearCallingIdentity();
19807                    try {
19808                        Process.setProcessGroup(app.pid, processGroup);
19809                    } catch (Exception e) {
19810                        Slog.w(TAG, "Failed setting process group of " + app.pid
19811                                + " to " + app.curSchedGroup);
19812                        e.printStackTrace();
19813                    } finally {
19814                        Binder.restoreCallingIdentity(oldId);
19815                    }
19816                } else {
19817                    if (app.thread != null) {
19818                        try {
19819                            app.thread.setSchedulingGroup(processGroup);
19820                        } catch (RemoteException e) {
19821                        }
19822                    }
19823                }
19824            }
19825        }
19826        if (app.repForegroundActivities != app.foregroundActivities) {
19827            app.repForegroundActivities = app.foregroundActivities;
19828            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19829        }
19830        if (app.repProcState != app.curProcState) {
19831            app.repProcState = app.curProcState;
19832            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19833            if (app.thread != null) {
19834                try {
19835                    if (false) {
19836                        //RuntimeException h = new RuntimeException("here");
19837                        Slog.i(TAG, "Sending new process state " + app.repProcState
19838                                + " to " + app /*, h*/);
19839                    }
19840                    app.thread.setProcessState(app.repProcState);
19841                } catch (RemoteException e) {
19842                }
19843            }
19844        }
19845        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19846                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19847            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19848                // Experimental code to more aggressively collect pss while
19849                // running test...  the problem is that this tends to collect
19850                // the data right when a process is transitioning between process
19851                // states, which well tend to give noisy data.
19852                long start = SystemClock.uptimeMillis();
19853                long pss = Debug.getPss(app.pid, mTmpLong, null);
19854                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19855                mPendingPssProcesses.remove(app);
19856                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19857                        + " to " + app.curProcState + ": "
19858                        + (SystemClock.uptimeMillis()-start) + "ms");
19859            }
19860            app.lastStateTime = now;
19861            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19862                    mTestPssMode, isSleeping(), now);
19863            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19864                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19865                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19866                    + (app.nextPssTime-now) + ": " + app);
19867        } else {
19868            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19869                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19870                    mTestPssMode)))) {
19871                requestPssLocked(app, app.setProcState);
19872                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19873                        mTestPssMode, isSleeping(), now);
19874            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19875                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19876        }
19877        if (app.setProcState != app.curProcState) {
19878            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19879                    "Proc state change of " + app.processName
19880                            + " to " + app.curProcState);
19881            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19882            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19883            if (setImportant && !curImportant) {
19884                // This app is no longer something we consider important enough to allow to
19885                // use arbitrary amounts of battery power.  Note
19886                // its current wake lock time to later know to kill it if
19887                // it is not behaving well.
19888                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19889                synchronized (stats) {
19890                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19891                            app.pid, nowElapsed);
19892                }
19893                app.lastCpuTime = app.curCpuTime;
19894
19895            }
19896            // Inform UsageStats of important process state change
19897            // Must be called before updating setProcState
19898            maybeUpdateUsageStatsLocked(app, nowElapsed);
19899
19900            app.setProcState = app.curProcState;
19901            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19902                app.notCachedSinceIdle = false;
19903            }
19904            if (!doingAll) {
19905                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19906            } else {
19907                app.procStateChanged = true;
19908            }
19909        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19910                > USAGE_STATS_INTERACTION_INTERVAL) {
19911            // For apps that sit around for a long time in the interactive state, we need
19912            // to report this at least once a day so they don't go idle.
19913            maybeUpdateUsageStatsLocked(app, nowElapsed);
19914        }
19915
19916        if (changes != 0) {
19917            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19918                    "Changes in " + app + ": " + changes);
19919            int i = mPendingProcessChanges.size()-1;
19920            ProcessChangeItem item = null;
19921            while (i >= 0) {
19922                item = mPendingProcessChanges.get(i);
19923                if (item.pid == app.pid) {
19924                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19925                            "Re-using existing item: " + item);
19926                    break;
19927                }
19928                i--;
19929            }
19930            if (i < 0) {
19931                // No existing item in pending changes; need a new one.
19932                final int NA = mAvailProcessChanges.size();
19933                if (NA > 0) {
19934                    item = mAvailProcessChanges.remove(NA-1);
19935                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19936                            "Retrieving available item: " + item);
19937                } else {
19938                    item = new ProcessChangeItem();
19939                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19940                            "Allocating new item: " + item);
19941                }
19942                item.changes = 0;
19943                item.pid = app.pid;
19944                item.uid = app.info.uid;
19945                if (mPendingProcessChanges.size() == 0) {
19946                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19947                            "*** Enqueueing dispatch processes changed!");
19948                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19949                }
19950                mPendingProcessChanges.add(item);
19951            }
19952            item.changes |= changes;
19953            item.processState = app.repProcState;
19954            item.foregroundActivities = app.repForegroundActivities;
19955            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19956                    "Item " + Integer.toHexString(System.identityHashCode(item))
19957                    + " " + app.toShortString() + ": changes=" + item.changes
19958                    + " procState=" + item.processState
19959                    + " foreground=" + item.foregroundActivities
19960                    + " type=" + app.adjType + " source=" + app.adjSource
19961                    + " target=" + app.adjTarget);
19962        }
19963
19964        return success;
19965    }
19966
19967    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19968        final UidRecord.ChangeItem pendingChange;
19969        if (uidRec == null || uidRec.pendingChange == null) {
19970            if (mPendingUidChanges.size() == 0) {
19971                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19972                        "*** Enqueueing dispatch uid changed!");
19973                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19974            }
19975            final int NA = mAvailUidChanges.size();
19976            if (NA > 0) {
19977                pendingChange = mAvailUidChanges.remove(NA-1);
19978                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19979                        "Retrieving available item: " + pendingChange);
19980            } else {
19981                pendingChange = new UidRecord.ChangeItem();
19982                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19983                        "Allocating new item: " + pendingChange);
19984            }
19985            if (uidRec != null) {
19986                uidRec.pendingChange = pendingChange;
19987                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19988                    // If this uid is going away, and we haven't yet reported it is gone,
19989                    // then do so now.
19990                    change = UidRecord.CHANGE_GONE_IDLE;
19991                }
19992            } else if (uid < 0) {
19993                throw new IllegalArgumentException("No UidRecord or uid");
19994            }
19995            pendingChange.uidRecord = uidRec;
19996            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19997            mPendingUidChanges.add(pendingChange);
19998        } else {
19999            pendingChange = uidRec.pendingChange;
20000            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20001                change = UidRecord.CHANGE_GONE_IDLE;
20002            }
20003        }
20004        pendingChange.change = change;
20005        pendingChange.processState = uidRec != null
20006                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20007    }
20008
20009    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20010            String authority) {
20011        if (app == null) return;
20012        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20013            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20014            if (userState == null) return;
20015            final long now = SystemClock.elapsedRealtime();
20016            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20017            if (lastReported == null || lastReported < now - 60 * 1000L) {
20018                mUsageStatsService.reportContentProviderUsage(
20019                        authority, providerPkgName, app.userId);
20020                userState.mProviderLastReportedFg.put(authority, now);
20021            }
20022        }
20023    }
20024
20025    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20026        if (DEBUG_USAGE_STATS) {
20027            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20028                    + "] state changes: old = " + app.setProcState + ", new = "
20029                    + app.curProcState);
20030        }
20031        if (mUsageStatsService == null) {
20032            return;
20033        }
20034        boolean isInteraction;
20035        // To avoid some abuse patterns, we are going to be careful about what we consider
20036        // to be an app interaction.  Being the top activity doesn't count while the display
20037        // is sleeping, nor do short foreground services.
20038        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20039            isInteraction = true;
20040            app.fgInteractionTime = 0;
20041        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20042            if (app.fgInteractionTime == 0) {
20043                app.fgInteractionTime = nowElapsed;
20044                isInteraction = false;
20045            } else {
20046                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20047            }
20048        } else {
20049            isInteraction = app.curProcState
20050                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20051            app.fgInteractionTime = 0;
20052        }
20053        if (isInteraction && (!app.reportedInteraction
20054                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20055            app.interactionEventTime = nowElapsed;
20056            String[] packages = app.getPackageList();
20057            if (packages != null) {
20058                for (int i = 0; i < packages.length; i++) {
20059                    mUsageStatsService.reportEvent(packages[i], app.userId,
20060                            UsageEvents.Event.SYSTEM_INTERACTION);
20061                }
20062            }
20063        }
20064        app.reportedInteraction = isInteraction;
20065        if (!isInteraction) {
20066            app.interactionEventTime = 0;
20067        }
20068    }
20069
20070    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20071        if (proc.thread != null) {
20072            if (proc.baseProcessTracker != null) {
20073                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20074            }
20075        }
20076    }
20077
20078    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20079            ProcessRecord TOP_APP, boolean doingAll, long now) {
20080        if (app.thread == null) {
20081            return false;
20082        }
20083
20084        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20085
20086        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20087    }
20088
20089    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20090            boolean oomAdj) {
20091        if (isForeground != proc.foregroundServices) {
20092            proc.foregroundServices = isForeground;
20093            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20094                    proc.info.uid);
20095            if (isForeground) {
20096                if (curProcs == null) {
20097                    curProcs = new ArrayList<ProcessRecord>();
20098                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20099                }
20100                if (!curProcs.contains(proc)) {
20101                    curProcs.add(proc);
20102                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20103                            proc.info.packageName, proc.info.uid);
20104                }
20105            } else {
20106                if (curProcs != null) {
20107                    if (curProcs.remove(proc)) {
20108                        mBatteryStatsService.noteEvent(
20109                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20110                                proc.info.packageName, proc.info.uid);
20111                        if (curProcs.size() <= 0) {
20112                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20113                        }
20114                    }
20115                }
20116            }
20117            if (oomAdj) {
20118                updateOomAdjLocked();
20119            }
20120        }
20121    }
20122
20123    private final ActivityRecord resumedAppLocked() {
20124        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20125        String pkg;
20126        int uid;
20127        if (act != null) {
20128            pkg = act.packageName;
20129            uid = act.info.applicationInfo.uid;
20130        } else {
20131            pkg = null;
20132            uid = -1;
20133        }
20134        // Has the UID or resumed package name changed?
20135        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20136                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20137            if (mCurResumedPackage != null) {
20138                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20139                        mCurResumedPackage, mCurResumedUid);
20140            }
20141            mCurResumedPackage = pkg;
20142            mCurResumedUid = uid;
20143            if (mCurResumedPackage != null) {
20144                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20145                        mCurResumedPackage, mCurResumedUid);
20146            }
20147        }
20148        return act;
20149    }
20150
20151    final boolean updateOomAdjLocked(ProcessRecord app) {
20152        final ActivityRecord TOP_ACT = resumedAppLocked();
20153        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20154        final boolean wasCached = app.cached;
20155
20156        mAdjSeq++;
20157
20158        // This is the desired cached adjusment we want to tell it to use.
20159        // If our app is currently cached, we know it, and that is it.  Otherwise,
20160        // we don't know it yet, and it needs to now be cached we will then
20161        // need to do a complete oom adj.
20162        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20163                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20164        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20165                SystemClock.uptimeMillis());
20166        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20167            // Changed to/from cached state, so apps after it in the LRU
20168            // list may also be changed.
20169            updateOomAdjLocked();
20170        }
20171        return success;
20172    }
20173
20174    final void updateOomAdjLocked() {
20175        final ActivityRecord TOP_ACT = resumedAppLocked();
20176        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20177        final long now = SystemClock.uptimeMillis();
20178        final long nowElapsed = SystemClock.elapsedRealtime();
20179        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20180        final int N = mLruProcesses.size();
20181
20182        if (false) {
20183            RuntimeException e = new RuntimeException();
20184            e.fillInStackTrace();
20185            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20186        }
20187
20188        // Reset state in all uid records.
20189        for (int i=mActiveUids.size()-1; i>=0; i--) {
20190            final UidRecord uidRec = mActiveUids.valueAt(i);
20191            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20192                    "Starting update of " + uidRec);
20193            uidRec.reset();
20194        }
20195
20196        mStackSupervisor.rankTaskLayersIfNeeded();
20197
20198        mAdjSeq++;
20199        mNewNumServiceProcs = 0;
20200        mNewNumAServiceProcs = 0;
20201
20202        final int emptyProcessLimit;
20203        final int cachedProcessLimit;
20204        if (mProcessLimit <= 0) {
20205            emptyProcessLimit = cachedProcessLimit = 0;
20206        } else if (mProcessLimit == 1) {
20207            emptyProcessLimit = 1;
20208            cachedProcessLimit = 0;
20209        } else {
20210            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20211            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20212        }
20213
20214        // Let's determine how many processes we have running vs.
20215        // how many slots we have for background processes; we may want
20216        // to put multiple processes in a slot of there are enough of
20217        // them.
20218        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20219                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20220        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20221        if (numEmptyProcs > cachedProcessLimit) {
20222            // If there are more empty processes than our limit on cached
20223            // processes, then use the cached process limit for the factor.
20224            // This ensures that the really old empty processes get pushed
20225            // down to the bottom, so if we are running low on memory we will
20226            // have a better chance at keeping around more cached processes
20227            // instead of a gazillion empty processes.
20228            numEmptyProcs = cachedProcessLimit;
20229        }
20230        int emptyFactor = numEmptyProcs/numSlots;
20231        if (emptyFactor < 1) emptyFactor = 1;
20232        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20233        if (cachedFactor < 1) cachedFactor = 1;
20234        int stepCached = 0;
20235        int stepEmpty = 0;
20236        int numCached = 0;
20237        int numEmpty = 0;
20238        int numTrimming = 0;
20239
20240        mNumNonCachedProcs = 0;
20241        mNumCachedHiddenProcs = 0;
20242
20243        // First update the OOM adjustment for each of the
20244        // application processes based on their current state.
20245        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20246        int nextCachedAdj = curCachedAdj+1;
20247        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20248        int nextEmptyAdj = curEmptyAdj+2;
20249        for (int i=N-1; i>=0; i--) {
20250            ProcessRecord app = mLruProcesses.get(i);
20251            if (!app.killedByAm && app.thread != null) {
20252                app.procStateChanged = false;
20253                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20254
20255                // If we haven't yet assigned the final cached adj
20256                // to the process, do that now.
20257                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20258                    switch (app.curProcState) {
20259                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20260                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20261                            // This process is a cached process holding activities...
20262                            // assign it the next cached value for that type, and then
20263                            // step that cached level.
20264                            app.curRawAdj = curCachedAdj;
20265                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20266                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20267                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20268                                    + ")");
20269                            if (curCachedAdj != nextCachedAdj) {
20270                                stepCached++;
20271                                if (stepCached >= cachedFactor) {
20272                                    stepCached = 0;
20273                                    curCachedAdj = nextCachedAdj;
20274                                    nextCachedAdj += 2;
20275                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20276                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20277                                    }
20278                                }
20279                            }
20280                            break;
20281                        default:
20282                            // For everything else, assign next empty cached process
20283                            // level and bump that up.  Note that this means that
20284                            // long-running services that have dropped down to the
20285                            // cached level will be treated as empty (since their process
20286                            // state is still as a service), which is what we want.
20287                            app.curRawAdj = curEmptyAdj;
20288                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20289                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20290                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20291                                    + ")");
20292                            if (curEmptyAdj != nextEmptyAdj) {
20293                                stepEmpty++;
20294                                if (stepEmpty >= emptyFactor) {
20295                                    stepEmpty = 0;
20296                                    curEmptyAdj = nextEmptyAdj;
20297                                    nextEmptyAdj += 2;
20298                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20299                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20300                                    }
20301                                }
20302                            }
20303                            break;
20304                    }
20305                }
20306
20307                applyOomAdjLocked(app, true, now, nowElapsed);
20308
20309                // Count the number of process types.
20310                switch (app.curProcState) {
20311                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20312                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20313                        mNumCachedHiddenProcs++;
20314                        numCached++;
20315                        if (numCached > cachedProcessLimit) {
20316                            app.kill("cached #" + numCached, true);
20317                        }
20318                        break;
20319                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20320                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20321                                && app.lastActivityTime < oldTime) {
20322                            app.kill("empty for "
20323                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20324                                    / 1000) + "s", true);
20325                        } else {
20326                            numEmpty++;
20327                            if (numEmpty > emptyProcessLimit) {
20328                                app.kill("empty #" + numEmpty, true);
20329                            }
20330                        }
20331                        break;
20332                    default:
20333                        mNumNonCachedProcs++;
20334                        break;
20335                }
20336
20337                if (app.isolated && app.services.size() <= 0) {
20338                    // If this is an isolated process, and there are no
20339                    // services running in it, then the process is no longer
20340                    // needed.  We agressively kill these because we can by
20341                    // definition not re-use the same process again, and it is
20342                    // good to avoid having whatever code was running in them
20343                    // left sitting around after no longer needed.
20344                    app.kill("isolated not needed", true);
20345                } else {
20346                    // Keeping this process, update its uid.
20347                    final UidRecord uidRec = app.uidRecord;
20348                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20349                        uidRec.curProcState = app.curProcState;
20350                    }
20351                }
20352
20353                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20354                        && !app.killedByAm) {
20355                    numTrimming++;
20356                }
20357            }
20358        }
20359
20360        mNumServiceProcs = mNewNumServiceProcs;
20361
20362        // Now determine the memory trimming level of background processes.
20363        // Unfortunately we need to start at the back of the list to do this
20364        // properly.  We only do this if the number of background apps we
20365        // are managing to keep around is less than half the maximum we desire;
20366        // if we are keeping a good number around, we'll let them use whatever
20367        // memory they want.
20368        final int numCachedAndEmpty = numCached + numEmpty;
20369        int memFactor;
20370        if (numCached <= ProcessList.TRIM_CACHED_APPS
20371                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20372            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20373                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20374            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20375                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20376            } else {
20377                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20378            }
20379        } else {
20380            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20381        }
20382        // We always allow the memory level to go up (better).  We only allow it to go
20383        // down if we are in a state where that is allowed, *and* the total number of processes
20384        // has gone down since last time.
20385        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20386                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20387                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20388        if (memFactor > mLastMemoryLevel) {
20389            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20390                memFactor = mLastMemoryLevel;
20391                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20392            }
20393        }
20394        if (memFactor != mLastMemoryLevel) {
20395            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20396        }
20397        mLastMemoryLevel = memFactor;
20398        mLastNumProcesses = mLruProcesses.size();
20399        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20400        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20401        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20402            if (mLowRamStartTime == 0) {
20403                mLowRamStartTime = now;
20404            }
20405            int step = 0;
20406            int fgTrimLevel;
20407            switch (memFactor) {
20408                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20409                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20410                    break;
20411                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20412                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20413                    break;
20414                default:
20415                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20416                    break;
20417            }
20418            int factor = numTrimming/3;
20419            int minFactor = 2;
20420            if (mHomeProcess != null) minFactor++;
20421            if (mPreviousProcess != null) minFactor++;
20422            if (factor < minFactor) factor = minFactor;
20423            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20424            for (int i=N-1; i>=0; i--) {
20425                ProcessRecord app = mLruProcesses.get(i);
20426                if (allChanged || app.procStateChanged) {
20427                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20428                    app.procStateChanged = false;
20429                }
20430                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20431                        && !app.killedByAm) {
20432                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20433                        try {
20434                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20435                                    "Trimming memory of " + app.processName + " to " + curLevel);
20436                            app.thread.scheduleTrimMemory(curLevel);
20437                        } catch (RemoteException e) {
20438                        }
20439                        if (false) {
20440                            // For now we won't do this; our memory trimming seems
20441                            // to be good enough at this point that destroying
20442                            // activities causes more harm than good.
20443                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20444                                    && app != mHomeProcess && app != mPreviousProcess) {
20445                                // Need to do this on its own message because the stack may not
20446                                // be in a consistent state at this point.
20447                                // For these apps we will also finish their activities
20448                                // to help them free memory.
20449                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20450                            }
20451                        }
20452                    }
20453                    app.trimMemoryLevel = curLevel;
20454                    step++;
20455                    if (step >= factor) {
20456                        step = 0;
20457                        switch (curLevel) {
20458                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20459                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20460                                break;
20461                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20462                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20463                                break;
20464                        }
20465                    }
20466                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20467                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20468                            && app.thread != null) {
20469                        try {
20470                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20471                                    "Trimming memory of heavy-weight " + app.processName
20472                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20473                            app.thread.scheduleTrimMemory(
20474                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20475                        } catch (RemoteException e) {
20476                        }
20477                    }
20478                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20479                } else {
20480                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20481                            || app.systemNoUi) && app.pendingUiClean) {
20482                        // If this application is now in the background and it
20483                        // had done UI, then give it the special trim level to
20484                        // have it free UI resources.
20485                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20486                        if (app.trimMemoryLevel < level && app.thread != null) {
20487                            try {
20488                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20489                                        "Trimming memory of bg-ui " + app.processName
20490                                        + " to " + level);
20491                                app.thread.scheduleTrimMemory(level);
20492                            } catch (RemoteException e) {
20493                            }
20494                        }
20495                        app.pendingUiClean = false;
20496                    }
20497                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20498                        try {
20499                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20500                                    "Trimming memory of fg " + app.processName
20501                                    + " to " + fgTrimLevel);
20502                            app.thread.scheduleTrimMemory(fgTrimLevel);
20503                        } catch (RemoteException e) {
20504                        }
20505                    }
20506                    app.trimMemoryLevel = fgTrimLevel;
20507                }
20508            }
20509        } else {
20510            if (mLowRamStartTime != 0) {
20511                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20512                mLowRamStartTime = 0;
20513            }
20514            for (int i=N-1; i>=0; i--) {
20515                ProcessRecord app = mLruProcesses.get(i);
20516                if (allChanged || app.procStateChanged) {
20517                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20518                    app.procStateChanged = false;
20519                }
20520                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20521                        || app.systemNoUi) && app.pendingUiClean) {
20522                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20523                            && app.thread != null) {
20524                        try {
20525                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20526                                    "Trimming memory of ui hidden " + app.processName
20527                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20528                            app.thread.scheduleTrimMemory(
20529                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20530                        } catch (RemoteException e) {
20531                        }
20532                    }
20533                    app.pendingUiClean = false;
20534                }
20535                app.trimMemoryLevel = 0;
20536            }
20537        }
20538
20539        if (mAlwaysFinishActivities) {
20540            // Need to do this on its own message because the stack may not
20541            // be in a consistent state at this point.
20542            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20543        }
20544
20545        if (allChanged) {
20546            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20547        }
20548
20549        // Update from any uid changes.
20550        for (int i=mActiveUids.size()-1; i>=0; i--) {
20551            final UidRecord uidRec = mActiveUids.valueAt(i);
20552            int uidChange = UidRecord.CHANGE_PROCSTATE;
20553            if (uidRec.setProcState != uidRec.curProcState) {
20554                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20555                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20556                        + " to " + uidRec.curProcState);
20557                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20558                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20559                        uidRec.lastBackgroundTime = nowElapsed;
20560                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20561                            // Note: the background settle time is in elapsed realtime, while
20562                            // the handler time base is uptime.  All this means is that we may
20563                            // stop background uids later than we had intended, but that only
20564                            // happens because the device was sleeping so we are okay anyway.
20565                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20566                        }
20567                    }
20568                } else {
20569                    if (uidRec.idle) {
20570                        uidChange = UidRecord.CHANGE_ACTIVE;
20571                        uidRec.idle = false;
20572                    }
20573                    uidRec.lastBackgroundTime = 0;
20574                }
20575                uidRec.setProcState = uidRec.curProcState;
20576                enqueueUidChangeLocked(uidRec, -1, uidChange);
20577                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20578            }
20579        }
20580
20581        if (mProcessStats.shouldWriteNowLocked(now)) {
20582            mHandler.post(new Runnable() {
20583                @Override public void run() {
20584                    synchronized (ActivityManagerService.this) {
20585                        mProcessStats.writeStateAsyncLocked();
20586                    }
20587                }
20588            });
20589        }
20590
20591        if (DEBUG_OOM_ADJ) {
20592            final long duration = SystemClock.uptimeMillis() - now;
20593            if (false) {
20594                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20595                        new RuntimeException("here").fillInStackTrace());
20596            } else {
20597                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20598            }
20599        }
20600    }
20601
20602    final void idleUids() {
20603        synchronized (this) {
20604            final long nowElapsed = SystemClock.elapsedRealtime();
20605            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20606            long nextTime = 0;
20607            for (int i=mActiveUids.size()-1; i>=0; i--) {
20608                final UidRecord uidRec = mActiveUids.valueAt(i);
20609                final long bgTime = uidRec.lastBackgroundTime;
20610                if (bgTime > 0 && !uidRec.idle) {
20611                    if (bgTime <= maxBgTime) {
20612                        uidRec.idle = true;
20613                        doStopUidLocked(uidRec.uid, uidRec);
20614                    } else {
20615                        if (nextTime == 0 || nextTime > bgTime) {
20616                            nextTime = bgTime;
20617                        }
20618                    }
20619                }
20620            }
20621            if (nextTime > 0) {
20622                mHandler.removeMessages(IDLE_UIDS_MSG);
20623                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20624                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20625            }
20626        }
20627    }
20628
20629    final void runInBackgroundDisabled(int uid) {
20630        synchronized (this) {
20631            UidRecord uidRec = mActiveUids.get(uid);
20632            if (uidRec != null) {
20633                // This uid is actually running...  should it be considered background now?
20634                if (uidRec.idle) {
20635                    doStopUidLocked(uidRec.uid, uidRec);
20636                }
20637            } else {
20638                // This uid isn't actually running...  still send a report about it being "stopped".
20639                doStopUidLocked(uid, null);
20640            }
20641        }
20642    }
20643
20644    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20645        mServices.stopInBackgroundLocked(uid);
20646        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20647    }
20648
20649    final void trimApplications() {
20650        synchronized (this) {
20651            int i;
20652
20653            // First remove any unused application processes whose package
20654            // has been removed.
20655            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20656                final ProcessRecord app = mRemovedProcesses.get(i);
20657                if (app.activities.size() == 0
20658                        && app.curReceiver == null && app.services.size() == 0) {
20659                    Slog.i(
20660                        TAG, "Exiting empty application process "
20661                        + app.toShortString() + " ("
20662                        + (app.thread != null ? app.thread.asBinder() : null)
20663                        + ")\n");
20664                    if (app.pid > 0 && app.pid != MY_PID) {
20665                        app.kill("empty", false);
20666                    } else {
20667                        try {
20668                            app.thread.scheduleExit();
20669                        } catch (Exception e) {
20670                            // Ignore exceptions.
20671                        }
20672                    }
20673                    cleanUpApplicationRecordLocked(app, false, true, -1);
20674                    mRemovedProcesses.remove(i);
20675
20676                    if (app.persistent) {
20677                        addAppLocked(app.info, false, null /* ABI override */);
20678                    }
20679                }
20680            }
20681
20682            // Now update the oom adj for all processes.
20683            updateOomAdjLocked();
20684        }
20685    }
20686
20687    /** This method sends the specified signal to each of the persistent apps */
20688    public void signalPersistentProcesses(int sig) throws RemoteException {
20689        if (sig != Process.SIGNAL_USR1) {
20690            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20691        }
20692
20693        synchronized (this) {
20694            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20695                    != PackageManager.PERMISSION_GRANTED) {
20696                throw new SecurityException("Requires permission "
20697                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20698            }
20699
20700            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20701                ProcessRecord r = mLruProcesses.get(i);
20702                if (r.thread != null && r.persistent) {
20703                    Process.sendSignal(r.pid, sig);
20704                }
20705            }
20706        }
20707    }
20708
20709    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20710        if (proc == null || proc == mProfileProc) {
20711            proc = mProfileProc;
20712            profileType = mProfileType;
20713            clearProfilerLocked();
20714        }
20715        if (proc == null) {
20716            return;
20717        }
20718        try {
20719            proc.thread.profilerControl(false, null, profileType);
20720        } catch (RemoteException e) {
20721            throw new IllegalStateException("Process disappeared");
20722        }
20723    }
20724
20725    private void clearProfilerLocked() {
20726        if (mProfileFd != null) {
20727            try {
20728                mProfileFd.close();
20729            } catch (IOException e) {
20730            }
20731        }
20732        mProfileApp = null;
20733        mProfileProc = null;
20734        mProfileFile = null;
20735        mProfileType = 0;
20736        mAutoStopProfiler = false;
20737        mSamplingInterval = 0;
20738    }
20739
20740    public boolean profileControl(String process, int userId, boolean start,
20741            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20742
20743        try {
20744            synchronized (this) {
20745                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20746                // its own permission.
20747                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20748                        != PackageManager.PERMISSION_GRANTED) {
20749                    throw new SecurityException("Requires permission "
20750                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20751                }
20752
20753                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20754                    throw new IllegalArgumentException("null profile info or fd");
20755                }
20756
20757                ProcessRecord proc = null;
20758                if (process != null) {
20759                    proc = findProcessLocked(process, userId, "profileControl");
20760                }
20761
20762                if (start && (proc == null || proc.thread == null)) {
20763                    throw new IllegalArgumentException("Unknown process: " + process);
20764                }
20765
20766                if (start) {
20767                    stopProfilerLocked(null, 0);
20768                    setProfileApp(proc.info, proc.processName, profilerInfo);
20769                    mProfileProc = proc;
20770                    mProfileType = profileType;
20771                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20772                    try {
20773                        fd = fd.dup();
20774                    } catch (IOException e) {
20775                        fd = null;
20776                    }
20777                    profilerInfo.profileFd = fd;
20778                    proc.thread.profilerControl(start, profilerInfo, profileType);
20779                    fd = null;
20780                    mProfileFd = null;
20781                } else {
20782                    stopProfilerLocked(proc, profileType);
20783                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20784                        try {
20785                            profilerInfo.profileFd.close();
20786                        } catch (IOException e) {
20787                        }
20788                    }
20789                }
20790
20791                return true;
20792            }
20793        } catch (RemoteException e) {
20794            throw new IllegalStateException("Process disappeared");
20795        } finally {
20796            if (profilerInfo != null && profilerInfo.profileFd != null) {
20797                try {
20798                    profilerInfo.profileFd.close();
20799                } catch (IOException e) {
20800                }
20801            }
20802        }
20803    }
20804
20805    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20806        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20807                userId, true, ALLOW_FULL_ONLY, callName, null);
20808        ProcessRecord proc = null;
20809        try {
20810            int pid = Integer.parseInt(process);
20811            synchronized (mPidsSelfLocked) {
20812                proc = mPidsSelfLocked.get(pid);
20813            }
20814        } catch (NumberFormatException e) {
20815        }
20816
20817        if (proc == null) {
20818            ArrayMap<String, SparseArray<ProcessRecord>> all
20819                    = mProcessNames.getMap();
20820            SparseArray<ProcessRecord> procs = all.get(process);
20821            if (procs != null && procs.size() > 0) {
20822                proc = procs.valueAt(0);
20823                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20824                    for (int i=1; i<procs.size(); i++) {
20825                        ProcessRecord thisProc = procs.valueAt(i);
20826                        if (thisProc.userId == userId) {
20827                            proc = thisProc;
20828                            break;
20829                        }
20830                    }
20831                }
20832            }
20833        }
20834
20835        return proc;
20836    }
20837
20838    public boolean dumpHeap(String process, int userId, boolean managed,
20839            String path, ParcelFileDescriptor fd) throws RemoteException {
20840
20841        try {
20842            synchronized (this) {
20843                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20844                // its own permission (same as profileControl).
20845                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20846                        != PackageManager.PERMISSION_GRANTED) {
20847                    throw new SecurityException("Requires permission "
20848                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20849                }
20850
20851                if (fd == null) {
20852                    throw new IllegalArgumentException("null fd");
20853                }
20854
20855                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20856                if (proc == null || proc.thread == null) {
20857                    throw new IllegalArgumentException("Unknown process: " + process);
20858                }
20859
20860                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20861                if (!isDebuggable) {
20862                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20863                        throw new SecurityException("Process not debuggable: " + proc);
20864                    }
20865                }
20866
20867                proc.thread.dumpHeap(managed, path, fd);
20868                fd = null;
20869                return true;
20870            }
20871        } catch (RemoteException e) {
20872            throw new IllegalStateException("Process disappeared");
20873        } finally {
20874            if (fd != null) {
20875                try {
20876                    fd.close();
20877                } catch (IOException e) {
20878                }
20879            }
20880        }
20881    }
20882
20883    @Override
20884    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20885            String reportPackage) {
20886        if (processName != null) {
20887            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20888                    "setDumpHeapDebugLimit()");
20889        } else {
20890            synchronized (mPidsSelfLocked) {
20891                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20892                if (proc == null) {
20893                    throw new SecurityException("No process found for calling pid "
20894                            + Binder.getCallingPid());
20895                }
20896                if (!Build.IS_DEBUGGABLE
20897                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20898                    throw new SecurityException("Not running a debuggable build");
20899                }
20900                processName = proc.processName;
20901                uid = proc.uid;
20902                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20903                    throw new SecurityException("Package " + reportPackage + " is not running in "
20904                            + proc);
20905                }
20906            }
20907        }
20908        synchronized (this) {
20909            if (maxMemSize > 0) {
20910                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20911            } else {
20912                if (uid != 0) {
20913                    mMemWatchProcesses.remove(processName, uid);
20914                } else {
20915                    mMemWatchProcesses.getMap().remove(processName);
20916                }
20917            }
20918        }
20919    }
20920
20921    @Override
20922    public void dumpHeapFinished(String path) {
20923        synchronized (this) {
20924            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20925                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20926                        + " does not match last pid " + mMemWatchDumpPid);
20927                return;
20928            }
20929            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20930                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20931                        + " does not match last path " + mMemWatchDumpFile);
20932                return;
20933            }
20934            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20935            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20936        }
20937    }
20938
20939    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20940    public void monitor() {
20941        synchronized (this) { }
20942    }
20943
20944    void onCoreSettingsChange(Bundle settings) {
20945        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20946            ProcessRecord processRecord = mLruProcesses.get(i);
20947            try {
20948                if (processRecord.thread != null) {
20949                    processRecord.thread.setCoreSettings(settings);
20950                }
20951            } catch (RemoteException re) {
20952                /* ignore */
20953            }
20954        }
20955    }
20956
20957    // Multi-user methods
20958
20959    /**
20960     * Start user, if its not already running, but don't bring it to foreground.
20961     */
20962    @Override
20963    public boolean startUserInBackground(final int userId) {
20964        return mUserController.startUser(userId, /* foreground */ false);
20965    }
20966
20967    @Override
20968    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20969        return mUserController.unlockUser(userId, token, secret, listener);
20970    }
20971
20972    @Override
20973    public boolean switchUser(final int targetUserId) {
20974        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20975        UserInfo currentUserInfo;
20976        UserInfo targetUserInfo;
20977        synchronized (this) {
20978            int currentUserId = mUserController.getCurrentUserIdLocked();
20979            currentUserInfo = mUserController.getUserInfo(currentUserId);
20980            targetUserInfo = mUserController.getUserInfo(targetUserId);
20981            if (targetUserInfo == null) {
20982                Slog.w(TAG, "No user info for user #" + targetUserId);
20983                return false;
20984            }
20985            if (!targetUserInfo.supportsSwitchTo()) {
20986                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20987                return false;
20988            }
20989            if (targetUserInfo.isManagedProfile()) {
20990                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20991                return false;
20992            }
20993            mUserController.setTargetUserIdLocked(targetUserId);
20994        }
20995        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20996        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20997        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20998        return true;
20999    }
21000
21001    void scheduleStartProfilesLocked() {
21002        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21003            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21004                    DateUtils.SECOND_IN_MILLIS);
21005        }
21006    }
21007
21008    @Override
21009    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21010        return mUserController.stopUser(userId, force, callback);
21011    }
21012
21013    @Override
21014    public UserInfo getCurrentUser() {
21015        return mUserController.getCurrentUser();
21016    }
21017
21018    @Override
21019    public boolean isUserRunning(int userId, int flags) {
21020        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21021                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21022            String msg = "Permission Denial: isUserRunning() from pid="
21023                    + Binder.getCallingPid()
21024                    + ", uid=" + Binder.getCallingUid()
21025                    + " requires " + INTERACT_ACROSS_USERS;
21026            Slog.w(TAG, msg);
21027            throw new SecurityException(msg);
21028        }
21029        synchronized (this) {
21030            return mUserController.isUserRunningLocked(userId, flags);
21031        }
21032    }
21033
21034    @Override
21035    public int[] getRunningUserIds() {
21036        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21037                != PackageManager.PERMISSION_GRANTED) {
21038            String msg = "Permission Denial: isUserRunning() from pid="
21039                    + Binder.getCallingPid()
21040                    + ", uid=" + Binder.getCallingUid()
21041                    + " requires " + INTERACT_ACROSS_USERS;
21042            Slog.w(TAG, msg);
21043            throw new SecurityException(msg);
21044        }
21045        synchronized (this) {
21046            return mUserController.getStartedUserArrayLocked();
21047        }
21048    }
21049
21050    @Override
21051    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21052        mUserController.registerUserSwitchObserver(observer);
21053    }
21054
21055    @Override
21056    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21057        mUserController.unregisterUserSwitchObserver(observer);
21058    }
21059
21060    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21061        if (info == null) return null;
21062        ApplicationInfo newInfo = new ApplicationInfo(info);
21063        newInfo.initForUser(userId);
21064        return newInfo;
21065    }
21066
21067    public boolean isUserStopped(int userId) {
21068        synchronized (this) {
21069            return mUserController.getStartedUserStateLocked(userId) == null;
21070        }
21071    }
21072
21073    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21074        if (aInfo == null
21075                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21076            return aInfo;
21077        }
21078
21079        ActivityInfo info = new ActivityInfo(aInfo);
21080        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21081        return info;
21082    }
21083
21084    private boolean processSanityChecksLocked(ProcessRecord process) {
21085        if (process == null || process.thread == null) {
21086            return false;
21087        }
21088
21089        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21090        if (!isDebuggable) {
21091            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21092                return false;
21093            }
21094        }
21095
21096        return true;
21097    }
21098
21099    public boolean startBinderTracking() throws RemoteException {
21100        synchronized (this) {
21101            mBinderTransactionTrackingEnabled = true;
21102            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21103            // permission (same as profileControl).
21104            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21105                    != PackageManager.PERMISSION_GRANTED) {
21106                throw new SecurityException("Requires permission "
21107                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21108            }
21109
21110            for (int i = 0; i < mLruProcesses.size(); i++) {
21111                ProcessRecord process = mLruProcesses.get(i);
21112                if (!processSanityChecksLocked(process)) {
21113                    continue;
21114                }
21115                try {
21116                    process.thread.startBinderTracking();
21117                } catch (RemoteException e) {
21118                    Log.v(TAG, "Process disappared");
21119                }
21120            }
21121            return true;
21122        }
21123    }
21124
21125    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21126        try {
21127            synchronized (this) {
21128                mBinderTransactionTrackingEnabled = false;
21129                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21130                // permission (same as profileControl).
21131                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21132                        != PackageManager.PERMISSION_GRANTED) {
21133                    throw new SecurityException("Requires permission "
21134                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21135                }
21136
21137                if (fd == null) {
21138                    throw new IllegalArgumentException("null fd");
21139                }
21140
21141                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21142                pw.println("Binder transaction traces for all processes.\n");
21143                for (ProcessRecord process : mLruProcesses) {
21144                    if (!processSanityChecksLocked(process)) {
21145                        continue;
21146                    }
21147
21148                    pw.println("Traces for process: " + process.processName);
21149                    pw.flush();
21150                    try {
21151                        TransferPipe tp = new TransferPipe();
21152                        try {
21153                            process.thread.stopBinderTrackingAndDump(
21154                                    tp.getWriteFd().getFileDescriptor());
21155                            tp.go(fd.getFileDescriptor());
21156                        } finally {
21157                            tp.kill();
21158                        }
21159                    } catch (IOException e) {
21160                        pw.println("Failure while dumping IPC traces from " + process +
21161                                ".  Exception: " + e);
21162                        pw.flush();
21163                    } catch (RemoteException e) {
21164                        pw.println("Got a RemoteException while dumping IPC traces from " +
21165                                process + ".  Exception: " + e);
21166                        pw.flush();
21167                    }
21168                }
21169                fd = null;
21170                return true;
21171            }
21172        } finally {
21173            if (fd != null) {
21174                try {
21175                    fd.close();
21176                } catch (IOException e) {
21177                }
21178            }
21179        }
21180    }
21181
21182    private final class LocalService extends ActivityManagerInternal {
21183        @Override
21184        public void onWakefulnessChanged(int wakefulness) {
21185            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21186        }
21187
21188        @Override
21189        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21190                String processName, String abiOverride, int uid, Runnable crashHandler) {
21191            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21192                    processName, abiOverride, uid, crashHandler);
21193        }
21194
21195        @Override
21196        public SleepToken acquireSleepToken(String tag) {
21197            Preconditions.checkNotNull(tag);
21198
21199            synchronized (ActivityManagerService.this) {
21200                SleepTokenImpl token = new SleepTokenImpl(tag);
21201                mSleepTokens.add(token);
21202                updateSleepIfNeededLocked();
21203                applyVrModeIfNeededLocked(mFocusedActivity, false);
21204                return token;
21205            }
21206        }
21207
21208        @Override
21209        public ComponentName getHomeActivityForUser(int userId) {
21210            synchronized (ActivityManagerService.this) {
21211                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21212                return homeActivity == null ? null : homeActivity.realActivity;
21213            }
21214        }
21215
21216        @Override
21217        public void onUserRemoved(int userId) {
21218            synchronized (ActivityManagerService.this) {
21219                ActivityManagerService.this.onUserStoppedLocked(userId);
21220            }
21221        }
21222
21223        @Override
21224        public void onLocalVoiceInteractionStarted(IBinder activity,
21225                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21226            synchronized (ActivityManagerService.this) {
21227                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21228                        voiceSession, voiceInteractor);
21229            }
21230        }
21231
21232        @Override
21233        public void notifyStartingWindowDrawn() {
21234            synchronized (ActivityManagerService.this) {
21235                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21236            }
21237        }
21238
21239        @Override
21240        public void notifyAppTransitionStarting(int reason) {
21241            synchronized (ActivityManagerService.this) {
21242                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21243            }
21244        }
21245
21246        @Override
21247        public void notifyAppTransitionFinished() {
21248            synchronized (ActivityManagerService.this) {
21249                mStackSupervisor.notifyAppTransitionDone();
21250            }
21251        }
21252
21253        @Override
21254        public void notifyAppTransitionCancelled() {
21255            synchronized (ActivityManagerService.this) {
21256                mStackSupervisor.notifyAppTransitionDone();
21257            }
21258        }
21259
21260        @Override
21261        public List<IBinder> getTopVisibleActivities() {
21262            synchronized (ActivityManagerService.this) {
21263                return mStackSupervisor.getTopVisibleActivities();
21264            }
21265        }
21266
21267        @Override
21268        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21269            synchronized (ActivityManagerService.this) {
21270                mStackSupervisor.setDockedStackMinimized(minimized);
21271            }
21272        }
21273
21274        @Override
21275        public void killForegroundAppsForUser(int userHandle) {
21276            synchronized (ActivityManagerService.this) {
21277                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21278                final int NP = mProcessNames.getMap().size();
21279                for (int ip = 0; ip < NP; ip++) {
21280                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21281                    final int NA = apps.size();
21282                    for (int ia = 0; ia < NA; ia++) {
21283                        final ProcessRecord app = apps.valueAt(ia);
21284                        if (app.persistent) {
21285                            // We don't kill persistent processes.
21286                            continue;
21287                        }
21288                        if (app.removed) {
21289                            procs.add(app);
21290                        } else if (app.userId == userHandle && app.foregroundActivities) {
21291                            app.removed = true;
21292                            procs.add(app);
21293                        }
21294                    }
21295                }
21296
21297                final int N = procs.size();
21298                for (int i = 0; i < N; i++) {
21299                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21300                }
21301            }
21302        }
21303    }
21304
21305    private final class SleepTokenImpl extends SleepToken {
21306        private final String mTag;
21307        private final long mAcquireTime;
21308
21309        public SleepTokenImpl(String tag) {
21310            mTag = tag;
21311            mAcquireTime = SystemClock.uptimeMillis();
21312        }
21313
21314        @Override
21315        public void release() {
21316            synchronized (ActivityManagerService.this) {
21317                if (mSleepTokens.remove(this)) {
21318                    updateSleepIfNeededLocked();
21319                }
21320            }
21321        }
21322
21323        @Override
21324        public String toString() {
21325            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21326        }
21327    }
21328
21329    /**
21330     * An implementation of IAppTask, that allows an app to manage its own tasks via
21331     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21332     * only the process that calls getAppTasks() can call the AppTask methods.
21333     */
21334    class AppTaskImpl extends IAppTask.Stub {
21335        private int mTaskId;
21336        private int mCallingUid;
21337
21338        public AppTaskImpl(int taskId, int callingUid) {
21339            mTaskId = taskId;
21340            mCallingUid = callingUid;
21341        }
21342
21343        private void checkCaller() {
21344            if (mCallingUid != Binder.getCallingUid()) {
21345                throw new SecurityException("Caller " + mCallingUid
21346                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21347            }
21348        }
21349
21350        @Override
21351        public void finishAndRemoveTask() {
21352            checkCaller();
21353
21354            synchronized (ActivityManagerService.this) {
21355                long origId = Binder.clearCallingIdentity();
21356                try {
21357                    // We remove the task from recents to preserve backwards
21358                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21359                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21360                    }
21361                } finally {
21362                    Binder.restoreCallingIdentity(origId);
21363                }
21364            }
21365        }
21366
21367        @Override
21368        public ActivityManager.RecentTaskInfo getTaskInfo() {
21369            checkCaller();
21370
21371            synchronized (ActivityManagerService.this) {
21372                long origId = Binder.clearCallingIdentity();
21373                try {
21374                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21375                    if (tr == null) {
21376                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21377                    }
21378                    return createRecentTaskInfoFromTaskRecord(tr);
21379                } finally {
21380                    Binder.restoreCallingIdentity(origId);
21381                }
21382            }
21383        }
21384
21385        @Override
21386        public void moveToFront() {
21387            checkCaller();
21388            // Will bring task to front if it already has a root activity.
21389            final long origId = Binder.clearCallingIdentity();
21390            try {
21391                synchronized (this) {
21392                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21393                }
21394            } finally {
21395                Binder.restoreCallingIdentity(origId);
21396            }
21397        }
21398
21399        @Override
21400        public int startActivity(IBinder whoThread, String callingPackage,
21401                Intent intent, String resolvedType, Bundle bOptions) {
21402            checkCaller();
21403
21404            int callingUser = UserHandle.getCallingUserId();
21405            TaskRecord tr;
21406            IApplicationThread appThread;
21407            synchronized (ActivityManagerService.this) {
21408                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21409                if (tr == null) {
21410                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21411                }
21412                appThread = ApplicationThreadNative.asInterface(whoThread);
21413                if (appThread == null) {
21414                    throw new IllegalArgumentException("Bad app thread " + appThread);
21415                }
21416            }
21417            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21418                    resolvedType, null, null, null, null, 0, 0, null, null,
21419                    null, bOptions, false, callingUser, null, tr);
21420        }
21421
21422        @Override
21423        public void setExcludeFromRecents(boolean exclude) {
21424            checkCaller();
21425
21426            synchronized (ActivityManagerService.this) {
21427                long origId = Binder.clearCallingIdentity();
21428                try {
21429                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21430                    if (tr == null) {
21431                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21432                    }
21433                    Intent intent = tr.getBaseIntent();
21434                    if (exclude) {
21435                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21436                    } else {
21437                        intent.setFlags(intent.getFlags()
21438                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21439                    }
21440                } finally {
21441                    Binder.restoreCallingIdentity(origId);
21442                }
21443            }
21444        }
21445    }
21446
21447    /**
21448     * Kill processes for the user with id userId and that depend on the package named packageName
21449     */
21450    @Override
21451    public void killPackageDependents(String packageName, int userId) {
21452        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21453        if (packageName == null) {
21454            throw new NullPointerException(
21455                    "Cannot kill the dependents of a package without its name.");
21456        }
21457
21458        long callingId = Binder.clearCallingIdentity();
21459        IPackageManager pm = AppGlobals.getPackageManager();
21460        int pkgUid = -1;
21461        try {
21462            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21463        } catch (RemoteException e) {
21464        }
21465        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21466            throw new IllegalArgumentException(
21467                    "Cannot kill dependents of non-existing package " + packageName);
21468        }
21469        try {
21470            synchronized(this) {
21471                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21472                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21473                        "dep: " + packageName);
21474            }
21475        } finally {
21476            Binder.restoreCallingIdentity(callingId);
21477        }
21478    }
21479}
21480