ActivityManagerService.java revision 73d1ce85ac5e7d2bb20996bdadb3df5f31cb4bc1
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.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
277import static android.provider.Settings.Global.DEBUG_APP;
278import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
279import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
280import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
281import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
282import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
283import static android.provider.Settings.System.FONT_SCALE;
284import static com.android.internal.util.XmlUtils.readBooleanAttribute;
285import static com.android.internal.util.XmlUtils.readIntAttribute;
286import static com.android.internal.util.XmlUtils.readLongAttribute;
287import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
288import static com.android.internal.util.XmlUtils.writeIntAttribute;
289import static com.android.internal.util.XmlUtils.writeLongAttribute;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
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 = 192 * 1024;
504    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
505    // as one line, but close enough for now.
506    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
507
508    // Access modes for handleIncomingUser.
509    static final int ALLOW_NON_FULL = 0;
510    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
511    static final int ALLOW_FULL_ONLY = 2;
512
513    // Delay in notifying task stack change listeners (in millis)
514    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
515
516    // Necessary ApplicationInfo flags to mark an app as persistent
517    private static final int PERSISTENT_MASK =
518            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
519
520    // Intent sent when remote bugreport collection has been completed
521    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
522            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
523
524    // Delay to disable app launch boost
525    static final int APP_BOOST_MESSAGE_DELAY = 3000;
526    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
527    static final int APP_BOOST_TIMEOUT = 2500;
528
529    // Used to indicate that a task is removed it should also be removed from recents.
530    private static final boolean REMOVE_FROM_RECENTS = true;
531    // Used to indicate that an app transition should be animated.
532    static final boolean ANIMATE = true;
533
534    // Determines whether to take full screen screenshots
535    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
536    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
537
538    private static native int nativeMigrateToBoost();
539    private static native int nativeMigrateFromBoost();
540    private boolean mIsBoosted = false;
541    private long mBoostStartTime = 0;
542
543    /** All system services */
544    SystemServiceManager mSystemServiceManager;
545
546    private Installer mInstaller;
547
548    /** Run all ActivityStacks through this */
549    final ActivityStackSupervisor mStackSupervisor;
550
551    final ActivityStarter mActivityStarter;
552
553    /** Task stack change listeners. */
554    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
555            new RemoteCallbackList<ITaskStackListener>();
556
557    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
558
559    public IntentFirewall mIntentFirewall;
560
561    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562    // default actuion automatically.  Important for devices without direct input
563    // devices.
564    private boolean mShowDialogs = true;
565    private boolean mInVrMode = false;
566
567    BroadcastQueue mFgBroadcastQueue;
568    BroadcastQueue mBgBroadcastQueue;
569    // Convenient for easy iteration over the queues. Foreground is first
570    // so that dispatch of foreground broadcasts gets precedence.
571    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
572
573    BroadcastStats mLastBroadcastStats;
574    BroadcastStats mCurBroadcastStats;
575
576    BroadcastQueue broadcastQueueForIntent(Intent intent) {
577        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
578        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
579                "Broadcast intent " + intent + " on "
580                + (isFg ? "foreground" : "background") + " queue");
581        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
582    }
583
584    /**
585     * Activity we have told the window manager to have key focus.
586     */
587    ActivityRecord mFocusedActivity = null;
588
589    /**
590     * User id of the last activity mFocusedActivity was set to.
591     */
592    private int mLastFocusedUserId;
593
594    /**
595     * If non-null, we are tracking the time the user spends in the currently focused app.
596     */
597    private AppTimeTracker mCurAppTimeTracker;
598
599    /**
600     * List of intents that were used to start the most recent tasks.
601     */
602    final RecentTasks mRecentTasks;
603
604    /**
605     * For addAppTask: cached of the last activity component that was added.
606     */
607    ComponentName mLastAddedTaskComponent;
608
609    /**
610     * For addAppTask: cached of the last activity uid that was added.
611     */
612    int mLastAddedTaskUid;
613
614    /**
615     * For addAppTask: cached of the last ActivityInfo that was added.
616     */
617    ActivityInfo mLastAddedTaskActivity;
618
619    /**
620     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
621     */
622    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
623
624    /**
625     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
626     */
627    String mDeviceOwnerName;
628
629    final UserController mUserController;
630
631    final AppErrors mAppErrors;
632
633    boolean mDoingSetFocusedActivity;
634
635    public boolean canShowErrorDialogs() {
636        return mShowDialogs && !mSleeping && !mShuttingDown;
637    }
638
639    // it's a semaphore; boost when 0->1, reset when 1->0
640    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
641        @Override protected Integer initialValue() {
642            return 0;
643        }
644    };
645
646    static void boostPriorityForLockedSection() {
647        if (sIsBoosted.get() == 0) {
648            // boost to prio 118 while holding a global lock
649            Process.setThreadPriority(Process.myTid(), -2);
650            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
651        }
652        int cur = sIsBoosted.get();
653        sIsBoosted.set(cur + 1);
654    }
655
656    static void resetPriorityAfterLockedSection() {
657        sIsBoosted.set(sIsBoosted.get() - 1);
658        if (sIsBoosted.get() == 0) {
659            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
660            Process.setThreadPriority(Process.myTid(), 0);
661        }
662    }
663    public class PendingAssistExtras extends Binder implements Runnable {
664        public final ActivityRecord activity;
665        public final Bundle extras;
666        public final Intent intent;
667        public final String hint;
668        public final IResultReceiver receiver;
669        public final int userHandle;
670        public boolean haveResult = false;
671        public Bundle result = null;
672        public AssistStructure structure = null;
673        public AssistContent content = null;
674        public Bundle receiverExtras;
675
676        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
677                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
678            activity = _activity;
679            extras = _extras;
680            intent = _intent;
681            hint = _hint;
682            receiver = _receiver;
683            receiverExtras = _receiverExtras;
684            userHandle = _userHandle;
685        }
686        @Override
687        public void run() {
688            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
689            synchronized (this) {
690                haveResult = true;
691                notifyAll();
692            }
693            pendingAssistExtrasTimedOut(this);
694        }
695    }
696
697    final ArrayList<PendingAssistExtras> mPendingAssistExtras
698            = new ArrayList<PendingAssistExtras>();
699
700    /**
701     * Process management.
702     */
703    final ProcessList mProcessList = new ProcessList();
704
705    /**
706     * All of the applications we currently have running organized by name.
707     * The keys are strings of the application package name (as
708     * returned by the package manager), and the keys are ApplicationRecord
709     * objects.
710     */
711    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
712
713    /**
714     * Tracking long-term execution of processes to look for abuse and other
715     * bad app behavior.
716     */
717    final ProcessStatsService mProcessStats;
718
719    /**
720     * The currently running isolated processes.
721     */
722    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
723
724    /**
725     * Counter for assigning isolated process uids, to avoid frequently reusing the
726     * same ones.
727     */
728    int mNextIsolatedProcessUid = 0;
729
730    /**
731     * The currently running heavy-weight process, if any.
732     */
733    ProcessRecord mHeavyWeightProcess = null;
734
735    /**
736     * All of the processes we currently have running organized by pid.
737     * The keys are the pid running the application.
738     *
739     * <p>NOTE: This object is protected by its own lock, NOT the global
740     * activity manager lock!
741     */
742    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
743
744    /**
745     * All of the processes that have been forced to be foreground.  The key
746     * is the pid of the caller who requested it (we hold a death
747     * link on it).
748     */
749    abstract class ForegroundToken implements IBinder.DeathRecipient {
750        int pid;
751        IBinder token;
752    }
753    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
754
755    /**
756     * List of records for processes that someone had tried to start before the
757     * system was ready.  We don't start them at that point, but ensure they
758     * are started by the time booting is complete.
759     */
760    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
761
762    /**
763     * List of persistent applications that are in the process
764     * of being started.
765     */
766    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
767
768    /**
769     * Processes that are being forcibly torn down.
770     */
771    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * List of running applications, sorted by recent usage.
775     * The first entry in the list is the least recently used.
776     */
777    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
778
779    /**
780     * Where in mLruProcesses that the processes hosting activities start.
781     */
782    int mLruProcessActivityStart = 0;
783
784    /**
785     * Where in mLruProcesses that the processes hosting services start.
786     * This is after (lower index) than mLruProcessesActivityStart.
787     */
788    int mLruProcessServiceStart = 0;
789
790    /**
791     * List of processes that should gc as soon as things are idle.
792     */
793    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
794
795    /**
796     * Processes we want to collect PSS data from.
797     */
798    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
799
800    private boolean mBinderTransactionTrackingEnabled = false;
801
802    /**
803     * Last time we requested PSS data of all processes.
804     */
805    long mLastFullPssTime = SystemClock.uptimeMillis();
806
807    /**
808     * If set, the next time we collect PSS data we should do a full collection
809     * with data from native processes and the kernel.
810     */
811    boolean mFullPssPending = false;
812
813    /**
814     * This is the process holding what we currently consider to be
815     * the "home" activity.
816     */
817    ProcessRecord mHomeProcess;
818
819    /**
820     * This is the process holding the activity the user last visited that
821     * is in a different process from the one they are currently in.
822     */
823    ProcessRecord mPreviousProcess;
824
825    /**
826     * The time at which the previous process was last visible.
827     */
828    long mPreviousProcessVisibleTime;
829
830    /**
831     * Track all uids that have actively running processes.
832     */
833    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
834
835    /**
836     * This is for verifying the UID report flow.
837     */
838    static final boolean VALIDATE_UID_STATES = true;
839    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
840
841    /**
842     * Packages that the user has asked to have run in screen size
843     * compatibility mode instead of filling the screen.
844     */
845    final CompatModePackages mCompatModePackages;
846
847    /**
848     * Set of IntentSenderRecord objects that are currently active.
849     */
850    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
851            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
852
853    /**
854     * Fingerprints (hashCode()) of stack traces that we've
855     * already logged DropBox entries for.  Guarded by itself.  If
856     * something (rogue user app) forces this over
857     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
858     */
859    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
860    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
861
862    /**
863     * Strict Mode background batched logging state.
864     *
865     * The string buffer is guarded by itself, and its lock is also
866     * used to determine if another batched write is already
867     * in-flight.
868     */
869    private final StringBuilder mStrictModeBuffer = new StringBuilder();
870
871    /**
872     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
873     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
874     */
875    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
876
877    /**
878     * Resolver for broadcast intents to registered receivers.
879     * Holds BroadcastFilter (subclass of IntentFilter).
880     */
881    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
882            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
883        @Override
884        protected boolean allowFilterResult(
885                BroadcastFilter filter, List<BroadcastFilter> dest) {
886            IBinder target = filter.receiverList.receiver.asBinder();
887            for (int i = dest.size() - 1; i >= 0; i--) {
888                if (dest.get(i).receiverList.receiver.asBinder() == target) {
889                    return false;
890                }
891            }
892            return true;
893        }
894
895        @Override
896        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
897            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
898                    || userId == filter.owningUserId) {
899                return super.newResult(filter, match, userId);
900            }
901            return null;
902        }
903
904        @Override
905        protected BroadcastFilter[] newArray(int size) {
906            return new BroadcastFilter[size];
907        }
908
909        @Override
910        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
911            return packageName.equals(filter.packageName);
912        }
913    };
914
915    /**
916     * State of all active sticky broadcasts per user.  Keys are the action of the
917     * sticky Intent, values are an ArrayList of all broadcasted intents with
918     * that action (which should usually be one).  The SparseArray is keyed
919     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
920     * for stickies that are sent to all users.
921     */
922    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
923            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
924
925    final ActiveServices mServices;
926
927    final static class Association {
928        final int mSourceUid;
929        final String mSourceProcess;
930        final int mTargetUid;
931        final ComponentName mTargetComponent;
932        final String mTargetProcess;
933
934        int mCount;
935        long mTime;
936
937        int mNesting;
938        long mStartTime;
939
940        // states of the source process when the bind occurred.
941        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
942        long mLastStateUptime;
943        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
944                - ActivityManager.MIN_PROCESS_STATE+1];
945
946        Association(int sourceUid, String sourceProcess, int targetUid,
947                ComponentName targetComponent, String targetProcess) {
948            mSourceUid = sourceUid;
949            mSourceProcess = sourceProcess;
950            mTargetUid = targetUid;
951            mTargetComponent = targetComponent;
952            mTargetProcess = targetProcess;
953        }
954    }
955
956    /**
957     * When service association tracking is enabled, this is all of the associations we
958     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
959     * -> association data.
960     */
961    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
962            mAssociations = new SparseArray<>();
963    boolean mTrackingAssociations;
964
965    /**
966     * Backup/restore process management
967     */
968    String mBackupAppName = null;
969    BackupRecord mBackupTarget = null;
970
971    final ProviderMap mProviderMap;
972
973    /**
974     * List of content providers who have clients waiting for them.  The
975     * application is currently being launched and the provider will be
976     * removed from this list once it is published.
977     */
978    final ArrayList<ContentProviderRecord> mLaunchingProviders
979            = new ArrayList<ContentProviderRecord>();
980
981    /**
982     * File storing persisted {@link #mGrantedUriPermissions}.
983     */
984    private final AtomicFile mGrantFile;
985
986    /** XML constants used in {@link #mGrantFile} */
987    private static final String TAG_URI_GRANTS = "uri-grants";
988    private static final String TAG_URI_GRANT = "uri-grant";
989    private static final String ATTR_USER_HANDLE = "userHandle";
990    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
991    private static final String ATTR_TARGET_USER_ID = "targetUserId";
992    private static final String ATTR_SOURCE_PKG = "sourcePkg";
993    private static final String ATTR_TARGET_PKG = "targetPkg";
994    private static final String ATTR_URI = "uri";
995    private static final String ATTR_MODE_FLAGS = "modeFlags";
996    private static final String ATTR_CREATED_TIME = "createdTime";
997    private static final String ATTR_PREFIX = "prefix";
998
999    /**
1000     * Global set of specific {@link Uri} permissions that have been granted.
1001     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1002     * to {@link UriPermission#uri} to {@link UriPermission}.
1003     */
1004    @GuardedBy("this")
1005    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1006            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1007
1008    public static class GrantUri {
1009        public final int sourceUserId;
1010        public final Uri uri;
1011        public boolean prefix;
1012
1013        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1014            this.sourceUserId = sourceUserId;
1015            this.uri = uri;
1016            this.prefix = prefix;
1017        }
1018
1019        @Override
1020        public int hashCode() {
1021            int hashCode = 1;
1022            hashCode = 31 * hashCode + sourceUserId;
1023            hashCode = 31 * hashCode + uri.hashCode();
1024            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1025            return hashCode;
1026        }
1027
1028        @Override
1029        public boolean equals(Object o) {
1030            if (o instanceof GrantUri) {
1031                GrantUri other = (GrantUri) o;
1032                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1033                        && prefix == other.prefix;
1034            }
1035            return false;
1036        }
1037
1038        @Override
1039        public String toString() {
1040            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1041            if (prefix) result += " [prefix]";
1042            return result;
1043        }
1044
1045        public String toSafeString() {
1046            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1047            if (prefix) result += " [prefix]";
1048            return result;
1049        }
1050
1051        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1052            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1053                    ContentProvider.getUriWithoutUserId(uri), false);
1054        }
1055    }
1056
1057    CoreSettingsObserver mCoreSettingsObserver;
1058
1059    FontScaleSettingObserver mFontScaleSettingObserver;
1060
1061    private final class FontScaleSettingObserver extends ContentObserver {
1062        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1063
1064        public FontScaleSettingObserver() {
1065            super(mHandler);
1066            ContentResolver resolver = mContext.getContentResolver();
1067            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1068        }
1069
1070        @Override
1071        public void onChange(boolean selfChange, Uri uri) {
1072            if (mFontScaleUri.equals(uri)) {
1073                updateFontScaleIfNeeded();
1074            }
1075        }
1076    }
1077
1078    /**
1079     * Thread-local storage used to carry caller permissions over through
1080     * indirect content-provider access.
1081     */
1082    private class Identity {
1083        public final IBinder token;
1084        public final int pid;
1085        public final int uid;
1086
1087        Identity(IBinder _token, int _pid, int _uid) {
1088            token = _token;
1089            pid = _pid;
1090            uid = _uid;
1091        }
1092    }
1093
1094    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1095
1096    /**
1097     * All information we have collected about the runtime performance of
1098     * any user id that can impact battery performance.
1099     */
1100    final BatteryStatsService mBatteryStatsService;
1101
1102    /**
1103     * Information about component usage
1104     */
1105    UsageStatsManagerInternal mUsageStatsService;
1106
1107    /**
1108     * Access to DeviceIdleController service.
1109     */
1110    DeviceIdleController.LocalService mLocalDeviceIdleController;
1111
1112    /**
1113     * Information about and control over application operations
1114     */
1115    final AppOpsService mAppOpsService;
1116
1117    /**
1118     * Current configuration information.  HistoryRecord objects are given
1119     * a reference to this object to indicate which configuration they are
1120     * currently running in, so this object must be kept immutable.
1121     */
1122    Configuration mConfiguration = new Configuration();
1123
1124    /**
1125     * Current sequencing integer of the configuration, for skipping old
1126     * configurations.
1127     */
1128    int mConfigurationSeq = 0;
1129
1130    boolean mSuppressResizeConfigChanges = false;
1131
1132    /**
1133     * Hardware-reported OpenGLES version.
1134     */
1135    final int GL_ES_VERSION;
1136
1137    /**
1138     * List of initialization arguments to pass to all processes when binding applications to them.
1139     * For example, references to the commonly used services.
1140     */
1141    HashMap<String, IBinder> mAppBindArgs;
1142
1143    /**
1144     * Temporary to avoid allocations.  Protected by main lock.
1145     */
1146    final StringBuilder mStringBuilder = new StringBuilder(256);
1147
1148    /**
1149     * Used to control how we initialize the service.
1150     */
1151    ComponentName mTopComponent;
1152    String mTopAction = Intent.ACTION_MAIN;
1153    String mTopData;
1154
1155    volatile boolean mProcessesReady = false;
1156    volatile boolean mSystemReady = false;
1157    volatile boolean mOnBattery = false;
1158    volatile int mFactoryTest;
1159
1160    @GuardedBy("this") boolean mBooting = false;
1161    @GuardedBy("this") boolean mCallFinishBooting = false;
1162    @GuardedBy("this") boolean mBootAnimationComplete = false;
1163    @GuardedBy("this") boolean mLaunchWarningShown = false;
1164    @GuardedBy("this") boolean mCheckedForSetup = false;
1165
1166    Context mContext;
1167
1168    /**
1169     * The time at which we will allow normal application switches again,
1170     * after a call to {@link #stopAppSwitches()}.
1171     */
1172    long mAppSwitchesAllowedTime;
1173
1174    /**
1175     * This is set to true after the first switch after mAppSwitchesAllowedTime
1176     * is set; any switches after that will clear the time.
1177     */
1178    boolean mDidAppSwitch;
1179
1180    /**
1181     * Last time (in realtime) at which we checked for power usage.
1182     */
1183    long mLastPowerCheckRealtime;
1184
1185    /**
1186     * Last time (in uptime) at which we checked for power usage.
1187     */
1188    long mLastPowerCheckUptime;
1189
1190    /**
1191     * Set while we are wanting to sleep, to prevent any
1192     * activities from being started/resumed.
1193     */
1194    private boolean mSleeping = false;
1195
1196    /**
1197     * The process state used for processes that are running the top activities.
1198     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1199     */
1200    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1201
1202    /**
1203     * Set while we are running a voice interaction.  This overrides
1204     * sleeping while it is active.
1205     */
1206    private IVoiceInteractionSession mRunningVoice;
1207
1208    /**
1209     * For some direct access we need to power manager.
1210     */
1211    PowerManagerInternal mLocalPowerManager;
1212
1213    /**
1214     * We want to hold a wake lock while running a voice interaction session, since
1215     * this may happen with the screen off and we need to keep the CPU running to
1216     * be able to continue to interact with the user.
1217     */
1218    PowerManager.WakeLock mVoiceWakeLock;
1219
1220    /**
1221     * State of external calls telling us if the device is awake or asleep.
1222     */
1223    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1224
1225    /**
1226     * A list of tokens that cause the top activity to be put to sleep.
1227     * They are used by components that may hide and block interaction with underlying
1228     * activities.
1229     */
1230    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1231
1232    static final int LOCK_SCREEN_HIDDEN = 0;
1233    static final int LOCK_SCREEN_LEAVING = 1;
1234    static final int LOCK_SCREEN_SHOWN = 2;
1235    /**
1236     * State of external call telling us if the lock screen is shown.
1237     */
1238    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1239
1240    /**
1241     * Set if we are shutting down the system, similar to sleeping.
1242     */
1243    boolean mShuttingDown = false;
1244
1245    /**
1246     * Current sequence id for oom_adj computation traversal.
1247     */
1248    int mAdjSeq = 0;
1249
1250    /**
1251     * Current sequence id for process LRU updating.
1252     */
1253    int mLruSeq = 0;
1254
1255    /**
1256     * Keep track of the non-cached/empty process we last found, to help
1257     * determine how to distribute cached/empty processes next time.
1258     */
1259    int mNumNonCachedProcs = 0;
1260
1261    /**
1262     * Keep track of the number of cached hidden procs, to balance oom adj
1263     * distribution between those and empty procs.
1264     */
1265    int mNumCachedHiddenProcs = 0;
1266
1267    /**
1268     * Keep track of the number of service processes we last found, to
1269     * determine on the next iteration which should be B services.
1270     */
1271    int mNumServiceProcs = 0;
1272    int mNewNumAServiceProcs = 0;
1273    int mNewNumServiceProcs = 0;
1274
1275    /**
1276     * Allow the current computed overall memory level of the system to go down?
1277     * This is set to false when we are killing processes for reasons other than
1278     * memory management, so that the now smaller process list will not be taken as
1279     * an indication that memory is tighter.
1280     */
1281    boolean mAllowLowerMemLevel = false;
1282
1283    /**
1284     * The last computed memory level, for holding when we are in a state that
1285     * processes are going away for other reasons.
1286     */
1287    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1288
1289    /**
1290     * The last total number of process we have, to determine if changes actually look
1291     * like a shrinking number of process due to lower RAM.
1292     */
1293    int mLastNumProcesses;
1294
1295    /**
1296     * The uptime of the last time we performed idle maintenance.
1297     */
1298    long mLastIdleTime = SystemClock.uptimeMillis();
1299
1300    /**
1301     * Total time spent with RAM that has been added in the past since the last idle time.
1302     */
1303    long mLowRamTimeSinceLastIdle = 0;
1304
1305    /**
1306     * If RAM is currently low, when that horrible situation started.
1307     */
1308    long mLowRamStartTime = 0;
1309
1310    /**
1311     * For reporting to battery stats the current top application.
1312     */
1313    private String mCurResumedPackage = null;
1314    private int mCurResumedUid = -1;
1315
1316    /**
1317     * For reporting to battery stats the apps currently running foreground
1318     * service.  The ProcessMap is package/uid tuples; each of these contain
1319     * an array of the currently foreground processes.
1320     */
1321    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1322            = new ProcessMap<ArrayList<ProcessRecord>>();
1323
1324    /**
1325     * This is set if we had to do a delayed dexopt of an app before launching
1326     * it, to increase the ANR timeouts in that case.
1327     */
1328    boolean mDidDexOpt;
1329
1330    /**
1331     * Set if the systemServer made a call to enterSafeMode.
1332     */
1333    boolean mSafeMode;
1334
1335    /**
1336     * If true, we are running under a test environment so will sample PSS from processes
1337     * much more rapidly to try to collect better data when the tests are rapidly
1338     * running through apps.
1339     */
1340    boolean mTestPssMode = false;
1341
1342    String mDebugApp = null;
1343    boolean mWaitForDebugger = false;
1344    boolean mDebugTransient = false;
1345    String mOrigDebugApp = null;
1346    boolean mOrigWaitForDebugger = false;
1347    boolean mAlwaysFinishActivities = false;
1348    boolean mLenientBackgroundCheck = false;
1349    boolean mForceResizableActivities;
1350    boolean mSupportsMultiWindow;
1351    boolean mSupportsFreeformWindowManagement;
1352    boolean mSupportsPictureInPicture;
1353    boolean mSupportsLeanbackOnly;
1354    Rect mDefaultPinnedStackBounds;
1355    IActivityController mController = null;
1356    boolean mControllerIsAMonkey = false;
1357    String mProfileApp = null;
1358    ProcessRecord mProfileProc = null;
1359    String mProfileFile;
1360    ParcelFileDescriptor mProfileFd;
1361    int mSamplingInterval = 0;
1362    boolean mAutoStopProfiler = false;
1363    int mProfileType = 0;
1364    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1365    String mMemWatchDumpProcName;
1366    String mMemWatchDumpFile;
1367    int mMemWatchDumpPid;
1368    int mMemWatchDumpUid;
1369    String mTrackAllocationApp = null;
1370    String mNativeDebuggingApp = null;
1371
1372    final long[] mTmpLong = new long[2];
1373
1374    static final class ProcessChangeItem {
1375        static final int CHANGE_ACTIVITIES = 1<<0;
1376        static final int CHANGE_PROCESS_STATE = 1<<1;
1377        int changes;
1378        int uid;
1379        int pid;
1380        int processState;
1381        boolean foregroundActivities;
1382    }
1383
1384    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1385    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1386
1387    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1388    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1389
1390    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1391    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1392
1393    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1394    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1395
1396    /**
1397     * Runtime CPU use collection thread.  This object's lock is used to
1398     * perform synchronization with the thread (notifying it to run).
1399     */
1400    final Thread mProcessCpuThread;
1401
1402    /**
1403     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1404     * Must acquire this object's lock when accessing it.
1405     * NOTE: this lock will be held while doing long operations (trawling
1406     * through all processes in /proc), so it should never be acquired by
1407     * any critical paths such as when holding the main activity manager lock.
1408     */
1409    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1410            MONITOR_THREAD_CPU_USAGE);
1411    final AtomicLong mLastCpuTime = new AtomicLong(0);
1412    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1413
1414    long mLastWriteTime = 0;
1415
1416    /**
1417     * Used to retain an update lock when the foreground activity is in
1418     * immersive mode.
1419     */
1420    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1421
1422    /**
1423     * Set to true after the system has finished booting.
1424     */
1425    boolean mBooted = false;
1426
1427    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1428    int mProcessLimitOverride = -1;
1429
1430    WindowManagerService mWindowManager;
1431    final ActivityThread mSystemThread;
1432
1433    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1434        final ProcessRecord mApp;
1435        final int mPid;
1436        final IApplicationThread mAppThread;
1437
1438        AppDeathRecipient(ProcessRecord app, int pid,
1439                IApplicationThread thread) {
1440            if (DEBUG_ALL) Slog.v(
1441                TAG, "New death recipient " + this
1442                + " for thread " + thread.asBinder());
1443            mApp = app;
1444            mPid = pid;
1445            mAppThread = thread;
1446        }
1447
1448        @Override
1449        public void binderDied() {
1450            if (DEBUG_ALL) Slog.v(
1451                TAG, "Death received in " + this
1452                + " for thread " + mAppThread.asBinder());
1453            synchronized(ActivityManagerService.this) {
1454                appDiedLocked(mApp, mPid, mAppThread, true);
1455            }
1456        }
1457    }
1458
1459    static final int SHOW_ERROR_UI_MSG = 1;
1460    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1461    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1462    static final int UPDATE_CONFIGURATION_MSG = 4;
1463    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1464    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1465    static final int SERVICE_TIMEOUT_MSG = 12;
1466    static final int UPDATE_TIME_ZONE = 13;
1467    static final int SHOW_UID_ERROR_UI_MSG = 14;
1468    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1469    static final int PROC_START_TIMEOUT_MSG = 20;
1470    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1471    static final int KILL_APPLICATION_MSG = 22;
1472    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1473    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1474    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1475    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1476    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1477    static final int CLEAR_DNS_CACHE_MSG = 28;
1478    static final int UPDATE_HTTP_PROXY_MSG = 29;
1479    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1480    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1481    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1482    static final int REPORT_MEM_USAGE_MSG = 33;
1483    static final int REPORT_USER_SWITCH_MSG = 34;
1484    static final int CONTINUE_USER_SWITCH_MSG = 35;
1485    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1486    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1487    static final int PERSIST_URI_GRANTS_MSG = 38;
1488    static final int REQUEST_ALL_PSS_MSG = 39;
1489    static final int START_PROFILES_MSG = 40;
1490    static final int UPDATE_TIME = 41;
1491    static final int SYSTEM_USER_START_MSG = 42;
1492    static final int SYSTEM_USER_CURRENT_MSG = 43;
1493    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1494    static final int FINISH_BOOTING_MSG = 45;
1495    static final int START_USER_SWITCH_UI_MSG = 46;
1496    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1497    static final int DISMISS_DIALOG_UI_MSG = 48;
1498    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1499    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1500    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1501    static final int DELETE_DUMPHEAP_MSG = 52;
1502    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1503    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1504    static final int REPORT_TIME_TRACKER_MSG = 55;
1505    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1506    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1507    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1508    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1509    static final int IDLE_UIDS_MSG = 60;
1510    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1511    static final int LOG_STACK_STATE = 62;
1512    static final int VR_MODE_CHANGE_MSG = 63;
1513    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1514    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1515    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1516    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1517    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1518    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1519
1520    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1521    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1522    static final int FIRST_COMPAT_MODE_MSG = 300;
1523    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1524
1525    static ServiceThread sKillThread = null;
1526    static KillHandler sKillHandler = null;
1527
1528    CompatModeDialog mCompatModeDialog;
1529    long mLastMemUsageReportTime = 0;
1530
1531    /**
1532     * Flag whether the current user is a "monkey", i.e. whether
1533     * the UI is driven by a UI automation tool.
1534     */
1535    private boolean mUserIsMonkey;
1536
1537    /** Flag whether the device has a Recents UI */
1538    boolean mHasRecents;
1539
1540    /** The dimensions of the thumbnails in the Recents UI. */
1541    int mThumbnailWidth;
1542    int mThumbnailHeight;
1543    float mFullscreenThumbnailScale;
1544
1545    final ServiceThread mHandlerThread;
1546    final MainHandler mHandler;
1547    final UiHandler mUiHandler;
1548
1549    PackageManagerInternal mPackageManagerInt;
1550
1551    // VoiceInteraction session ID that changes for each new request except when
1552    // being called for multiwindow assist in a single session.
1553    private int mViSessionId = 1000;
1554
1555    final class KillHandler extends Handler {
1556        static final int KILL_PROCESS_GROUP_MSG = 4000;
1557
1558        public KillHandler(Looper looper) {
1559            super(looper, null, true);
1560        }
1561
1562        @Override
1563        public void handleMessage(Message msg) {
1564            switch (msg.what) {
1565                case KILL_PROCESS_GROUP_MSG:
1566                {
1567                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1568                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1569                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1570                }
1571                break;
1572
1573                default:
1574                    super.handleMessage(msg);
1575            }
1576        }
1577    }
1578
1579    final class UiHandler extends Handler {
1580        public UiHandler() {
1581            super(com.android.server.UiThread.get().getLooper(), null, true);
1582        }
1583
1584        @Override
1585        public void handleMessage(Message msg) {
1586            switch (msg.what) {
1587            case SHOW_ERROR_UI_MSG: {
1588                mAppErrors.handleShowAppErrorUi(msg);
1589                ensureBootCompleted();
1590            } break;
1591            case SHOW_NOT_RESPONDING_UI_MSG: {
1592                mAppErrors.handleShowAnrUi(msg);
1593                ensureBootCompleted();
1594            } break;
1595            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1596                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1597                synchronized (ActivityManagerService.this) {
1598                    ProcessRecord proc = (ProcessRecord) data.get("app");
1599                    if (proc == null) {
1600                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1601                        break;
1602                    }
1603                    if (proc.crashDialog != null) {
1604                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1605                        return;
1606                    }
1607                    AppErrorResult res = (AppErrorResult) data.get("result");
1608                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1609                        Dialog d = new StrictModeViolationDialog(mContext,
1610                                ActivityManagerService.this, res, proc);
1611                        d.show();
1612                        proc.crashDialog = d;
1613                    } else {
1614                        // The device is asleep, so just pretend that the user
1615                        // saw a crash dialog and hit "force quit".
1616                        res.set(0);
1617                    }
1618                }
1619                ensureBootCompleted();
1620            } break;
1621            case SHOW_FACTORY_ERROR_UI_MSG: {
1622                Dialog d = new FactoryErrorDialog(
1623                    mContext, msg.getData().getCharSequence("msg"));
1624                d.show();
1625                ensureBootCompleted();
1626            } break;
1627            case WAIT_FOR_DEBUGGER_UI_MSG: {
1628                synchronized (ActivityManagerService.this) {
1629                    ProcessRecord app = (ProcessRecord)msg.obj;
1630                    if (msg.arg1 != 0) {
1631                        if (!app.waitedForDebugger) {
1632                            Dialog d = new AppWaitingForDebuggerDialog(
1633                                    ActivityManagerService.this,
1634                                    mContext, app);
1635                            app.waitDialog = d;
1636                            app.waitedForDebugger = true;
1637                            d.show();
1638                        }
1639                    } else {
1640                        if (app.waitDialog != null) {
1641                            app.waitDialog.dismiss();
1642                            app.waitDialog = null;
1643                        }
1644                    }
1645                }
1646            } break;
1647            case SHOW_UID_ERROR_UI_MSG: {
1648                if (mShowDialogs) {
1649                    AlertDialog d = new BaseErrorDialog(mContext);
1650                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1651                    d.setCancelable(false);
1652                    d.setTitle(mContext.getText(R.string.android_system_label));
1653                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1654                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1655                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1656                    d.show();
1657                }
1658            } break;
1659            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1660                if (mShowDialogs) {
1661                    AlertDialog d = new BaseErrorDialog(mContext);
1662                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1663                    d.setCancelable(false);
1664                    d.setTitle(mContext.getText(R.string.android_system_label));
1665                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1666                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1667                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1668                    d.show();
1669                }
1670            } break;
1671            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1672                synchronized (ActivityManagerService.this) {
1673                    ActivityRecord ar = (ActivityRecord) msg.obj;
1674                    if (mCompatModeDialog != null) {
1675                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1676                                ar.info.applicationInfo.packageName)) {
1677                            return;
1678                        }
1679                        mCompatModeDialog.dismiss();
1680                        mCompatModeDialog = null;
1681                    }
1682                    if (ar != null && false) {
1683                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1684                                ar.packageName)) {
1685                            int mode = mCompatModePackages.computeCompatModeLocked(
1686                                    ar.info.applicationInfo);
1687                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1688                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1689                                mCompatModeDialog = new CompatModeDialog(
1690                                        ActivityManagerService.this, mContext,
1691                                        ar.info.applicationInfo);
1692                                mCompatModeDialog.show();
1693                            }
1694                        }
1695                    }
1696                }
1697                break;
1698            }
1699            case START_USER_SWITCH_UI_MSG: {
1700                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1701                break;
1702            }
1703            case DISMISS_DIALOG_UI_MSG: {
1704                final Dialog d = (Dialog) msg.obj;
1705                d.dismiss();
1706                break;
1707            }
1708            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1709                dispatchProcessesChanged();
1710                break;
1711            }
1712            case DISPATCH_PROCESS_DIED_UI_MSG: {
1713                final int pid = msg.arg1;
1714                final int uid = msg.arg2;
1715                dispatchProcessDied(pid, uid);
1716                break;
1717            }
1718            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1719                dispatchUidsChanged();
1720            } break;
1721            }
1722        }
1723    }
1724
1725    final class MainHandler extends Handler {
1726        public MainHandler(Looper looper) {
1727            super(looper, null, true);
1728        }
1729
1730        @Override
1731        public void handleMessage(Message msg) {
1732            switch (msg.what) {
1733            case UPDATE_CONFIGURATION_MSG: {
1734                final ContentResolver resolver = mContext.getContentResolver();
1735                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1736                        msg.arg1);
1737            } break;
1738            case GC_BACKGROUND_PROCESSES_MSG: {
1739                synchronized (ActivityManagerService.this) {
1740                    performAppGcsIfAppropriateLocked();
1741                }
1742            } break;
1743            case SERVICE_TIMEOUT_MSG: {
1744                if (mDidDexOpt) {
1745                    mDidDexOpt = false;
1746                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1747                    nmsg.obj = msg.obj;
1748                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1749                    return;
1750                }
1751                mServices.serviceTimeout((ProcessRecord)msg.obj);
1752            } break;
1753            case UPDATE_TIME_ZONE: {
1754                synchronized (ActivityManagerService.this) {
1755                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1756                        ProcessRecord r = mLruProcesses.get(i);
1757                        if (r.thread != null) {
1758                            try {
1759                                r.thread.updateTimeZone();
1760                            } catch (RemoteException ex) {
1761                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1762                            }
1763                        }
1764                    }
1765                }
1766            } break;
1767            case CLEAR_DNS_CACHE_MSG: {
1768                synchronized (ActivityManagerService.this) {
1769                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1770                        ProcessRecord r = mLruProcesses.get(i);
1771                        if (r.thread != null) {
1772                            try {
1773                                r.thread.clearDnsCache();
1774                            } catch (RemoteException ex) {
1775                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1776                            }
1777                        }
1778                    }
1779                }
1780            } break;
1781            case UPDATE_HTTP_PROXY_MSG: {
1782                ProxyInfo proxy = (ProxyInfo)msg.obj;
1783                String host = "";
1784                String port = "";
1785                String exclList = "";
1786                Uri pacFileUrl = Uri.EMPTY;
1787                if (proxy != null) {
1788                    host = proxy.getHost();
1789                    port = Integer.toString(proxy.getPort());
1790                    exclList = proxy.getExclusionListAsString();
1791                    pacFileUrl = proxy.getPacFileUrl();
1792                }
1793                synchronized (ActivityManagerService.this) {
1794                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1795                        ProcessRecord r = mLruProcesses.get(i);
1796                        if (r.thread != null) {
1797                            try {
1798                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1799                            } catch (RemoteException ex) {
1800                                Slog.w(TAG, "Failed to update http proxy for: " +
1801                                        r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806            } break;
1807            case PROC_START_TIMEOUT_MSG: {
1808                if (mDidDexOpt) {
1809                    mDidDexOpt = false;
1810                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1811                    nmsg.obj = msg.obj;
1812                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1813                    return;
1814                }
1815                ProcessRecord app = (ProcessRecord)msg.obj;
1816                synchronized (ActivityManagerService.this) {
1817                    processStartTimedOutLocked(app);
1818                }
1819            } break;
1820            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1821                ProcessRecord app = (ProcessRecord)msg.obj;
1822                synchronized (ActivityManagerService.this) {
1823                    processContentProviderPublishTimedOutLocked(app);
1824                }
1825            } break;
1826            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1827                synchronized (ActivityManagerService.this) {
1828                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1829                }
1830            } break;
1831            case KILL_APPLICATION_MSG: {
1832                synchronized (ActivityManagerService.this) {
1833                    int appid = msg.arg1;
1834                    boolean restart = (msg.arg2 == 1);
1835                    Bundle bundle = (Bundle)msg.obj;
1836                    String pkg = bundle.getString("pkg");
1837                    String reason = bundle.getString("reason");
1838                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1839                            false, UserHandle.USER_ALL, reason);
1840                }
1841            } break;
1842            case FINALIZE_PENDING_INTENT_MSG: {
1843                ((PendingIntentRecord)msg.obj).completeFinalize();
1844            } break;
1845            case POST_HEAVY_NOTIFICATION_MSG: {
1846                INotificationManager inm = NotificationManager.getService();
1847                if (inm == null) {
1848                    return;
1849                }
1850
1851                ActivityRecord root = (ActivityRecord)msg.obj;
1852                ProcessRecord process = root.app;
1853                if (process == null) {
1854                    return;
1855                }
1856
1857                try {
1858                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1859                    String text = mContext.getString(R.string.heavy_weight_notification,
1860                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1861                    Notification notification = new Notification.Builder(context)
1862                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1863                            .setWhen(0)
1864                            .setOngoing(true)
1865                            .setTicker(text)
1866                            .setColor(mContext.getColor(
1867                                    com.android.internal.R.color.system_notification_accent_color))
1868                            .setContentTitle(text)
1869                            .setContentText(
1870                                    mContext.getText(R.string.heavy_weight_notification_detail))
1871                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1872                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1873                                    new UserHandle(root.userId)))
1874                            .build();
1875                    try {
1876                        int[] outId = new int[1];
1877                        inm.enqueueNotificationWithTag("android", "android", null,
1878                                R.string.heavy_weight_notification,
1879                                notification, outId, root.userId);
1880                    } catch (RuntimeException e) {
1881                        Slog.w(ActivityManagerService.TAG,
1882                                "Error showing notification for heavy-weight app", e);
1883                    } catch (RemoteException e) {
1884                    }
1885                } catch (NameNotFoundException e) {
1886                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1887                }
1888            } break;
1889            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1890                INotificationManager inm = NotificationManager.getService();
1891                if (inm == null) {
1892                    return;
1893                }
1894                try {
1895                    inm.cancelNotificationWithTag("android", null,
1896                            R.string.heavy_weight_notification,  msg.arg1);
1897                } catch (RuntimeException e) {
1898                    Slog.w(ActivityManagerService.TAG,
1899                            "Error canceling notification for service", e);
1900                } catch (RemoteException e) {
1901                }
1902            } break;
1903            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1904                synchronized (ActivityManagerService.this) {
1905                    checkExcessivePowerUsageLocked(true);
1906                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1907                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1908                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1909                }
1910            } break;
1911            case REPORT_MEM_USAGE_MSG: {
1912                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1913                Thread thread = new Thread() {
1914                    @Override public void run() {
1915                        reportMemUsage(memInfos);
1916                    }
1917                };
1918                thread.start();
1919                break;
1920            }
1921            case REPORT_USER_SWITCH_MSG: {
1922                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1923                break;
1924            }
1925            case CONTINUE_USER_SWITCH_MSG: {
1926                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1927                break;
1928            }
1929            case USER_SWITCH_TIMEOUT_MSG: {
1930                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1931                break;
1932            }
1933            case IMMERSIVE_MODE_LOCK_MSG: {
1934                final boolean nextState = (msg.arg1 != 0);
1935                if (mUpdateLock.isHeld() != nextState) {
1936                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1937                            "Applying new update lock state '" + nextState
1938                            + "' for " + (ActivityRecord)msg.obj);
1939                    if (nextState) {
1940                        mUpdateLock.acquire();
1941                    } else {
1942                        mUpdateLock.release();
1943                    }
1944                }
1945                break;
1946            }
1947            case PERSIST_URI_GRANTS_MSG: {
1948                writeGrantedUriPermissions();
1949                break;
1950            }
1951            case REQUEST_ALL_PSS_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1954                }
1955                break;
1956            }
1957            case START_PROFILES_MSG: {
1958                synchronized (ActivityManagerService.this) {
1959                    mUserController.startProfilesLocked();
1960                }
1961                break;
1962            }
1963            case UPDATE_TIME: {
1964                synchronized (ActivityManagerService.this) {
1965                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1966                        ProcessRecord r = mLruProcesses.get(i);
1967                        if (r.thread != null) {
1968                            try {
1969                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1970                            } catch (RemoteException ex) {
1971                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1972                            }
1973                        }
1974                    }
1975                }
1976                break;
1977            }
1978            case SYSTEM_USER_START_MSG: {
1979                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1980                        Integer.toString(msg.arg1), msg.arg1);
1981                mSystemServiceManager.startUser(msg.arg1);
1982                break;
1983            }
1984            case SYSTEM_USER_UNLOCK_MSG: {
1985                final int userId = msg.arg1;
1986                mSystemServiceManager.unlockUser(userId);
1987                synchronized (ActivityManagerService.this) {
1988                    mRecentTasks.loadUserRecentsLocked(userId);
1989                }
1990                if (userId == UserHandle.USER_SYSTEM) {
1991                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1992                }
1993                installEncryptionUnawareProviders(userId);
1994                mUserController.finishUserUnlocked((UserState) msg.obj);
1995                break;
1996            }
1997            case SYSTEM_USER_CURRENT_MSG: {
1998                mBatteryStatsService.noteEvent(
1999                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2000                        Integer.toString(msg.arg2), msg.arg2);
2001                mBatteryStatsService.noteEvent(
2002                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2003                        Integer.toString(msg.arg1), msg.arg1);
2004                mSystemServiceManager.switchUser(msg.arg1);
2005                break;
2006            }
2007            case ENTER_ANIMATION_COMPLETE_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2010                    if (r != null && r.app != null && r.app.thread != null) {
2011                        try {
2012                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2013                        } catch (RemoteException e) {
2014                        }
2015                    }
2016                }
2017                break;
2018            }
2019            case FINISH_BOOTING_MSG: {
2020                if (msg.arg1 != 0) {
2021                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2022                    finishBooting();
2023                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2024                }
2025                if (msg.arg2 != 0) {
2026                    enableScreenAfterBoot();
2027                }
2028                break;
2029            }
2030            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2031                try {
2032                    Locale l = (Locale) msg.obj;
2033                    IBinder service = ServiceManager.getService("mount");
2034                    IMountService mountService = IMountService.Stub.asInterface(service);
2035                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2036                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2037                } catch (RemoteException e) {
2038                    Log.e(TAG, "Error storing locale for decryption UI", e);
2039                }
2040                break;
2041            }
2042            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2043                synchronized (ActivityManagerService.this) {
2044                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2045                        try {
2046                            // Make a one-way callback to the listener
2047                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2048                        } catch (RemoteException e){
2049                            // Handled by the RemoteCallbackList
2050                        }
2051                    }
2052                    mTaskStackListeners.finishBroadcast();
2053                }
2054                break;
2055            }
2056            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2057                synchronized (ActivityManagerService.this) {
2058                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2059                        try {
2060                            // Make a one-way callback to the listener
2061                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2062                        } catch (RemoteException e){
2063                            // Handled by the RemoteCallbackList
2064                        }
2065                    }
2066                    mTaskStackListeners.finishBroadcast();
2067                }
2068                break;
2069            }
2070            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2071                synchronized (ActivityManagerService.this) {
2072                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2073                        try {
2074                            // Make a one-way callback to the listener
2075                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2076                        } catch (RemoteException e){
2077                            // Handled by the RemoteCallbackList
2078                        }
2079                    }
2080                    mTaskStackListeners.finishBroadcast();
2081                }
2082                break;
2083            }
2084            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2085                synchronized (ActivityManagerService.this) {
2086                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2087                        try {
2088                            // Make a one-way callback to the listener
2089                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2090                        } catch (RemoteException e){
2091                            // Handled by the RemoteCallbackList
2092                        }
2093                    }
2094                    mTaskStackListeners.finishBroadcast();
2095                }
2096                break;
2097            }
2098            case NOTIFY_FORCED_RESIZABLE_MSG: {
2099                synchronized (ActivityManagerService.this) {
2100                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2101                        try {
2102                            // Make a one-way callback to the listener
2103                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2104                                    (String) msg.obj, msg.arg1);
2105                        } catch (RemoteException e){
2106                            // Handled by the RemoteCallbackList
2107                        }
2108                    }
2109                    mTaskStackListeners.finishBroadcast();
2110                }
2111                break;
2112            }
2113                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2114                    synchronized (ActivityManagerService.this) {
2115                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2116                            try {
2117                                // Make a one-way callback to the listener
2118                                mTaskStackListeners.getBroadcastItem(i)
2119                                        .onActivityDismissingDockedStack();
2120                            } catch (RemoteException e){
2121                                // Handled by the RemoteCallbackList
2122                            }
2123                        }
2124                        mTaskStackListeners.finishBroadcast();
2125                    }
2126                    break;
2127                }
2128            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2129                final int uid = msg.arg1;
2130                final byte[] firstPacket = (byte[]) msg.obj;
2131
2132                synchronized (mPidsSelfLocked) {
2133                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2134                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2135                        if (p.uid == uid) {
2136                            try {
2137                                p.thread.notifyCleartextNetwork(firstPacket);
2138                            } catch (RemoteException ignored) {
2139                            }
2140                        }
2141                    }
2142                }
2143                break;
2144            }
2145            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2146                final String procName;
2147                final int uid;
2148                final long memLimit;
2149                final String reportPackage;
2150                synchronized (ActivityManagerService.this) {
2151                    procName = mMemWatchDumpProcName;
2152                    uid = mMemWatchDumpUid;
2153                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2154                    if (val == null) {
2155                        val = mMemWatchProcesses.get(procName, 0);
2156                    }
2157                    if (val != null) {
2158                        memLimit = val.first;
2159                        reportPackage = val.second;
2160                    } else {
2161                        memLimit = 0;
2162                        reportPackage = null;
2163                    }
2164                }
2165                if (procName == null) {
2166                    return;
2167                }
2168
2169                if (DEBUG_PSS) Slog.d(TAG_PSS,
2170                        "Showing dump heap notification from " + procName + "/" + uid);
2171
2172                INotificationManager inm = NotificationManager.getService();
2173                if (inm == null) {
2174                    return;
2175                }
2176
2177                String text = mContext.getString(R.string.dump_heap_notification, procName);
2178
2179
2180                Intent deleteIntent = new Intent();
2181                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2182                Intent intent = new Intent();
2183                intent.setClassName("android", DumpHeapActivity.class.getName());
2184                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2185                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2186                if (reportPackage != null) {
2187                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2188                }
2189                int userId = UserHandle.getUserId(uid);
2190                Notification notification = new Notification.Builder(mContext)
2191                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2192                        .setWhen(0)
2193                        .setOngoing(true)
2194                        .setAutoCancel(true)
2195                        .setTicker(text)
2196                        .setColor(mContext.getColor(
2197                                com.android.internal.R.color.system_notification_accent_color))
2198                        .setContentTitle(text)
2199                        .setContentText(
2200                                mContext.getText(R.string.dump_heap_notification_detail))
2201                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2202                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2203                                new UserHandle(userId)))
2204                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2205                                deleteIntent, 0, UserHandle.SYSTEM))
2206                        .build();
2207
2208                try {
2209                    int[] outId = new int[1];
2210                    inm.enqueueNotificationWithTag("android", "android", null,
2211                            R.string.dump_heap_notification,
2212                            notification, outId, userId);
2213                } catch (RuntimeException e) {
2214                    Slog.w(ActivityManagerService.TAG,
2215                            "Error showing notification for dump heap", e);
2216                } catch (RemoteException e) {
2217                }
2218            } break;
2219            case DELETE_DUMPHEAP_MSG: {
2220                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2221                        DumpHeapActivity.JAVA_URI,
2222                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2223                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2224                        UserHandle.myUserId());
2225                synchronized (ActivityManagerService.this) {
2226                    mMemWatchDumpFile = null;
2227                    mMemWatchDumpProcName = null;
2228                    mMemWatchDumpPid = -1;
2229                    mMemWatchDumpUid = -1;
2230                }
2231            } break;
2232            case FOREGROUND_PROFILE_CHANGED_MSG: {
2233                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2234            } break;
2235            case REPORT_TIME_TRACKER_MSG: {
2236                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2237                tracker.deliverResult(mContext);
2238            } break;
2239            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2240                mUserController.dispatchUserSwitchComplete(msg.arg1);
2241            } break;
2242            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2243                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2244                try {
2245                    connection.shutdown();
2246                } catch (RemoteException e) {
2247                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2248                }
2249                // Only a UiAutomation can set this flag and now that
2250                // it is finished we make sure it is reset to its default.
2251                mUserIsMonkey = false;
2252            } break;
2253            case APP_BOOST_DEACTIVATE_MSG: {
2254                synchronized(ActivityManagerService.this) {
2255                    if (mIsBoosted) {
2256                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2257                            nativeMigrateFromBoost();
2258                            mIsBoosted = false;
2259                            mBoostStartTime = 0;
2260                        } else {
2261                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2262                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2263                        }
2264                    }
2265                }
2266            } break;
2267            case IDLE_UIDS_MSG: {
2268                idleUids();
2269            } break;
2270            case LOG_STACK_STATE: {
2271                synchronized (ActivityManagerService.this) {
2272                    mStackSupervisor.logStackState();
2273                }
2274            } break;
2275            case VR_MODE_CHANGE_MSG: {
2276                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2277                final ActivityRecord r = (ActivityRecord) msg.obj;
2278                boolean vrMode;
2279                ComponentName requestedPackage;
2280                ComponentName callingPackage;
2281                int userId;
2282                synchronized (ActivityManagerService.this) {
2283                    vrMode = r.requestedVrComponent != null;
2284                    requestedPackage = r.requestedVrComponent;
2285                    userId = r.userId;
2286                    callingPackage = r.info.getComponentName();
2287                    if (mInVrMode != vrMode) {
2288                        mInVrMode = vrMode;
2289                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2290                    }
2291                }
2292                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2293            } break;
2294            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2295                final ActivityRecord r = (ActivityRecord) msg.obj;
2296                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2297                if (needsVrMode) {
2298                    VrManagerInternal vrService =
2299                            LocalServices.getService(VrManagerInternal.class);
2300                    boolean enable = msg.arg1 == 1;
2301                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2302                            r.info.getComponentName());
2303                }
2304            } break;
2305            }
2306        }
2307    };
2308
2309    static final int COLLECT_PSS_BG_MSG = 1;
2310
2311    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2312        @Override
2313        public void handleMessage(Message msg) {
2314            switch (msg.what) {
2315            case COLLECT_PSS_BG_MSG: {
2316                long start = SystemClock.uptimeMillis();
2317                MemInfoReader memInfo = null;
2318                synchronized (ActivityManagerService.this) {
2319                    if (mFullPssPending) {
2320                        mFullPssPending = false;
2321                        memInfo = new MemInfoReader();
2322                    }
2323                }
2324                if (memInfo != null) {
2325                    updateCpuStatsNow();
2326                    long nativeTotalPss = 0;
2327                    synchronized (mProcessCpuTracker) {
2328                        final int N = mProcessCpuTracker.countStats();
2329                        for (int j=0; j<N; j++) {
2330                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2331                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2332                                // This is definitely an application process; skip it.
2333                                continue;
2334                            }
2335                            synchronized (mPidsSelfLocked) {
2336                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2337                                    // This is one of our own processes; skip it.
2338                                    continue;
2339                                }
2340                            }
2341                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2342                        }
2343                    }
2344                    memInfo.readMemInfo();
2345                    synchronized (ActivityManagerService.this) {
2346                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2347                                + (SystemClock.uptimeMillis()-start) + "ms");
2348                        final long cachedKb = memInfo.getCachedSizeKb();
2349                        final long freeKb = memInfo.getFreeSizeKb();
2350                        final long zramKb = memInfo.getZramTotalSizeKb();
2351                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2352                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2353                                kernelKb*1024, nativeTotalPss*1024);
2354                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2355                                nativeTotalPss);
2356                    }
2357                }
2358
2359                int num = 0;
2360                long[] tmp = new long[2];
2361                do {
2362                    ProcessRecord proc;
2363                    int procState;
2364                    int pid;
2365                    long lastPssTime;
2366                    synchronized (ActivityManagerService.this) {
2367                        if (mPendingPssProcesses.size() <= 0) {
2368                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2369                                    "Collected PSS of " + num + " processes in "
2370                                    + (SystemClock.uptimeMillis() - start) + "ms");
2371                            mPendingPssProcesses.clear();
2372                            return;
2373                        }
2374                        proc = mPendingPssProcesses.remove(0);
2375                        procState = proc.pssProcState;
2376                        lastPssTime = proc.lastPssTime;
2377                        if (proc.thread != null && procState == proc.setProcState
2378                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2379                                        < SystemClock.uptimeMillis()) {
2380                            pid = proc.pid;
2381                        } else {
2382                            proc = null;
2383                            pid = 0;
2384                        }
2385                    }
2386                    if (proc != null) {
2387                        long pss = Debug.getPss(pid, tmp, null);
2388                        synchronized (ActivityManagerService.this) {
2389                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2390                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2391                                num++;
2392                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2393                                        SystemClock.uptimeMillis());
2394                            }
2395                        }
2396                    }
2397                } while (true);
2398            }
2399            }
2400        }
2401    };
2402
2403    public void setSystemProcess() {
2404        try {
2405            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2406            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2407            ServiceManager.addService("meminfo", new MemBinder(this));
2408            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2409            ServiceManager.addService("dbinfo", new DbBinder(this));
2410            if (MONITOR_CPU_USAGE) {
2411                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2412            }
2413            ServiceManager.addService("permission", new PermissionController(this));
2414            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2415
2416            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2417                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2418            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2419
2420            synchronized (this) {
2421                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2422                app.persistent = true;
2423                app.pid = MY_PID;
2424                app.maxAdj = ProcessList.SYSTEM_ADJ;
2425                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2426                synchronized (mPidsSelfLocked) {
2427                    mPidsSelfLocked.put(app.pid, app);
2428                }
2429                updateLruProcessLocked(app, false, null);
2430                updateOomAdjLocked();
2431            }
2432        } catch (PackageManager.NameNotFoundException e) {
2433            throw new RuntimeException(
2434                    "Unable to find android system package", e);
2435        }
2436    }
2437
2438    public void setWindowManager(WindowManagerService wm) {
2439        mWindowManager = wm;
2440        mStackSupervisor.setWindowManager(wm);
2441        mActivityStarter.setWindowManager(wm);
2442    }
2443
2444    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2445        mUsageStatsService = usageStatsManager;
2446    }
2447
2448    public void startObservingNativeCrashes() {
2449        final NativeCrashListener ncl = new NativeCrashListener(this);
2450        ncl.start();
2451    }
2452
2453    public IAppOpsService getAppOpsService() {
2454        return mAppOpsService;
2455    }
2456
2457    static class MemBinder extends Binder {
2458        ActivityManagerService mActivityManagerService;
2459        MemBinder(ActivityManagerService activityManagerService) {
2460            mActivityManagerService = activityManagerService;
2461        }
2462
2463        @Override
2464        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2465            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2466                    != PackageManager.PERMISSION_GRANTED) {
2467                pw.println("Permission Denial: can't dump meminfo from from pid="
2468                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2469                        + " without permission " + android.Manifest.permission.DUMP);
2470                return;
2471            }
2472
2473            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2474        }
2475    }
2476
2477    static class GraphicsBinder extends Binder {
2478        ActivityManagerService mActivityManagerService;
2479        GraphicsBinder(ActivityManagerService activityManagerService) {
2480            mActivityManagerService = activityManagerService;
2481        }
2482
2483        @Override
2484        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2485            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2486                    != PackageManager.PERMISSION_GRANTED) {
2487                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2488                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2489                        + " without permission " + android.Manifest.permission.DUMP);
2490                return;
2491            }
2492
2493            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2494        }
2495    }
2496
2497    static class DbBinder extends Binder {
2498        ActivityManagerService mActivityManagerService;
2499        DbBinder(ActivityManagerService activityManagerService) {
2500            mActivityManagerService = activityManagerService;
2501        }
2502
2503        @Override
2504        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2505            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2506                    != PackageManager.PERMISSION_GRANTED) {
2507                pw.println("Permission Denial: can't dump dbinfo from from pid="
2508                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2509                        + " without permission " + android.Manifest.permission.DUMP);
2510                return;
2511            }
2512
2513            mActivityManagerService.dumpDbInfo(fd, pw, args);
2514        }
2515    }
2516
2517    static class CpuBinder extends Binder {
2518        ActivityManagerService mActivityManagerService;
2519        CpuBinder(ActivityManagerService activityManagerService) {
2520            mActivityManagerService = activityManagerService;
2521        }
2522
2523        @Override
2524        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526                    != PackageManager.PERMISSION_GRANTED) {
2527                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2528                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529                        + " without permission " + android.Manifest.permission.DUMP);
2530                return;
2531            }
2532
2533            synchronized (mActivityManagerService.mProcessCpuTracker) {
2534                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2535                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2536                        SystemClock.uptimeMillis()));
2537            }
2538        }
2539    }
2540
2541    public static final class Lifecycle extends SystemService {
2542        private final ActivityManagerService mService;
2543
2544        public Lifecycle(Context context) {
2545            super(context);
2546            mService = new ActivityManagerService(context);
2547        }
2548
2549        @Override
2550        public void onStart() {
2551            mService.start();
2552        }
2553
2554        public ActivityManagerService getService() {
2555            return mService;
2556        }
2557    }
2558
2559    // Note: This method is invoked on the main thread but may need to attach various
2560    // handlers to other threads.  So take care to be explicit about the looper.
2561    public ActivityManagerService(Context systemContext) {
2562        mContext = systemContext;
2563        mFactoryTest = FactoryTest.getMode();
2564        mSystemThread = ActivityThread.currentActivityThread();
2565
2566        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2567
2568        mHandlerThread = new ServiceThread(TAG,
2569                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2570        mHandlerThread.start();
2571        mHandler = new MainHandler(mHandlerThread.getLooper());
2572        mUiHandler = new UiHandler();
2573
2574        /* static; one-time init here */
2575        if (sKillHandler == null) {
2576            sKillThread = new ServiceThread(TAG + ":kill",
2577                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2578            sKillThread.start();
2579            sKillHandler = new KillHandler(sKillThread.getLooper());
2580        }
2581
2582        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2583                "foreground", BROADCAST_FG_TIMEOUT, false);
2584        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2585                "background", BROADCAST_BG_TIMEOUT, true);
2586        mBroadcastQueues[0] = mFgBroadcastQueue;
2587        mBroadcastQueues[1] = mBgBroadcastQueue;
2588
2589        mServices = new ActiveServices(this);
2590        mProviderMap = new ProviderMap(this);
2591        mAppErrors = new AppErrors(mContext, this);
2592
2593        // TODO: Move creation of battery stats service outside of activity manager service.
2594        File dataDir = Environment.getDataDirectory();
2595        File systemDir = new File(dataDir, "system");
2596        systemDir.mkdirs();
2597        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2598        mBatteryStatsService.getActiveStatistics().readLocked();
2599        mBatteryStatsService.scheduleWriteToDisk();
2600        mOnBattery = DEBUG_POWER ? true
2601                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2602        mBatteryStatsService.getActiveStatistics().setCallback(this);
2603
2604        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2605
2606        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2607        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2608                new IAppOpsCallback.Stub() {
2609                    @Override public void opChanged(int op, int uid, String packageName) {
2610                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2611                            if (mAppOpsService.checkOperation(op, uid, packageName)
2612                                    != AppOpsManager.MODE_ALLOWED) {
2613                                runInBackgroundDisabled(uid);
2614                            }
2615                        }
2616                    }
2617                });
2618
2619        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2620
2621        mUserController = new UserController(this);
2622
2623        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2624            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2625
2626        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2627
2628        mConfiguration.setToDefaults();
2629        mConfiguration.setLocales(LocaleList.getDefault());
2630
2631        mConfigurationSeq = mConfiguration.seq = 1;
2632        mProcessCpuTracker.init();
2633
2634        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2635        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2636        mStackSupervisor = new ActivityStackSupervisor(this);
2637        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2638        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2639
2640        mProcessCpuThread = new Thread("CpuTracker") {
2641            @Override
2642            public void run() {
2643                while (true) {
2644                    try {
2645                        try {
2646                            synchronized(this) {
2647                                final long now = SystemClock.uptimeMillis();
2648                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2649                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2650                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2651                                //        + ", write delay=" + nextWriteDelay);
2652                                if (nextWriteDelay < nextCpuDelay) {
2653                                    nextCpuDelay = nextWriteDelay;
2654                                }
2655                                if (nextCpuDelay > 0) {
2656                                    mProcessCpuMutexFree.set(true);
2657                                    this.wait(nextCpuDelay);
2658                                }
2659                            }
2660                        } catch (InterruptedException e) {
2661                        }
2662                        updateCpuStatsNow();
2663                    } catch (Exception e) {
2664                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2665                    }
2666                }
2667            }
2668        };
2669
2670        Watchdog.getInstance().addMonitor(this);
2671        Watchdog.getInstance().addThread(mHandler);
2672    }
2673
2674    public void setSystemServiceManager(SystemServiceManager mgr) {
2675        mSystemServiceManager = mgr;
2676    }
2677
2678    public void setInstaller(Installer installer) {
2679        mInstaller = installer;
2680    }
2681
2682    private void start() {
2683        Process.removeAllProcessGroups();
2684        mProcessCpuThread.start();
2685
2686        mBatteryStatsService.publish(mContext);
2687        mAppOpsService.publish(mContext);
2688        Slog.d("AppOps", "AppOpsService published");
2689        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2690    }
2691
2692    void onUserStoppedLocked(int userId) {
2693        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2694    }
2695
2696    public void initPowerManagement() {
2697        mStackSupervisor.initPowerManagement();
2698        mBatteryStatsService.initPowerManagement();
2699        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2700        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2701        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2702        mVoiceWakeLock.setReferenceCounted(false);
2703    }
2704
2705    @Override
2706    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2707            throws RemoteException {
2708        if (code == SYSPROPS_TRANSACTION) {
2709            // We need to tell all apps about the system property change.
2710            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2711            synchronized(this) {
2712                final int NP = mProcessNames.getMap().size();
2713                for (int ip=0; ip<NP; ip++) {
2714                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2715                    final int NA = apps.size();
2716                    for (int ia=0; ia<NA; ia++) {
2717                        ProcessRecord app = apps.valueAt(ia);
2718                        if (app.thread != null) {
2719                            procs.add(app.thread.asBinder());
2720                        }
2721                    }
2722                }
2723            }
2724
2725            int N = procs.size();
2726            for (int i=0; i<N; i++) {
2727                Parcel data2 = Parcel.obtain();
2728                try {
2729                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2730                } catch (RemoteException e) {
2731                }
2732                data2.recycle();
2733            }
2734        }
2735        try {
2736            return super.onTransact(code, data, reply, flags);
2737        } catch (RuntimeException e) {
2738            // The activity manager only throws security exceptions, so let's
2739            // log all others.
2740            if (!(e instanceof SecurityException)) {
2741                Slog.wtf(TAG, "Activity Manager Crash", e);
2742            }
2743            throw e;
2744        }
2745    }
2746
2747    void updateCpuStats() {
2748        final long now = SystemClock.uptimeMillis();
2749        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2750            return;
2751        }
2752        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2753            synchronized (mProcessCpuThread) {
2754                mProcessCpuThread.notify();
2755            }
2756        }
2757    }
2758
2759    void updateCpuStatsNow() {
2760        synchronized (mProcessCpuTracker) {
2761            mProcessCpuMutexFree.set(false);
2762            final long now = SystemClock.uptimeMillis();
2763            boolean haveNewCpuStats = false;
2764
2765            if (MONITOR_CPU_USAGE &&
2766                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2767                mLastCpuTime.set(now);
2768                mProcessCpuTracker.update();
2769                if (mProcessCpuTracker.hasGoodLastStats()) {
2770                    haveNewCpuStats = true;
2771                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2772                    //Slog.i(TAG, "Total CPU usage: "
2773                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2774
2775                    // Slog the cpu usage if the property is set.
2776                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2777                        int user = mProcessCpuTracker.getLastUserTime();
2778                        int system = mProcessCpuTracker.getLastSystemTime();
2779                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2780                        int irq = mProcessCpuTracker.getLastIrqTime();
2781                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2782                        int idle = mProcessCpuTracker.getLastIdleTime();
2783
2784                        int total = user + system + iowait + irq + softIrq + idle;
2785                        if (total == 0) total = 1;
2786
2787                        EventLog.writeEvent(EventLogTags.CPU,
2788                                ((user+system+iowait+irq+softIrq) * 100) / total,
2789                                (user * 100) / total,
2790                                (system * 100) / total,
2791                                (iowait * 100) / total,
2792                                (irq * 100) / total,
2793                                (softIrq * 100) / total);
2794                    }
2795                }
2796            }
2797
2798            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2799            synchronized(bstats) {
2800                synchronized(mPidsSelfLocked) {
2801                    if (haveNewCpuStats) {
2802                        if (bstats.startAddingCpuLocked()) {
2803                            int totalUTime = 0;
2804                            int totalSTime = 0;
2805                            final int N = mProcessCpuTracker.countStats();
2806                            for (int i=0; i<N; i++) {
2807                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2808                                if (!st.working) {
2809                                    continue;
2810                                }
2811                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2812                                totalUTime += st.rel_utime;
2813                                totalSTime += st.rel_stime;
2814                                if (pr != null) {
2815                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2816                                    if (ps == null || !ps.isActive()) {
2817                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2818                                                pr.info.uid, pr.processName);
2819                                    }
2820                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2821                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2822                                } else {
2823                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2824                                    if (ps == null || !ps.isActive()) {
2825                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2826                                                bstats.mapUid(st.uid), st.name);
2827                                    }
2828                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2829                                }
2830                            }
2831                            final int userTime = mProcessCpuTracker.getLastUserTime();
2832                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2833                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2834                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2835                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2836                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2837                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2838                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2839                        }
2840                    }
2841                }
2842
2843                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2844                    mLastWriteTime = now;
2845                    mBatteryStatsService.scheduleWriteToDisk();
2846                }
2847            }
2848        }
2849    }
2850
2851    @Override
2852    public void batteryNeedsCpuUpdate() {
2853        updateCpuStatsNow();
2854    }
2855
2856    @Override
2857    public void batteryPowerChanged(boolean onBattery) {
2858        // When plugging in, update the CPU stats first before changing
2859        // the plug state.
2860        updateCpuStatsNow();
2861        synchronized (this) {
2862            synchronized(mPidsSelfLocked) {
2863                mOnBattery = DEBUG_POWER ? true : onBattery;
2864            }
2865        }
2866    }
2867
2868    @Override
2869    public void batterySendBroadcast(Intent intent) {
2870        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2871                AppOpsManager.OP_NONE, null, false, false,
2872                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2873    }
2874
2875    /**
2876     * Initialize the application bind args. These are passed to each
2877     * process when the bindApplication() IPC is sent to the process. They're
2878     * lazily setup to make sure the services are running when they're asked for.
2879     */
2880    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2881        if (mAppBindArgs == null) {
2882            mAppBindArgs = new HashMap<>();
2883
2884            // Isolated processes won't get this optimization, so that we don't
2885            // violate the rules about which services they have access to.
2886            if (!isolated) {
2887                // Setup the application init args
2888                mAppBindArgs.put("package", ServiceManager.getService("package"));
2889                mAppBindArgs.put("window", ServiceManager.getService("window"));
2890                mAppBindArgs.put(Context.ALARM_SERVICE,
2891                        ServiceManager.getService(Context.ALARM_SERVICE));
2892            }
2893        }
2894        return mAppBindArgs;
2895    }
2896
2897    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2898        if (r == null || mFocusedActivity == r) {
2899            return false;
2900        }
2901
2902        if (!r.isFocusable()) {
2903            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2904            return false;
2905        }
2906
2907        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2908
2909        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2910        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2911                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2912        mDoingSetFocusedActivity = true;
2913
2914        final ActivityRecord last = mFocusedActivity;
2915        mFocusedActivity = r;
2916        if (r.task.isApplicationTask()) {
2917            if (mCurAppTimeTracker != r.appTimeTracker) {
2918                // We are switching app tracking.  Complete the current one.
2919                if (mCurAppTimeTracker != null) {
2920                    mCurAppTimeTracker.stop();
2921                    mHandler.obtainMessage(
2922                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2923                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2924                    mCurAppTimeTracker = null;
2925                }
2926                if (r.appTimeTracker != null) {
2927                    mCurAppTimeTracker = r.appTimeTracker;
2928                    startTimeTrackingFocusedActivityLocked();
2929                }
2930            } else {
2931                startTimeTrackingFocusedActivityLocked();
2932            }
2933        } else {
2934            r.appTimeTracker = null;
2935        }
2936        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2937        // TODO: Probably not, because we don't want to resume voice on switching
2938        // back to this activity
2939        if (r.task.voiceInteractor != null) {
2940            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2941        } else {
2942            finishRunningVoiceLocked();
2943            IVoiceInteractionSession session;
2944            if (last != null && ((session = last.task.voiceSession) != null
2945                    || (session = last.voiceSession) != null)) {
2946                // We had been in a voice interaction session, but now focused has
2947                // move to something different.  Just finish the session, we can't
2948                // return to it and retain the proper state and synchronization with
2949                // the voice interaction service.
2950                finishVoiceTask(session);
2951            }
2952        }
2953        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2954            mWindowManager.setFocusedApp(r.appToken, true);
2955        }
2956        applyUpdateLockStateLocked(r);
2957        applyUpdateVrModeLocked(r);
2958        if (mFocusedActivity.userId != mLastFocusedUserId) {
2959            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2960            mHandler.obtainMessage(
2961                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2962            mLastFocusedUserId = mFocusedActivity.userId;
2963        }
2964
2965        // Log a warning if the focused app is changed during the process. This could
2966        // indicate a problem of the focus setting logic!
2967        if (mFocusedActivity != r) Slog.w(TAG,
2968                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2969        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2970
2971        EventLogTags.writeAmFocusedActivity(
2972                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2973                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2974                reason);
2975        return true;
2976    }
2977
2978    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2979        if (mFocusedActivity != goingAway) {
2980            return;
2981        }
2982
2983        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2984        if (focusedStack != null) {
2985            final ActivityRecord top = focusedStack.topActivity();
2986            if (top != null && top.userId != mLastFocusedUserId) {
2987                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2988                mHandler.sendMessage(
2989                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2990                mLastFocusedUserId = top.userId;
2991            }
2992        }
2993
2994        // Try to move focus to another activity if possible.
2995        if (setFocusedActivityLocked(
2996                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2997            return;
2998        }
2999
3000        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3001                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3002        mFocusedActivity = null;
3003        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3004    }
3005
3006    @Override
3007    public void setFocusedStack(int stackId) {
3008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3009        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3010        final long callingId = Binder.clearCallingIdentity();
3011        try {
3012            synchronized (this) {
3013                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3014                if (stack == null) {
3015                    return;
3016                }
3017                final ActivityRecord r = stack.topRunningActivityLocked();
3018                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3019                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3020                }
3021            }
3022        } finally {
3023            Binder.restoreCallingIdentity(callingId);
3024        }
3025    }
3026
3027    @Override
3028    public void setFocusedTask(int taskId) {
3029        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3030        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3031        final long callingId = Binder.clearCallingIdentity();
3032        try {
3033            synchronized (this) {
3034                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3035                if (task == null) {
3036                    return;
3037                }
3038                final ActivityRecord r = task.topRunningActivityLocked();
3039                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3040                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3041                }
3042            }
3043        } finally {
3044            Binder.restoreCallingIdentity(callingId);
3045        }
3046    }
3047
3048    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3049    @Override
3050    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3051        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3052        synchronized (this) {
3053            if (listener != null) {
3054                mTaskStackListeners.register(listener);
3055            }
3056        }
3057    }
3058
3059    @Override
3060    public void notifyActivityDrawn(IBinder token) {
3061        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3062        synchronized (this) {
3063            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3064            if (r != null) {
3065                r.task.stack.notifyActivityDrawnLocked(r);
3066            }
3067        }
3068    }
3069
3070    final void applyUpdateLockStateLocked(ActivityRecord r) {
3071        // Modifications to the UpdateLock state are done on our handler, outside
3072        // the activity manager's locks.  The new state is determined based on the
3073        // state *now* of the relevant activity record.  The object is passed to
3074        // the handler solely for logging detail, not to be consulted/modified.
3075        final boolean nextState = r != null && r.immersive;
3076        mHandler.sendMessage(
3077                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3078    }
3079
3080    final void applyUpdateVrModeLocked(ActivityRecord r) {
3081        mHandler.sendMessage(
3082                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3083    }
3084
3085    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3086        mHandler.sendMessage(
3087                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3088    }
3089
3090    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3091        Message msg = Message.obtain();
3092        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3093        msg.obj = r.task.askedCompatMode ? null : r;
3094        mUiHandler.sendMessage(msg);
3095    }
3096
3097    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3098            String what, Object obj, ProcessRecord srcApp) {
3099        app.lastActivityTime = now;
3100
3101        if (app.activities.size() > 0) {
3102            // Don't want to touch dependent processes that are hosting activities.
3103            return index;
3104        }
3105
3106        int lrui = mLruProcesses.lastIndexOf(app);
3107        if (lrui < 0) {
3108            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3109                    + what + " " + obj + " from " + srcApp);
3110            return index;
3111        }
3112
3113        if (lrui >= index) {
3114            // Don't want to cause this to move dependent processes *back* in the
3115            // list as if they were less frequently used.
3116            return index;
3117        }
3118
3119        if (lrui >= mLruProcessActivityStart) {
3120            // Don't want to touch dependent processes that are hosting activities.
3121            return index;
3122        }
3123
3124        mLruProcesses.remove(lrui);
3125        if (index > 0) {
3126            index--;
3127        }
3128        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3129                + " in LRU list: " + app);
3130        mLruProcesses.add(index, app);
3131        return index;
3132    }
3133
3134    static void killProcessGroup(int uid, int pid) {
3135        if (sKillHandler != null) {
3136            sKillHandler.sendMessage(
3137                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3138        } else {
3139            Slog.w(TAG, "Asked to kill process group before system bringup!");
3140            Process.killProcessGroup(uid, pid);
3141        }
3142    }
3143
3144    final void removeLruProcessLocked(ProcessRecord app) {
3145        int lrui = mLruProcesses.lastIndexOf(app);
3146        if (lrui >= 0) {
3147            if (!app.killed) {
3148                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3149                Process.killProcessQuiet(app.pid);
3150                killProcessGroup(app.uid, app.pid);
3151            }
3152            if (lrui <= mLruProcessActivityStart) {
3153                mLruProcessActivityStart--;
3154            }
3155            if (lrui <= mLruProcessServiceStart) {
3156                mLruProcessServiceStart--;
3157            }
3158            mLruProcesses.remove(lrui);
3159        }
3160    }
3161
3162    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3163            ProcessRecord client) {
3164        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3165                || app.treatLikeActivity;
3166        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3167        if (!activityChange && hasActivity) {
3168            // The process has activities, so we are only allowing activity-based adjustments
3169            // to move it.  It should be kept in the front of the list with other
3170            // processes that have activities, and we don't want those to change their
3171            // order except due to activity operations.
3172            return;
3173        }
3174
3175        mLruSeq++;
3176        final long now = SystemClock.uptimeMillis();
3177        app.lastActivityTime = now;
3178
3179        // First a quick reject: if the app is already at the position we will
3180        // put it, then there is nothing to do.
3181        if (hasActivity) {
3182            final int N = mLruProcesses.size();
3183            if (N > 0 && mLruProcesses.get(N-1) == app) {
3184                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3185                return;
3186            }
3187        } else {
3188            if (mLruProcessServiceStart > 0
3189                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3190                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3191                return;
3192            }
3193        }
3194
3195        int lrui = mLruProcesses.lastIndexOf(app);
3196
3197        if (app.persistent && lrui >= 0) {
3198            // We don't care about the position of persistent processes, as long as
3199            // they are in the list.
3200            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3201            return;
3202        }
3203
3204        /* In progress: compute new position first, so we can avoid doing work
3205           if the process is not actually going to move.  Not yet working.
3206        int addIndex;
3207        int nextIndex;
3208        boolean inActivity = false, inService = false;
3209        if (hasActivity) {
3210            // Process has activities, put it at the very tipsy-top.
3211            addIndex = mLruProcesses.size();
3212            nextIndex = mLruProcessServiceStart;
3213            inActivity = true;
3214        } else if (hasService) {
3215            // Process has services, put it at the top of the service list.
3216            addIndex = mLruProcessActivityStart;
3217            nextIndex = mLruProcessServiceStart;
3218            inActivity = true;
3219            inService = true;
3220        } else  {
3221            // Process not otherwise of interest, it goes to the top of the non-service area.
3222            addIndex = mLruProcessServiceStart;
3223            if (client != null) {
3224                int clientIndex = mLruProcesses.lastIndexOf(client);
3225                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3226                        + app);
3227                if (clientIndex >= 0 && addIndex > clientIndex) {
3228                    addIndex = clientIndex;
3229                }
3230            }
3231            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3232        }
3233
3234        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3235                + mLruProcessActivityStart + "): " + app);
3236        */
3237
3238        if (lrui >= 0) {
3239            if (lrui < mLruProcessActivityStart) {
3240                mLruProcessActivityStart--;
3241            }
3242            if (lrui < mLruProcessServiceStart) {
3243                mLruProcessServiceStart--;
3244            }
3245            /*
3246            if (addIndex > lrui) {
3247                addIndex--;
3248            }
3249            if (nextIndex > lrui) {
3250                nextIndex--;
3251            }
3252            */
3253            mLruProcesses.remove(lrui);
3254        }
3255
3256        /*
3257        mLruProcesses.add(addIndex, app);
3258        if (inActivity) {
3259            mLruProcessActivityStart++;
3260        }
3261        if (inService) {
3262            mLruProcessActivityStart++;
3263        }
3264        */
3265
3266        int nextIndex;
3267        if (hasActivity) {
3268            final int N = mLruProcesses.size();
3269            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3270                // Process doesn't have activities, but has clients with
3271                // activities...  move it up, but one below the top (the top
3272                // should always have a real activity).
3273                if (DEBUG_LRU) Slog.d(TAG_LRU,
3274                        "Adding to second-top of LRU activity list: " + app);
3275                mLruProcesses.add(N - 1, app);
3276                // To keep it from spamming the LRU list (by making a bunch of clients),
3277                // we will push down any other entries owned by the app.
3278                final int uid = app.info.uid;
3279                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3280                    ProcessRecord subProc = mLruProcesses.get(i);
3281                    if (subProc.info.uid == uid) {
3282                        // We want to push this one down the list.  If the process after
3283                        // it is for the same uid, however, don't do so, because we don't
3284                        // want them internally to be re-ordered.
3285                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3286                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3287                                    "Pushing uid " + uid + " swapping at " + i + ": "
3288                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3289                            ProcessRecord tmp = mLruProcesses.get(i);
3290                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3291                            mLruProcesses.set(i - 1, tmp);
3292                            i--;
3293                        }
3294                    } else {
3295                        // A gap, we can stop here.
3296                        break;
3297                    }
3298                }
3299            } else {
3300                // Process has activities, put it at the very tipsy-top.
3301                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3302                mLruProcesses.add(app);
3303            }
3304            nextIndex = mLruProcessServiceStart;
3305        } else if (hasService) {
3306            // Process has services, put it at the top of the service list.
3307            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3308            mLruProcesses.add(mLruProcessActivityStart, app);
3309            nextIndex = mLruProcessServiceStart;
3310            mLruProcessActivityStart++;
3311        } else  {
3312            // Process not otherwise of interest, it goes to the top of the non-service area.
3313            int index = mLruProcessServiceStart;
3314            if (client != null) {
3315                // If there is a client, don't allow the process to be moved up higher
3316                // in the list than that client.
3317                int clientIndex = mLruProcesses.lastIndexOf(client);
3318                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3319                        + " when updating " + app);
3320                if (clientIndex <= lrui) {
3321                    // Don't allow the client index restriction to push it down farther in the
3322                    // list than it already is.
3323                    clientIndex = lrui;
3324                }
3325                if (clientIndex >= 0 && index > clientIndex) {
3326                    index = clientIndex;
3327                }
3328            }
3329            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3330            mLruProcesses.add(index, app);
3331            nextIndex = index-1;
3332            mLruProcessActivityStart++;
3333            mLruProcessServiceStart++;
3334        }
3335
3336        // If the app is currently using a content provider or service,
3337        // bump those processes as well.
3338        for (int j=app.connections.size()-1; j>=0; j--) {
3339            ConnectionRecord cr = app.connections.valueAt(j);
3340            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3341                    && cr.binding.service.app != null
3342                    && cr.binding.service.app.lruSeq != mLruSeq
3343                    && !cr.binding.service.app.persistent) {
3344                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3345                        "service connection", cr, app);
3346            }
3347        }
3348        for (int j=app.conProviders.size()-1; j>=0; j--) {
3349            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3350            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3351                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3352                        "provider reference", cpr, app);
3353            }
3354        }
3355    }
3356
3357    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3358        if (uid == Process.SYSTEM_UID) {
3359            // The system gets to run in any process.  If there are multiple
3360            // processes with the same uid, just pick the first (this
3361            // should never happen).
3362            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3363            if (procs == null) return null;
3364            final int procCount = procs.size();
3365            for (int i = 0; i < procCount; i++) {
3366                final int procUid = procs.keyAt(i);
3367                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3368                    // Don't use an app process or different user process for system component.
3369                    continue;
3370                }
3371                return procs.valueAt(i);
3372            }
3373        }
3374        ProcessRecord proc = mProcessNames.get(processName, uid);
3375        if (false && proc != null && !keepIfLarge
3376                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3377                && proc.lastCachedPss >= 4000) {
3378            // Turn this condition on to cause killing to happen regularly, for testing.
3379            if (proc.baseProcessTracker != null) {
3380                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3381            }
3382            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3383        } else if (proc != null && !keepIfLarge
3384                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3385                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3386            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3387            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3388                if (proc.baseProcessTracker != null) {
3389                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3390                }
3391                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3392            }
3393        }
3394        return proc;
3395    }
3396
3397    void notifyPackageUse(String packageName, int reason) {
3398        IPackageManager pm = AppGlobals.getPackageManager();
3399        try {
3400            pm.notifyPackageUse(packageName, reason);
3401        } catch (RemoteException e) {
3402        }
3403    }
3404
3405    boolean isNextTransitionForward() {
3406        int transit = mWindowManager.getPendingAppTransition();
3407        return transit == TRANSIT_ACTIVITY_OPEN
3408                || transit == TRANSIT_TASK_OPEN
3409                || transit == TRANSIT_TASK_TO_FRONT;
3410    }
3411
3412    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3413            String processName, String abiOverride, int uid, Runnable crashHandler) {
3414        synchronized(this) {
3415            ApplicationInfo info = new ApplicationInfo();
3416            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3417            // For isolated processes, the former contains the parent's uid and the latter the
3418            // actual uid of the isolated process.
3419            // In the special case introduced by this method (which is, starting an isolated
3420            // process directly from the SystemServer without an actual parent app process) the
3421            // closest thing to a parent's uid is SYSTEM_UID.
3422            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3423            // the |isolated| logic in the ProcessRecord constructor.
3424            info.uid = Process.SYSTEM_UID;
3425            info.processName = processName;
3426            info.className = entryPoint;
3427            info.packageName = "android";
3428            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3429                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3430                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3431                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3432                    crashHandler);
3433            return proc != null ? proc.pid : 0;
3434        }
3435    }
3436
3437    final ProcessRecord startProcessLocked(String processName,
3438            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3439            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3440            boolean isolated, boolean keepIfLarge) {
3441        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3442                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3443                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3444                null /* crashHandler */);
3445    }
3446
3447    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3448            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3449            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3450            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3451        long startTime = SystemClock.elapsedRealtime();
3452        ProcessRecord app;
3453        if (!isolated) {
3454            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3455            checkTime(startTime, "startProcess: after getProcessRecord");
3456
3457            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3458                // If we are in the background, then check to see if this process
3459                // is bad.  If so, we will just silently fail.
3460                if (mAppErrors.isBadProcessLocked(info)) {
3461                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3462                            + "/" + info.processName);
3463                    return null;
3464                }
3465            } else {
3466                // When the user is explicitly starting a process, then clear its
3467                // crash count so that we won't make it bad until they see at
3468                // least one crash dialog again, and make the process good again
3469                // if it had been bad.
3470                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3471                        + "/" + info.processName);
3472                mAppErrors.resetProcessCrashTimeLocked(info);
3473                if (mAppErrors.isBadProcessLocked(info)) {
3474                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3475                            UserHandle.getUserId(info.uid), info.uid,
3476                            info.processName);
3477                    mAppErrors.clearBadProcessLocked(info);
3478                    if (app != null) {
3479                        app.bad = false;
3480                    }
3481                }
3482            }
3483        } else {
3484            // If this is an isolated process, it can't re-use an existing process.
3485            app = null;
3486        }
3487
3488        // app launch boost for big.little configurations
3489        // use cpusets to migrate freshly launched tasks to big cores
3490        synchronized(ActivityManagerService.this) {
3491            nativeMigrateToBoost();
3492            mIsBoosted = true;
3493            mBoostStartTime = SystemClock.uptimeMillis();
3494            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3495            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3496        }
3497
3498        // We don't have to do anything more if:
3499        // (1) There is an existing application record; and
3500        // (2) The caller doesn't think it is dead, OR there is no thread
3501        //     object attached to it so we know it couldn't have crashed; and
3502        // (3) There is a pid assigned to it, so it is either starting or
3503        //     already running.
3504        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3505                + " app=" + app + " knownToBeDead=" + knownToBeDead
3506                + " thread=" + (app != null ? app.thread : null)
3507                + " pid=" + (app != null ? app.pid : -1));
3508        if (app != null && app.pid > 0) {
3509            if (!knownToBeDead || app.thread == null) {
3510                // We already have the app running, or are waiting for it to
3511                // come up (we have a pid but not yet its thread), so keep it.
3512                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3513                // If this is a new package in the process, add the package to the list
3514                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3515                checkTime(startTime, "startProcess: done, added package to proc");
3516                return app;
3517            }
3518
3519            // An application record is attached to a previous process,
3520            // clean it up now.
3521            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3522            checkTime(startTime, "startProcess: bad proc running, killing");
3523            killProcessGroup(app.uid, app.pid);
3524            handleAppDiedLocked(app, true, true);
3525            checkTime(startTime, "startProcess: done killing old proc");
3526        }
3527
3528        String hostingNameStr = hostingName != null
3529                ? hostingName.flattenToShortString() : null;
3530
3531        if (app == null) {
3532            checkTime(startTime, "startProcess: creating new process record");
3533            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3534            if (app == null) {
3535                Slog.w(TAG, "Failed making new process record for "
3536                        + processName + "/" + info.uid + " isolated=" + isolated);
3537                return null;
3538            }
3539            app.crashHandler = crashHandler;
3540            checkTime(startTime, "startProcess: done creating new process record");
3541        } else {
3542            // If this is a new package in the process, add the package to the list
3543            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3544            checkTime(startTime, "startProcess: added package to existing proc");
3545        }
3546
3547        // If the system is not ready yet, then hold off on starting this
3548        // process until it is.
3549        if (!mProcessesReady
3550                && !isAllowedWhileBooting(info)
3551                && !allowWhileBooting) {
3552            if (!mProcessesOnHold.contains(app)) {
3553                mProcessesOnHold.add(app);
3554            }
3555            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3556                    "System not ready, putting on hold: " + app);
3557            checkTime(startTime, "startProcess: returning with proc on hold");
3558            return app;
3559        }
3560
3561        checkTime(startTime, "startProcess: stepping in to startProcess");
3562        startProcessLocked(
3563                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3564        checkTime(startTime, "startProcess: done starting proc!");
3565        return (app.pid != 0) ? app : null;
3566    }
3567
3568    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3569        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3570    }
3571
3572    private final void startProcessLocked(ProcessRecord app,
3573            String hostingType, String hostingNameStr) {
3574        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3575                null /* entryPoint */, null /* entryPointArgs */);
3576    }
3577
3578    private final void startProcessLocked(ProcessRecord app, String hostingType,
3579            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3580        long startTime = SystemClock.elapsedRealtime();
3581        if (app.pid > 0 && app.pid != MY_PID) {
3582            checkTime(startTime, "startProcess: removing from pids map");
3583            synchronized (mPidsSelfLocked) {
3584                mPidsSelfLocked.remove(app.pid);
3585                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3586            }
3587            checkTime(startTime, "startProcess: done removing from pids map");
3588            app.setPid(0);
3589        }
3590
3591        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3592                "startProcessLocked removing on hold: " + app);
3593        mProcessesOnHold.remove(app);
3594
3595        checkTime(startTime, "startProcess: starting to update cpu stats");
3596        updateCpuStats();
3597        checkTime(startTime, "startProcess: done updating cpu stats");
3598
3599        try {
3600            try {
3601                final int userId = UserHandle.getUserId(app.uid);
3602                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3603            } catch (RemoteException e) {
3604                throw e.rethrowAsRuntimeException();
3605            }
3606
3607            int uid = app.uid;
3608            int[] gids = null;
3609            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3610            if (!app.isolated) {
3611                int[] permGids = null;
3612                try {
3613                    checkTime(startTime, "startProcess: getting gids from package manager");
3614                    final IPackageManager pm = AppGlobals.getPackageManager();
3615                    permGids = pm.getPackageGids(app.info.packageName,
3616                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3617                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3618                            MountServiceInternal.class);
3619                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3620                            app.info.packageName);
3621                } catch (RemoteException e) {
3622                    throw e.rethrowAsRuntimeException();
3623                }
3624
3625                /*
3626                 * Add shared application and profile GIDs so applications can share some
3627                 * resources like shared libraries and access user-wide resources
3628                 */
3629                if (ArrayUtils.isEmpty(permGids)) {
3630                    gids = new int[2];
3631                } else {
3632                    gids = new int[permGids.length + 2];
3633                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3634                }
3635                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3636                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3637            }
3638            checkTime(startTime, "startProcess: building args");
3639            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3640                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3641                        && mTopComponent != null
3642                        && app.processName.equals(mTopComponent.getPackageName())) {
3643                    uid = 0;
3644                }
3645                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3646                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3647                    uid = 0;
3648                }
3649            }
3650            int debugFlags = 0;
3651            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3652                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3653                // Also turn on CheckJNI for debuggable apps. It's quite
3654                // awkward to turn on otherwise.
3655                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3656            }
3657            // Run the app in safe mode if its manifest requests so or the
3658            // system is booted in safe mode.
3659            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3660                mSafeMode == true) {
3661                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3662            }
3663            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3664                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3665            }
3666            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3667            if ("true".equals(genDebugInfoProperty)) {
3668                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3669            }
3670            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3671                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3672            }
3673            if ("1".equals(SystemProperties.get("debug.assert"))) {
3674                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3675            }
3676            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3677                // Enable all debug flags required by the native debugger.
3678                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3679                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3680                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3681                mNativeDebuggingApp = null;
3682            }
3683
3684            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3685            if (requiredAbi == null) {
3686                requiredAbi = Build.SUPPORTED_ABIS[0];
3687            }
3688
3689            String instructionSet = null;
3690            if (app.info.primaryCpuAbi != null) {
3691                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3692            }
3693
3694            app.gids = gids;
3695            app.requiredAbi = requiredAbi;
3696            app.instructionSet = instructionSet;
3697
3698            // Start the process.  It will either succeed and return a result containing
3699            // the PID of the new process, or else throw a RuntimeException.
3700            boolean isActivityProcess = (entryPoint == null);
3701            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3702            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3703                    app.processName);
3704            checkTime(startTime, "startProcess: asking zygote to start proc");
3705            Process.ProcessStartResult startResult = Process.start(entryPoint,
3706                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3707                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3708                    app.info.dataDir, entryPointArgs);
3709            checkTime(startTime, "startProcess: returned from zygote!");
3710            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3711
3712            if (app.isolated) {
3713                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3714            }
3715            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3716            checkTime(startTime, "startProcess: done updating battery stats");
3717
3718            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3719                    UserHandle.getUserId(uid), startResult.pid, uid,
3720                    app.processName, hostingType,
3721                    hostingNameStr != null ? hostingNameStr : "");
3722
3723            try {
3724                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3725                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3726            } catch (RemoteException ex) {
3727                // Ignore
3728            }
3729
3730            if (app.persistent) {
3731                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3732            }
3733
3734            checkTime(startTime, "startProcess: building log message");
3735            StringBuilder buf = mStringBuilder;
3736            buf.setLength(0);
3737            buf.append("Start proc ");
3738            buf.append(startResult.pid);
3739            buf.append(':');
3740            buf.append(app.processName);
3741            buf.append('/');
3742            UserHandle.formatUid(buf, uid);
3743            if (!isActivityProcess) {
3744                buf.append(" [");
3745                buf.append(entryPoint);
3746                buf.append("]");
3747            }
3748            buf.append(" for ");
3749            buf.append(hostingType);
3750            if (hostingNameStr != null) {
3751                buf.append(" ");
3752                buf.append(hostingNameStr);
3753            }
3754            Slog.i(TAG, buf.toString());
3755            app.setPid(startResult.pid);
3756            app.usingWrapper = startResult.usingWrapper;
3757            app.removed = false;
3758            app.killed = false;
3759            app.killedByAm = false;
3760            checkTime(startTime, "startProcess: starting to update pids map");
3761            synchronized (mPidsSelfLocked) {
3762                this.mPidsSelfLocked.put(startResult.pid, app);
3763                if (isActivityProcess) {
3764                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3765                    msg.obj = app;
3766                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3767                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3768                }
3769            }
3770            checkTime(startTime, "startProcess: done updating pids map");
3771        } catch (RuntimeException e) {
3772            Slog.e(TAG, "Failure starting process " + app.processName, e);
3773
3774            // Something went very wrong while trying to start this process; one
3775            // common case is when the package is frozen due to an active
3776            // upgrade. To recover, clean up any active bookkeeping related to
3777            // starting this process. (We already invoked this method once when
3778            // the package was initially frozen through KILL_APPLICATION_MSG, so
3779            // it doesn't hurt to use it again.)
3780            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3781                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3782        }
3783    }
3784
3785    void updateUsageStats(ActivityRecord component, boolean resumed) {
3786        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3787                "updateUsageStats: comp=" + component + "res=" + resumed);
3788        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3789        if (resumed) {
3790            if (mUsageStatsService != null) {
3791                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3792                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3793            }
3794            synchronized (stats) {
3795                stats.noteActivityResumedLocked(component.app.uid);
3796            }
3797        } else {
3798            if (mUsageStatsService != null) {
3799                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3800                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3801            }
3802            synchronized (stats) {
3803                stats.noteActivityPausedLocked(component.app.uid);
3804            }
3805        }
3806    }
3807
3808    Intent getHomeIntent() {
3809        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3810        intent.setComponent(mTopComponent);
3811        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3812        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3813            intent.addCategory(Intent.CATEGORY_HOME);
3814        }
3815        return intent;
3816    }
3817
3818    boolean startHomeActivityLocked(int userId, String reason) {
3819        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3820                && mTopAction == null) {
3821            // We are running in factory test mode, but unable to find
3822            // the factory test app, so just sit around displaying the
3823            // error message and don't try to start anything.
3824            return false;
3825        }
3826        Intent intent = getHomeIntent();
3827        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3828        if (aInfo != null) {
3829            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3830            // Don't do this if the home app is currently being
3831            // instrumented.
3832            aInfo = new ActivityInfo(aInfo);
3833            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3834            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3835                    aInfo.applicationInfo.uid, true);
3836            if (app == null || app.instrumentationClass == null) {
3837                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3838                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3839            }
3840        } else {
3841            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3842        }
3843
3844        return true;
3845    }
3846
3847    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3848        ActivityInfo ai = null;
3849        ComponentName comp = intent.getComponent();
3850        try {
3851            if (comp != null) {
3852                // Factory test.
3853                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3854            } else {
3855                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3856                        intent,
3857                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3858                        flags, userId);
3859
3860                if (info != null) {
3861                    ai = info.activityInfo;
3862                }
3863            }
3864        } catch (RemoteException e) {
3865            // ignore
3866        }
3867
3868        return ai;
3869    }
3870
3871    /**
3872     * Starts the "new version setup screen" if appropriate.
3873     */
3874    void startSetupActivityLocked() {
3875        // Only do this once per boot.
3876        if (mCheckedForSetup) {
3877            return;
3878        }
3879
3880        // We will show this screen if the current one is a different
3881        // version than the last one shown, and we are not running in
3882        // low-level factory test mode.
3883        final ContentResolver resolver = mContext.getContentResolver();
3884        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3885                Settings.Global.getInt(resolver,
3886                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3887            mCheckedForSetup = true;
3888
3889            // See if we should be showing the platform update setup UI.
3890            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3891            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3892                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3893            if (!ris.isEmpty()) {
3894                final ResolveInfo ri = ris.get(0);
3895                String vers = ri.activityInfo.metaData != null
3896                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3897                        : null;
3898                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3899                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3900                            Intent.METADATA_SETUP_VERSION);
3901                }
3902                String lastVers = Settings.Secure.getString(
3903                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3904                if (vers != null && !vers.equals(lastVers)) {
3905                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3906                    intent.setComponent(new ComponentName(
3907                            ri.activityInfo.packageName, ri.activityInfo.name));
3908                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3909                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3910                            null, 0, 0, 0, null, false, false, null, null, null);
3911                }
3912            }
3913        }
3914    }
3915
3916    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3917        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3918    }
3919
3920    void enforceNotIsolatedCaller(String caller) {
3921        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3922            throw new SecurityException("Isolated process not allowed to call " + caller);
3923        }
3924    }
3925
3926    void enforceShellRestriction(String restriction, int userHandle) {
3927        if (Binder.getCallingUid() == Process.SHELL_UID) {
3928            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3929                throw new SecurityException("Shell does not have permission to access user "
3930                        + userHandle);
3931            }
3932        }
3933    }
3934
3935    @Override
3936    public int getFrontActivityScreenCompatMode() {
3937        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3938        synchronized (this) {
3939            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3940        }
3941    }
3942
3943    @Override
3944    public void setFrontActivityScreenCompatMode(int mode) {
3945        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3946                "setFrontActivityScreenCompatMode");
3947        synchronized (this) {
3948            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3949        }
3950    }
3951
3952    @Override
3953    public int getPackageScreenCompatMode(String packageName) {
3954        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3955        synchronized (this) {
3956            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3957        }
3958    }
3959
3960    @Override
3961    public void setPackageScreenCompatMode(String packageName, int mode) {
3962        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3963                "setPackageScreenCompatMode");
3964        synchronized (this) {
3965            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3966        }
3967    }
3968
3969    @Override
3970    public boolean getPackageAskScreenCompat(String packageName) {
3971        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3972        synchronized (this) {
3973            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3974        }
3975    }
3976
3977    @Override
3978    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3979        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3980                "setPackageAskScreenCompat");
3981        synchronized (this) {
3982            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3983        }
3984    }
3985
3986    private boolean hasUsageStatsPermission(String callingPackage) {
3987        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3988                Binder.getCallingUid(), callingPackage);
3989        if (mode == AppOpsManager.MODE_DEFAULT) {
3990            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3991                    == PackageManager.PERMISSION_GRANTED;
3992        }
3993        return mode == AppOpsManager.MODE_ALLOWED;
3994    }
3995
3996    @Override
3997    public int getPackageProcessState(String packageName, String callingPackage) {
3998        if (!hasUsageStatsPermission(callingPackage)) {
3999            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4000                    "getPackageProcessState");
4001        }
4002
4003        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4004        synchronized (this) {
4005            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4006                final ProcessRecord proc = mLruProcesses.get(i);
4007                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4008                        || procState > proc.setProcState) {
4009                    boolean found = false;
4010                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4011                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4012                            procState = proc.setProcState;
4013                            found = true;
4014                        }
4015                    }
4016                    if (proc.pkgDeps != null && !found) {
4017                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4018                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4019                                procState = proc.setProcState;
4020                                break;
4021                            }
4022                        }
4023                    }
4024                }
4025            }
4026        }
4027        return procState;
4028    }
4029
4030    @Override
4031    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4032        synchronized (this) {
4033            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4034            if (app == null) {
4035                return false;
4036            }
4037            if (app.trimMemoryLevel < level && app.thread != null &&
4038                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4039                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4040                try {
4041                    app.thread.scheduleTrimMemory(level);
4042                    app.trimMemoryLevel = level;
4043                    return true;
4044                } catch (RemoteException e) {
4045                    // Fallthrough to failure case.
4046                }
4047            }
4048        }
4049        return false;
4050    }
4051
4052    private void dispatchProcessesChanged() {
4053        int N;
4054        synchronized (this) {
4055            N = mPendingProcessChanges.size();
4056            if (mActiveProcessChanges.length < N) {
4057                mActiveProcessChanges = new ProcessChangeItem[N];
4058            }
4059            mPendingProcessChanges.toArray(mActiveProcessChanges);
4060            mPendingProcessChanges.clear();
4061            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4062                    "*** Delivering " + N + " process changes");
4063        }
4064
4065        int i = mProcessObservers.beginBroadcast();
4066        while (i > 0) {
4067            i--;
4068            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4069            if (observer != null) {
4070                try {
4071                    for (int j=0; j<N; j++) {
4072                        ProcessChangeItem item = mActiveProcessChanges[j];
4073                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4074                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4075                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4076                                    + item.uid + ": " + item.foregroundActivities);
4077                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4078                                    item.foregroundActivities);
4079                        }
4080                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4081                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4082                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4083                                    + ": " + item.processState);
4084                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4085                        }
4086                    }
4087                } catch (RemoteException e) {
4088                }
4089            }
4090        }
4091        mProcessObservers.finishBroadcast();
4092
4093        synchronized (this) {
4094            for (int j=0; j<N; j++) {
4095                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4096            }
4097        }
4098    }
4099
4100    private void dispatchProcessDied(int pid, int uid) {
4101        int i = mProcessObservers.beginBroadcast();
4102        while (i > 0) {
4103            i--;
4104            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4105            if (observer != null) {
4106                try {
4107                    observer.onProcessDied(pid, uid);
4108                } catch (RemoteException e) {
4109                }
4110            }
4111        }
4112        mProcessObservers.finishBroadcast();
4113    }
4114
4115    private void dispatchUidsChanged() {
4116        int N;
4117        synchronized (this) {
4118            N = mPendingUidChanges.size();
4119            if (mActiveUidChanges.length < N) {
4120                mActiveUidChanges = new UidRecord.ChangeItem[N];
4121            }
4122            for (int i=0; i<N; i++) {
4123                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4124                mActiveUidChanges[i] = change;
4125                if (change.uidRecord != null) {
4126                    change.uidRecord.pendingChange = null;
4127                    change.uidRecord = null;
4128                }
4129            }
4130            mPendingUidChanges.clear();
4131            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4132                    "*** Delivering " + N + " uid changes");
4133        }
4134
4135        if (mLocalPowerManager != null) {
4136            for (int j=0; j<N; j++) {
4137                UidRecord.ChangeItem item = mActiveUidChanges[j];
4138                if (item.change == UidRecord.CHANGE_GONE
4139                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4140                    mLocalPowerManager.uidGone(item.uid);
4141                } else {
4142                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4143                }
4144            }
4145        }
4146
4147        int i = mUidObservers.beginBroadcast();
4148        while (i > 0) {
4149            i--;
4150            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4151            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4152            if (observer != null) {
4153                try {
4154                    for (int j=0; j<N; j++) {
4155                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4156                        final int change = item.change;
4157                        UidRecord validateUid = null;
4158                        if (VALIDATE_UID_STATES && i == 0) {
4159                            validateUid = mValidateUids.get(item.uid);
4160                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4161                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4162                                validateUid = new UidRecord(item.uid);
4163                                mValidateUids.put(item.uid, validateUid);
4164                            }
4165                        }
4166                        if (change == UidRecord.CHANGE_IDLE
4167                                || change == UidRecord.CHANGE_GONE_IDLE) {
4168                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4169                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                                        "UID idle uid=" + item.uid);
4171                                observer.onUidIdle(item.uid);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                if (validateUid != null) {
4175                                    validateUid.idle = true;
4176                                }
4177                            }
4178                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4179                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4180                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4181                                        "UID active uid=" + item.uid);
4182                                observer.onUidActive(item.uid);
4183                            }
4184                            if (VALIDATE_UID_STATES && i == 0) {
4185                                validateUid.idle = false;
4186                            }
4187                        }
4188                        if (change == UidRecord.CHANGE_GONE
4189                                || change == UidRecord.CHANGE_GONE_IDLE) {
4190                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4191                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4192                                        "UID gone uid=" + item.uid);
4193                                observer.onUidGone(item.uid);
4194                            }
4195                            if (VALIDATE_UID_STATES && i == 0) {
4196                                if (validateUid != null) {
4197                                    mValidateUids.remove(item.uid);
4198                                }
4199                            }
4200                        } else {
4201                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4202                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4203                                        "UID CHANGED uid=" + item.uid
4204                                                + ": " + item.processState);
4205                                observer.onUidStateChanged(item.uid, item.processState);
4206                            }
4207                            if (VALIDATE_UID_STATES && i == 0) {
4208                                validateUid.curProcState = validateUid.setProcState
4209                                        = item.processState;
4210                            }
4211                        }
4212                    }
4213                } catch (RemoteException e) {
4214                }
4215            }
4216        }
4217        mUidObservers.finishBroadcast();
4218
4219        synchronized (this) {
4220            for (int j=0; j<N; j++) {
4221                mAvailUidChanges.add(mActiveUidChanges[j]);
4222            }
4223        }
4224    }
4225
4226    @Override
4227    public final int startActivity(IApplicationThread caller, String callingPackage,
4228            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4229            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4230        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4231                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4232                UserHandle.getCallingUserId());
4233    }
4234
4235    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4236        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4237        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4238                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4239                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4240
4241        // TODO: Switch to user app stacks here.
4242        String mimeType = intent.getType();
4243        final Uri data = intent.getData();
4244        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4245            mimeType = getProviderMimeType(data, userId);
4246        }
4247        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4248
4249        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4250        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4251                null, 0, 0, null, null, null, null, false, userId, container, null);
4252    }
4253
4254    @Override
4255    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4256            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4257            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4258        enforceNotIsolatedCaller("startActivity");
4259        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4260                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4261        // TODO: Switch to user app stacks here.
4262        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4263                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4264                profilerInfo, null, null, bOptions, false, userId, null, null);
4265    }
4266
4267    @Override
4268    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4269            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4270            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4271            int userId) {
4272
4273        // This is very dangerous -- it allows you to perform a start activity (including
4274        // permission grants) as any app that may launch one of your own activities.  So
4275        // we will only allow this to be done from activities that are part of the core framework,
4276        // and then only when they are running as the system.
4277        final ActivityRecord sourceRecord;
4278        final int targetUid;
4279        final String targetPackage;
4280        synchronized (this) {
4281            if (resultTo == null) {
4282                throw new SecurityException("Must be called from an activity");
4283            }
4284            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4285            if (sourceRecord == null) {
4286                throw new SecurityException("Called with bad activity token: " + resultTo);
4287            }
4288            if (!sourceRecord.info.packageName.equals("android")) {
4289                throw new SecurityException(
4290                        "Must be called from an activity that is declared in the android package");
4291            }
4292            if (sourceRecord.app == null) {
4293                throw new SecurityException("Called without a process attached to activity");
4294            }
4295            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4296                // This is still okay, as long as this activity is running under the
4297                // uid of the original calling activity.
4298                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4299                    throw new SecurityException(
4300                            "Calling activity in uid " + sourceRecord.app.uid
4301                                    + " must be system uid or original calling uid "
4302                                    + sourceRecord.launchedFromUid);
4303                }
4304            }
4305            if (ignoreTargetSecurity) {
4306                if (intent.getComponent() == null) {
4307                    throw new SecurityException(
4308                            "Component must be specified with ignoreTargetSecurity");
4309                }
4310                if (intent.getSelector() != null) {
4311                    throw new SecurityException(
4312                            "Selector not allowed with ignoreTargetSecurity");
4313                }
4314            }
4315            targetUid = sourceRecord.launchedFromUid;
4316            targetPackage = sourceRecord.launchedFromPackage;
4317        }
4318
4319        if (userId == UserHandle.USER_NULL) {
4320            userId = UserHandle.getUserId(sourceRecord.app.uid);
4321        }
4322
4323        // TODO: Switch to user app stacks here.
4324        try {
4325            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4326                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4327                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4328            return ret;
4329        } catch (SecurityException e) {
4330            // XXX need to figure out how to propagate to original app.
4331            // A SecurityException here is generally actually a fault of the original
4332            // calling activity (such as a fairly granting permissions), so propagate it
4333            // back to them.
4334            /*
4335            StringBuilder msg = new StringBuilder();
4336            msg.append("While launching");
4337            msg.append(intent.toString());
4338            msg.append(": ");
4339            msg.append(e.getMessage());
4340            */
4341            throw e;
4342        }
4343    }
4344
4345    @Override
4346    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4347            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4348            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4349        enforceNotIsolatedCaller("startActivityAndWait");
4350        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4351                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4352        WaitResult res = new WaitResult();
4353        // TODO: Switch to user app stacks here.
4354        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4355                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4356                bOptions, false, userId, null, null);
4357        return res;
4358    }
4359
4360    @Override
4361    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4362            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4363            int startFlags, Configuration config, Bundle bOptions, int userId) {
4364        enforceNotIsolatedCaller("startActivityWithConfig");
4365        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4366                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4367        // TODO: Switch to user app stacks here.
4368        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4369                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4370                null, null, config, bOptions, false, userId, null, null);
4371        return ret;
4372    }
4373
4374    @Override
4375    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4376            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4377            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4378            throws TransactionTooLargeException {
4379        enforceNotIsolatedCaller("startActivityIntentSender");
4380        // Refuse possible leaked file descriptors
4381        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4382            throw new IllegalArgumentException("File descriptors passed in Intent");
4383        }
4384
4385        IIntentSender sender = intent.getTarget();
4386        if (!(sender instanceof PendingIntentRecord)) {
4387            throw new IllegalArgumentException("Bad PendingIntent object");
4388        }
4389
4390        PendingIntentRecord pir = (PendingIntentRecord)sender;
4391
4392        synchronized (this) {
4393            // If this is coming from the currently resumed activity, it is
4394            // effectively saying that app switches are allowed at this point.
4395            final ActivityStack stack = getFocusedStack();
4396            if (stack.mResumedActivity != null &&
4397                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4398                mAppSwitchesAllowedTime = 0;
4399            }
4400        }
4401        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4402                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4403        return ret;
4404    }
4405
4406    @Override
4407    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4408            Intent intent, String resolvedType, IVoiceInteractionSession session,
4409            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4410            Bundle bOptions, int userId) {
4411        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4412                != PackageManager.PERMISSION_GRANTED) {
4413            String msg = "Permission Denial: startVoiceActivity() from pid="
4414                    + Binder.getCallingPid()
4415                    + ", uid=" + Binder.getCallingUid()
4416                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4417            Slog.w(TAG, msg);
4418            throw new SecurityException(msg);
4419        }
4420        if (session == null || interactor == null) {
4421            throw new NullPointerException("null session or interactor");
4422        }
4423        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4424                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4425        // TODO: Switch to user app stacks here.
4426        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4427                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4428                null, bOptions, false, userId, null, null);
4429    }
4430
4431    @Override
4432    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4433            throws RemoteException {
4434        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4435        synchronized (this) {
4436            ActivityRecord activity = getFocusedStack().topActivity();
4437            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4438                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4439            }
4440            if (mRunningVoice != null || activity.task.voiceSession != null
4441                    || activity.voiceSession != null) {
4442                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4443                return;
4444            }
4445            if (activity.pendingVoiceInteractionStart) {
4446                Slog.w(TAG, "Pending start of voice interaction already.");
4447                return;
4448            }
4449            activity.pendingVoiceInteractionStart = true;
4450        }
4451        LocalServices.getService(VoiceInteractionManagerInternal.class)
4452                .startLocalVoiceInteraction(callingActivity, options);
4453    }
4454
4455    @Override
4456    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4457        LocalServices.getService(VoiceInteractionManagerInternal.class)
4458                .stopLocalVoiceInteraction(callingActivity);
4459    }
4460
4461    @Override
4462    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4463        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4464                .supportsLocalVoiceInteraction();
4465    }
4466
4467    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4468            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4469        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4470        if (activityToCallback == null) return;
4471        activityToCallback.setVoiceSessionLocked(voiceSession);
4472
4473        // Inform the activity
4474        try {
4475            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4476                    voiceInteractor);
4477            long token = Binder.clearCallingIdentity();
4478            try {
4479                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4480            } finally {
4481                Binder.restoreCallingIdentity(token);
4482            }
4483            // TODO: VI Should we cache the activity so that it's easier to find later
4484            // rather than scan through all the stacks and activities?
4485        } catch (RemoteException re) {
4486            activityToCallback.clearVoiceSessionLocked();
4487            // TODO: VI Should this terminate the voice session?
4488        }
4489    }
4490
4491    @Override
4492    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4493        synchronized (this) {
4494            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4495                if (keepAwake) {
4496                    mVoiceWakeLock.acquire();
4497                } else {
4498                    mVoiceWakeLock.release();
4499                }
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public boolean startNextMatchingActivity(IBinder callingActivity,
4506            Intent intent, Bundle bOptions) {
4507        // Refuse possible leaked file descriptors
4508        if (intent != null && intent.hasFileDescriptors() == true) {
4509            throw new IllegalArgumentException("File descriptors passed in Intent");
4510        }
4511        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4512
4513        synchronized (this) {
4514            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4515            if (r == null) {
4516                ActivityOptions.abort(options);
4517                return false;
4518            }
4519            if (r.app == null || r.app.thread == null) {
4520                // The caller is not running...  d'oh!
4521                ActivityOptions.abort(options);
4522                return false;
4523            }
4524            intent = new Intent(intent);
4525            // The caller is not allowed to change the data.
4526            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4527            // And we are resetting to find the next component...
4528            intent.setComponent(null);
4529
4530            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4531
4532            ActivityInfo aInfo = null;
4533            try {
4534                List<ResolveInfo> resolves =
4535                    AppGlobals.getPackageManager().queryIntentActivities(
4536                            intent, r.resolvedType,
4537                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4538                            UserHandle.getCallingUserId()).getList();
4539
4540                // Look for the original activity in the list...
4541                final int N = resolves != null ? resolves.size() : 0;
4542                for (int i=0; i<N; i++) {
4543                    ResolveInfo rInfo = resolves.get(i);
4544                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4545                            && rInfo.activityInfo.name.equals(r.info.name)) {
4546                        // We found the current one...  the next matching is
4547                        // after it.
4548                        i++;
4549                        if (i<N) {
4550                            aInfo = resolves.get(i).activityInfo;
4551                        }
4552                        if (debug) {
4553                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4554                                    + "/" + r.info.name);
4555                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4556                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4557                        }
4558                        break;
4559                    }
4560                }
4561            } catch (RemoteException e) {
4562            }
4563
4564            if (aInfo == null) {
4565                // Nobody who is next!
4566                ActivityOptions.abort(options);
4567                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4568                return false;
4569            }
4570
4571            intent.setComponent(new ComponentName(
4572                    aInfo.applicationInfo.packageName, aInfo.name));
4573            intent.setFlags(intent.getFlags()&~(
4574                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4575                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4576                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4577                    Intent.FLAG_ACTIVITY_NEW_TASK));
4578
4579            // Okay now we need to start the new activity, replacing the
4580            // currently running activity.  This is a little tricky because
4581            // we want to start the new one as if the current one is finished,
4582            // but not finish the current one first so that there is no flicker.
4583            // And thus...
4584            final boolean wasFinishing = r.finishing;
4585            r.finishing = true;
4586
4587            // Propagate reply information over to the new activity.
4588            final ActivityRecord resultTo = r.resultTo;
4589            final String resultWho = r.resultWho;
4590            final int requestCode = r.requestCode;
4591            r.resultTo = null;
4592            if (resultTo != null) {
4593                resultTo.removeResultsLocked(r, resultWho, requestCode);
4594            }
4595
4596            final long origId = Binder.clearCallingIdentity();
4597            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4598                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4599                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4600                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4601                    false, false, null, null, null);
4602            Binder.restoreCallingIdentity(origId);
4603
4604            r.finishing = wasFinishing;
4605            if (res != ActivityManager.START_SUCCESS) {
4606                return false;
4607            }
4608            return true;
4609        }
4610    }
4611
4612    @Override
4613    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4614        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4615            String msg = "Permission Denial: startActivityFromRecents called without " +
4616                    START_TASKS_FROM_RECENTS;
4617            Slog.w(TAG, msg);
4618            throw new SecurityException(msg);
4619        }
4620        final long origId = Binder.clearCallingIdentity();
4621        try {
4622            synchronized (this) {
4623                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4624            }
4625        } finally {
4626            Binder.restoreCallingIdentity(origId);
4627        }
4628    }
4629
4630    final int startActivityInPackage(int uid, String callingPackage,
4631            Intent intent, String resolvedType, IBinder resultTo,
4632            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4633            IActivityContainer container, TaskRecord inTask) {
4634
4635        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4636                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4637
4638        // TODO: Switch to user app stacks here.
4639        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641                null, null, null, bOptions, false, userId, container, inTask);
4642        return ret;
4643    }
4644
4645    @Override
4646    public final int startActivities(IApplicationThread caller, String callingPackage,
4647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4648            int userId) {
4649        enforceNotIsolatedCaller("startActivities");
4650        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4651                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4652        // TODO: Switch to user app stacks here.
4653        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4654                resolvedTypes, resultTo, bOptions, userId);
4655        return ret;
4656    }
4657
4658    final int startActivitiesInPackage(int uid, String callingPackage,
4659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4660            Bundle bOptions, int userId) {
4661
4662        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4663                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4664        // TODO: Switch to user app stacks here.
4665        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4666                resultTo, bOptions, userId);
4667        return ret;
4668    }
4669
4670    @Override
4671    public void reportActivityFullyDrawn(IBinder token) {
4672        synchronized (this) {
4673            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4674            if (r == null) {
4675                return;
4676            }
4677            r.reportFullyDrawnLocked();
4678        }
4679    }
4680
4681    @Override
4682    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4683        synchronized (this) {
4684            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4685            if (r == null) {
4686                return;
4687            }
4688            TaskRecord task = r.task;
4689            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4690                // Fixed screen orientation isn't supported when activities aren't in full screen
4691                // mode.
4692                return;
4693            }
4694            final long origId = Binder.clearCallingIdentity();
4695            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4696            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4697                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4698            if (config != null) {
4699                r.frozenBeforeDestroy = true;
4700                if (!updateConfigurationLocked(config, r, false)) {
4701                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4702                }
4703            }
4704            Binder.restoreCallingIdentity(origId);
4705        }
4706    }
4707
4708    @Override
4709    public int getRequestedOrientation(IBinder token) {
4710        synchronized (this) {
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r == null) {
4713                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4714            }
4715            return mWindowManager.getAppOrientation(r.appToken);
4716        }
4717    }
4718
4719    /**
4720     * This is the internal entry point for handling Activity.finish().
4721     *
4722     * @param token The Binder token referencing the Activity we want to finish.
4723     * @param resultCode Result code, if any, from this Activity.
4724     * @param resultData Result data (Intent), if any, from this Activity.
4725     * @param finishTask Whether to finish the task associated with this Activity.
4726     *
4727     * @return Returns true if the activity successfully finished, or false if it is still running.
4728     */
4729    @Override
4730    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4731            int finishTask) {
4732        // Refuse possible leaked file descriptors
4733        if (resultData != null && resultData.hasFileDescriptors() == true) {
4734            throw new IllegalArgumentException("File descriptors passed in Intent");
4735        }
4736
4737        synchronized(this) {
4738            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4739            if (r == null) {
4740                return true;
4741            }
4742            // Keep track of the root activity of the task before we finish it
4743            TaskRecord tr = r.task;
4744            ActivityRecord rootR = tr.getRootActivity();
4745            if (rootR == null) {
4746                Slog.w(TAG, "Finishing task with all activities already finished");
4747            }
4748            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4749            // finish.
4750            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4751                    mStackSupervisor.isLastLockedTask(tr)) {
4752                Slog.i(TAG, "Not finishing task in lock task mode");
4753                mStackSupervisor.showLockTaskToast();
4754                return false;
4755            }
4756            if (mController != null) {
4757                // Find the first activity that is not finishing.
4758                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4759                if (next != null) {
4760                    // ask watcher if this is allowed
4761                    boolean resumeOK = true;
4762                    try {
4763                        resumeOK = mController.activityResuming(next.packageName);
4764                    } catch (RemoteException e) {
4765                        mController = null;
4766                        Watchdog.getInstance().setActivityController(null);
4767                    }
4768
4769                    if (!resumeOK) {
4770                        Slog.i(TAG, "Not finishing activity because controller resumed");
4771                        return false;
4772                    }
4773                }
4774            }
4775            final long origId = Binder.clearCallingIdentity();
4776            try {
4777                boolean res;
4778                final boolean finishWithRootActivity =
4779                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4780                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4781                        || (finishWithRootActivity && r == rootR)) {
4782                    // If requested, remove the task that is associated to this activity only if it
4783                    // was the root activity in the task. The result code and data is ignored
4784                    // because we don't support returning them across task boundaries. Also, to
4785                    // keep backwards compatibility we remove the task from recents when finishing
4786                    // task with root activity.
4787                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4788                    if (!res) {
4789                        Slog.i(TAG, "Removing task failed to finish activity");
4790                    }
4791                } else {
4792                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4793                            resultData, "app-request", true);
4794                    if (!res) {
4795                        Slog.i(TAG, "Failed to finish by app-request");
4796                    }
4797                }
4798                return res;
4799            } finally {
4800                Binder.restoreCallingIdentity(origId);
4801            }
4802        }
4803    }
4804
4805    @Override
4806    public final void finishHeavyWeightApp() {
4807        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4808                != PackageManager.PERMISSION_GRANTED) {
4809            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4810                    + Binder.getCallingPid()
4811                    + ", uid=" + Binder.getCallingUid()
4812                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4813            Slog.w(TAG, msg);
4814            throw new SecurityException(msg);
4815        }
4816
4817        synchronized(this) {
4818            if (mHeavyWeightProcess == null) {
4819                return;
4820            }
4821
4822            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4823            for (int i = 0; i < activities.size(); i++) {
4824                ActivityRecord r = activities.get(i);
4825                if (!r.finishing && r.isInStackLocked()) {
4826                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4827                            null, "finish-heavy", true);
4828                }
4829            }
4830
4831            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4832                    mHeavyWeightProcess.userId, 0));
4833            mHeavyWeightProcess = null;
4834        }
4835    }
4836
4837    @Override
4838    public void crashApplication(int uid, int initialPid, String packageName,
4839            String message) {
4840        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4841                != PackageManager.PERMISSION_GRANTED) {
4842            String msg = "Permission Denial: crashApplication() from pid="
4843                    + Binder.getCallingPid()
4844                    + ", uid=" + Binder.getCallingUid()
4845                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4846            Slog.w(TAG, msg);
4847            throw new SecurityException(msg);
4848        }
4849
4850        synchronized(this) {
4851            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4852        }
4853    }
4854
4855    @Override
4856    public final void finishSubActivity(IBinder token, String resultWho,
4857            int requestCode) {
4858        synchronized(this) {
4859            final long origId = Binder.clearCallingIdentity();
4860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4861            if (r != null) {
4862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4863            }
4864            Binder.restoreCallingIdentity(origId);
4865        }
4866    }
4867
4868    @Override
4869    public boolean finishActivityAffinity(IBinder token) {
4870        synchronized(this) {
4871            final long origId = Binder.clearCallingIdentity();
4872            try {
4873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4874                if (r == null) {
4875                    return false;
4876                }
4877
4878                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4879                // can finish.
4880                final TaskRecord task = r.task;
4881                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4882                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4883                    mStackSupervisor.showLockTaskToast();
4884                    return false;
4885                }
4886                return task.stack.finishActivityAffinityLocked(r);
4887            } finally {
4888                Binder.restoreCallingIdentity(origId);
4889            }
4890        }
4891    }
4892
4893    @Override
4894    public void finishVoiceTask(IVoiceInteractionSession session) {
4895        synchronized (this) {
4896            final long origId = Binder.clearCallingIdentity();
4897            try {
4898                // TODO: VI Consider treating local voice interactions and voice tasks
4899                // differently here
4900                mStackSupervisor.finishVoiceTask(session);
4901            } finally {
4902                Binder.restoreCallingIdentity(origId);
4903            }
4904        }
4905
4906    }
4907
4908    @Override
4909    public boolean releaseActivityInstance(IBinder token) {
4910        synchronized(this) {
4911            final long origId = Binder.clearCallingIdentity();
4912            try {
4913                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4914                if (r == null) {
4915                    return false;
4916                }
4917                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4918            } finally {
4919                Binder.restoreCallingIdentity(origId);
4920            }
4921        }
4922    }
4923
4924    @Override
4925    public void releaseSomeActivities(IApplicationThread appInt) {
4926        synchronized(this) {
4927            final long origId = Binder.clearCallingIdentity();
4928            try {
4929                ProcessRecord app = getRecordForAppLocked(appInt);
4930                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4931            } finally {
4932                Binder.restoreCallingIdentity(origId);
4933            }
4934        }
4935    }
4936
4937    @Override
4938    public boolean willActivityBeVisible(IBinder token) {
4939        synchronized(this) {
4940            ActivityStack stack = ActivityRecord.getStackLocked(token);
4941            if (stack != null) {
4942                return stack.willActivityBeVisibleLocked(token);
4943            }
4944            return false;
4945        }
4946    }
4947
4948    @Override
4949    public void overridePendingTransition(IBinder token, String packageName,
4950            int enterAnim, int exitAnim) {
4951        synchronized(this) {
4952            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4953            if (self == null) {
4954                return;
4955            }
4956
4957            final long origId = Binder.clearCallingIdentity();
4958
4959            if (self.state == ActivityState.RESUMED
4960                    || self.state == ActivityState.PAUSING) {
4961                mWindowManager.overridePendingAppTransition(packageName,
4962                        enterAnim, exitAnim, null);
4963            }
4964
4965            Binder.restoreCallingIdentity(origId);
4966        }
4967    }
4968
4969    /**
4970     * Main function for removing an existing process from the activity manager
4971     * as a result of that process going away.  Clears out all connections
4972     * to the process.
4973     */
4974    private final void handleAppDiedLocked(ProcessRecord app,
4975            boolean restarting, boolean allowRestart) {
4976        int pid = app.pid;
4977        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4978        if (!kept && !restarting) {
4979            removeLruProcessLocked(app);
4980            if (pid > 0) {
4981                ProcessList.remove(pid);
4982            }
4983        }
4984
4985        if (mProfileProc == app) {
4986            clearProfilerLocked();
4987        }
4988
4989        // Remove this application's activities from active lists.
4990        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4991
4992        app.activities.clear();
4993
4994        if (app.instrumentationClass != null) {
4995            Slog.w(TAG, "Crash of app " + app.processName
4996                  + " running instrumentation " + app.instrumentationClass);
4997            Bundle info = new Bundle();
4998            info.putString("shortMsg", "Process crashed.");
4999            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5000        }
5001
5002        if (!restarting && hasVisibleActivities
5003                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5004            // If there was nothing to resume, and we are not already restarting this process, but
5005            // there is a visible activity that is hosted by the process...  then make sure all
5006            // visible activities are running, taking care of restarting this process.
5007            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5008        }
5009    }
5010
5011    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5012        IBinder threadBinder = thread.asBinder();
5013        // Find the application record.
5014        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5015            ProcessRecord rec = mLruProcesses.get(i);
5016            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5017                return i;
5018            }
5019        }
5020        return -1;
5021    }
5022
5023    final ProcessRecord getRecordForAppLocked(
5024            IApplicationThread thread) {
5025        if (thread == null) {
5026            return null;
5027        }
5028
5029        int appIndex = getLRURecordIndexForAppLocked(thread);
5030        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5031    }
5032
5033    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5034        // If there are no longer any background processes running,
5035        // and the app that died was not running instrumentation,
5036        // then tell everyone we are now low on memory.
5037        boolean haveBg = false;
5038        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5039            ProcessRecord rec = mLruProcesses.get(i);
5040            if (rec.thread != null
5041                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5042                haveBg = true;
5043                break;
5044            }
5045        }
5046
5047        if (!haveBg) {
5048            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5049            if (doReport) {
5050                long now = SystemClock.uptimeMillis();
5051                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5052                    doReport = false;
5053                } else {
5054                    mLastMemUsageReportTime = now;
5055                }
5056            }
5057            final ArrayList<ProcessMemInfo> memInfos
5058                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5059            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5060            long now = SystemClock.uptimeMillis();
5061            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5062                ProcessRecord rec = mLruProcesses.get(i);
5063                if (rec == dyingProc || rec.thread == null) {
5064                    continue;
5065                }
5066                if (doReport) {
5067                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5068                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5069                }
5070                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5071                    // The low memory report is overriding any current
5072                    // state for a GC request.  Make sure to do
5073                    // heavy/important/visible/foreground processes first.
5074                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5075                        rec.lastRequestedGc = 0;
5076                    } else {
5077                        rec.lastRequestedGc = rec.lastLowMemory;
5078                    }
5079                    rec.reportLowMemory = true;
5080                    rec.lastLowMemory = now;
5081                    mProcessesToGc.remove(rec);
5082                    addProcessToGcListLocked(rec);
5083                }
5084            }
5085            if (doReport) {
5086                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5087                mHandler.sendMessage(msg);
5088            }
5089            scheduleAppGcsLocked();
5090        }
5091    }
5092
5093    final void appDiedLocked(ProcessRecord app) {
5094       appDiedLocked(app, app.pid, app.thread, false);
5095    }
5096
5097    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5098            boolean fromBinderDied) {
5099        // First check if this ProcessRecord is actually active for the pid.
5100        synchronized (mPidsSelfLocked) {
5101            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5102            if (curProc != app) {
5103                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5104                return;
5105            }
5106        }
5107
5108        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5109        synchronized (stats) {
5110            stats.noteProcessDiedLocked(app.info.uid, pid);
5111        }
5112
5113        if (!app.killed) {
5114            if (!fromBinderDied) {
5115                Process.killProcessQuiet(pid);
5116            }
5117            killProcessGroup(app.uid, pid);
5118            app.killed = true;
5119        }
5120
5121        // Clean up already done if the process has been re-started.
5122        if (app.pid == pid && app.thread != null &&
5123                app.thread.asBinder() == thread.asBinder()) {
5124            boolean doLowMem = app.instrumentationClass == null;
5125            boolean doOomAdj = doLowMem;
5126            if (!app.killedByAm) {
5127                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5128                        + ") has died");
5129                mAllowLowerMemLevel = true;
5130            } else {
5131                // Note that we always want to do oom adj to update our state with the
5132                // new number of procs.
5133                mAllowLowerMemLevel = false;
5134                doLowMem = false;
5135            }
5136            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5137            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5138                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5139            handleAppDiedLocked(app, false, true);
5140
5141            if (doOomAdj) {
5142                updateOomAdjLocked();
5143            }
5144            if (doLowMem) {
5145                doLowMemReportIfNeededLocked(app);
5146            }
5147        } else if (app.pid != pid) {
5148            // A new process has already been started.
5149            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5150                    + ") has died and restarted (pid " + app.pid + ").");
5151            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5152        } else if (DEBUG_PROCESSES) {
5153            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5154                    + thread.asBinder());
5155        }
5156    }
5157
5158    /**
5159     * If a stack trace dump file is configured, dump process stack traces.
5160     * @param clearTraces causes the dump file to be erased prior to the new
5161     *    traces being written, if true; when false, the new traces will be
5162     *    appended to any existing file content.
5163     * @param firstPids of dalvik VM processes to dump stack traces for first
5164     * @param lastPids of dalvik VM processes to dump stack traces for last
5165     * @param nativeProcs optional list of native process names to dump stack crawls
5166     * @return file containing stack traces, or null if no dump file is configured
5167     */
5168    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5169            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5170        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5171        if (tracesPath == null || tracesPath.length() == 0) {
5172            return null;
5173        }
5174
5175        File tracesFile = new File(tracesPath);
5176        try {
5177            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5178            tracesFile.createNewFile();
5179            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5180        } catch (IOException e) {
5181            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5182            return null;
5183        }
5184
5185        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5186        return tracesFile;
5187    }
5188
5189    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5190            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5191        // Use a FileObserver to detect when traces finish writing.
5192        // The order of traces is considered important to maintain for legibility.
5193        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5194            @Override
5195            public synchronized void onEvent(int event, String path) { notify(); }
5196        };
5197
5198        try {
5199            observer.startWatching();
5200
5201            // First collect all of the stacks of the most important pids.
5202            if (firstPids != null) {
5203                try {
5204                    int num = firstPids.size();
5205                    for (int i = 0; i < num; i++) {
5206                        synchronized (observer) {
5207                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5208                                    + firstPids.get(i));
5209                            final long sime = SystemClock.elapsedRealtime();
5210                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5211                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5212                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5213                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5214                        }
5215                    }
5216                } catch (InterruptedException e) {
5217                    Slog.wtf(TAG, e);
5218                }
5219            }
5220
5221            // Next collect the stacks of the native pids
5222            if (nativeProcs != null) {
5223                int[] pids = Process.getPidsForCommands(nativeProcs);
5224                if (pids != null) {
5225                    for (int pid : pids) {
5226                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5227                        final long sime = SystemClock.elapsedRealtime();
5228                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5229                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5230                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5231                    }
5232                }
5233            }
5234
5235            // Lastly, measure CPU usage.
5236            if (processCpuTracker != null) {
5237                processCpuTracker.init();
5238                System.gc();
5239                processCpuTracker.update();
5240                try {
5241                    synchronized (processCpuTracker) {
5242                        processCpuTracker.wait(500); // measure over 1/2 second.
5243                    }
5244                } catch (InterruptedException e) {
5245                }
5246                processCpuTracker.update();
5247
5248                // We'll take the stack crawls of just the top apps using CPU.
5249                final int N = processCpuTracker.countWorkingStats();
5250                int numProcs = 0;
5251                for (int i=0; i<N && numProcs<5; i++) {
5252                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5253                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5254                        numProcs++;
5255                        try {
5256                            synchronized (observer) {
5257                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5258                                        + stats.pid);
5259                                final long stime = SystemClock.elapsedRealtime();
5260                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5261                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5262                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5263                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5264                            }
5265                        } catch (InterruptedException e) {
5266                            Slog.wtf(TAG, e);
5267                        }
5268                    } else if (DEBUG_ANR) {
5269                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5270                                + stats.pid);
5271                    }
5272                }
5273            }
5274        } finally {
5275            observer.stopWatching();
5276        }
5277    }
5278
5279    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5280        if (true || IS_USER_BUILD) {
5281            return;
5282        }
5283        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5284        if (tracesPath == null || tracesPath.length() == 0) {
5285            return;
5286        }
5287
5288        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5289        StrictMode.allowThreadDiskWrites();
5290        try {
5291            final File tracesFile = new File(tracesPath);
5292            final File tracesDir = tracesFile.getParentFile();
5293            final File tracesTmp = new File(tracesDir, "__tmp__");
5294            try {
5295                if (tracesFile.exists()) {
5296                    tracesTmp.delete();
5297                    tracesFile.renameTo(tracesTmp);
5298                }
5299                StringBuilder sb = new StringBuilder();
5300                Time tobj = new Time();
5301                tobj.set(System.currentTimeMillis());
5302                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5303                sb.append(": ");
5304                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5305                sb.append(" since ");
5306                sb.append(msg);
5307                FileOutputStream fos = new FileOutputStream(tracesFile);
5308                fos.write(sb.toString().getBytes());
5309                if (app == null) {
5310                    fos.write("\n*** No application process!".getBytes());
5311                }
5312                fos.close();
5313                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5314            } catch (IOException e) {
5315                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5316                return;
5317            }
5318
5319            if (app != null) {
5320                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5321                firstPids.add(app.pid);
5322                dumpStackTraces(tracesPath, firstPids, null, null, null);
5323            }
5324
5325            File lastTracesFile = null;
5326            File curTracesFile = null;
5327            for (int i=9; i>=0; i--) {
5328                String name = String.format(Locale.US, "slow%02d.txt", i);
5329                curTracesFile = new File(tracesDir, name);
5330                if (curTracesFile.exists()) {
5331                    if (lastTracesFile != null) {
5332                        curTracesFile.renameTo(lastTracesFile);
5333                    } else {
5334                        curTracesFile.delete();
5335                    }
5336                }
5337                lastTracesFile = curTracesFile;
5338            }
5339            tracesFile.renameTo(curTracesFile);
5340            if (tracesTmp.exists()) {
5341                tracesTmp.renameTo(tracesFile);
5342            }
5343        } finally {
5344            StrictMode.setThreadPolicy(oldPolicy);
5345        }
5346    }
5347
5348    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5349        if (!mLaunchWarningShown) {
5350            mLaunchWarningShown = true;
5351            mUiHandler.post(new Runnable() {
5352                @Override
5353                public void run() {
5354                    synchronized (ActivityManagerService.this) {
5355                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5356                        d.show();
5357                        mUiHandler.postDelayed(new Runnable() {
5358                            @Override
5359                            public void run() {
5360                                synchronized (ActivityManagerService.this) {
5361                                    d.dismiss();
5362                                    mLaunchWarningShown = false;
5363                                }
5364                            }
5365                        }, 4000);
5366                    }
5367                }
5368            });
5369        }
5370    }
5371
5372    @Override
5373    public boolean clearApplicationUserData(final String packageName,
5374            final IPackageDataObserver observer, int userId) {
5375        enforceNotIsolatedCaller("clearApplicationUserData");
5376        int uid = Binder.getCallingUid();
5377        int pid = Binder.getCallingPid();
5378        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5379                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5380
5381        final DevicePolicyManagerInternal dpmi = LocalServices
5382                .getService(DevicePolicyManagerInternal.class);
5383        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5384            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5385        }
5386
5387        long callingId = Binder.clearCallingIdentity();
5388        try {
5389            IPackageManager pm = AppGlobals.getPackageManager();
5390            int pkgUid = -1;
5391            synchronized(this) {
5392                try {
5393                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5394                } catch (RemoteException e) {
5395                }
5396                if (pkgUid == -1) {
5397                    Slog.w(TAG, "Invalid packageName: " + packageName);
5398                    if (observer != null) {
5399                        try {
5400                            observer.onRemoveCompleted(packageName, false);
5401                        } catch (RemoteException e) {
5402                            Slog.i(TAG, "Observer no longer exists.");
5403                        }
5404                    }
5405                    return false;
5406                }
5407                if (uid == pkgUid || checkComponentPermission(
5408                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5409                        pid, uid, -1, true)
5410                        == PackageManager.PERMISSION_GRANTED) {
5411                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5412                } else {
5413                    throw new SecurityException("PID " + pid + " does not have permission "
5414                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5415                                    + " of package " + packageName);
5416                }
5417
5418                // Remove all tasks match the cleared application package and user
5419                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5420                    final TaskRecord tr = mRecentTasks.get(i);
5421                    final String taskPackageName =
5422                            tr.getBaseIntent().getComponent().getPackageName();
5423                    if (tr.userId != userId) continue;
5424                    if (!taskPackageName.equals(packageName)) continue;
5425                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5426                }
5427            }
5428
5429            final int pkgUidF = pkgUid;
5430            final int userIdF = userId;
5431            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5432                @Override
5433                public void onRemoveCompleted(String packageName, boolean succeeded)
5434                        throws RemoteException {
5435                    synchronized (ActivityManagerService.this) {
5436                        finishForceStopPackageLocked(packageName, pkgUidF);
5437                    }
5438
5439                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5440                            Uri.fromParts("package", packageName, null));
5441                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5442                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5443                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5444                            null, null, 0, null, null, null, null, false, false, userIdF);
5445
5446                    if (observer != null) {
5447                        observer.onRemoveCompleted(packageName, succeeded);
5448                    }
5449                }
5450            };
5451
5452            try {
5453                // Clear application user data
5454                pm.clearApplicationUserData(packageName, localObserver, userId);
5455
5456                synchronized(this) {
5457                    // Remove all permissions granted from/to this package
5458                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5459                }
5460
5461                // Remove all zen rules created by this package; revoke it's zen access.
5462                INotificationManager inm = NotificationManager.getService();
5463                inm.removeAutomaticZenRules(packageName);
5464                inm.setNotificationPolicyAccessGranted(packageName, false);
5465
5466            } catch (RemoteException e) {
5467            }
5468        } finally {
5469            Binder.restoreCallingIdentity(callingId);
5470        }
5471        return true;
5472    }
5473
5474    @Override
5475    public void killBackgroundProcesses(final String packageName, int userId) {
5476        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5477                != PackageManager.PERMISSION_GRANTED &&
5478                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5479                        != PackageManager.PERMISSION_GRANTED) {
5480            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5481                    + Binder.getCallingPid()
5482                    + ", uid=" + Binder.getCallingUid()
5483                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5484            Slog.w(TAG, msg);
5485            throw new SecurityException(msg);
5486        }
5487
5488        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5489                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5490        long callingId = Binder.clearCallingIdentity();
5491        try {
5492            IPackageManager pm = AppGlobals.getPackageManager();
5493            synchronized(this) {
5494                int appId = -1;
5495                try {
5496                    appId = UserHandle.getAppId(
5497                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5498                } catch (RemoteException e) {
5499                }
5500                if (appId == -1) {
5501                    Slog.w(TAG, "Invalid packageName: " + packageName);
5502                    return;
5503                }
5504                killPackageProcessesLocked(packageName, appId, userId,
5505                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5506            }
5507        } finally {
5508            Binder.restoreCallingIdentity(callingId);
5509        }
5510    }
5511
5512    @Override
5513    public void killAllBackgroundProcesses() {
5514        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5515                != PackageManager.PERMISSION_GRANTED) {
5516            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5517                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5518                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5519            Slog.w(TAG, msg);
5520            throw new SecurityException(msg);
5521        }
5522
5523        final long callingId = Binder.clearCallingIdentity();
5524        try {
5525            synchronized (this) {
5526                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5527                final int NP = mProcessNames.getMap().size();
5528                for (int ip = 0; ip < NP; ip++) {
5529                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5530                    final int NA = apps.size();
5531                    for (int ia = 0; ia < NA; ia++) {
5532                        final ProcessRecord app = apps.valueAt(ia);
5533                        if (app.persistent) {
5534                            // We don't kill persistent processes.
5535                            continue;
5536                        }
5537                        if (app.removed) {
5538                            procs.add(app);
5539                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5540                            app.removed = true;
5541                            procs.add(app);
5542                        }
5543                    }
5544                }
5545
5546                final int N = procs.size();
5547                for (int i = 0; i < N; i++) {
5548                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5549                }
5550
5551                mAllowLowerMemLevel = true;
5552
5553                updateOomAdjLocked();
5554                doLowMemReportIfNeededLocked(null);
5555            }
5556        } finally {
5557            Binder.restoreCallingIdentity(callingId);
5558        }
5559    }
5560
5561    /**
5562     * Kills all background processes, except those matching any of the
5563     * specified properties.
5564     *
5565     * @param minTargetSdk the target SDK version at or above which to preserve
5566     *                     processes, or {@code -1} to ignore the target SDK
5567     * @param maxProcState the process state at or below which to preserve
5568     *                     processes, or {@code -1} to ignore the process state
5569     */
5570    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5571        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5572                != PackageManager.PERMISSION_GRANTED) {
5573            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5574                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5575                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5576            Slog.w(TAG, msg);
5577            throw new SecurityException(msg);
5578        }
5579
5580        final long callingId = Binder.clearCallingIdentity();
5581        try {
5582            synchronized (this) {
5583                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5584                final int NP = mProcessNames.getMap().size();
5585                for (int ip = 0; ip < NP; ip++) {
5586                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5587                    final int NA = apps.size();
5588                    for (int ia = 0; ia < NA; ia++) {
5589                        final ProcessRecord app = apps.valueAt(ia);
5590                        if (app.removed) {
5591                            procs.add(app);
5592                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5593                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5594                            app.removed = true;
5595                            procs.add(app);
5596                        }
5597                    }
5598                }
5599
5600                final int N = procs.size();
5601                for (int i = 0; i < N; i++) {
5602                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5603                }
5604            }
5605        } finally {
5606            Binder.restoreCallingIdentity(callingId);
5607        }
5608    }
5609
5610    @Override
5611    public void forceStopPackage(final String packageName, int userId) {
5612        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5613                != PackageManager.PERMISSION_GRANTED) {
5614            String msg = "Permission Denial: forceStopPackage() from pid="
5615                    + Binder.getCallingPid()
5616                    + ", uid=" + Binder.getCallingUid()
5617                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5618            Slog.w(TAG, msg);
5619            throw new SecurityException(msg);
5620        }
5621        final int callingPid = Binder.getCallingPid();
5622        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5623                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5624        long callingId = Binder.clearCallingIdentity();
5625        try {
5626            IPackageManager pm = AppGlobals.getPackageManager();
5627            synchronized(this) {
5628                int[] users = userId == UserHandle.USER_ALL
5629                        ? mUserController.getUsers() : new int[] { userId };
5630                for (int user : users) {
5631                    int pkgUid = -1;
5632                    try {
5633                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5634                                user);
5635                    } catch (RemoteException e) {
5636                    }
5637                    if (pkgUid == -1) {
5638                        Slog.w(TAG, "Invalid packageName: " + packageName);
5639                        continue;
5640                    }
5641                    try {
5642                        pm.setPackageStoppedState(packageName, true, user);
5643                    } catch (RemoteException e) {
5644                    } catch (IllegalArgumentException e) {
5645                        Slog.w(TAG, "Failed trying to unstop package "
5646                                + packageName + ": " + e);
5647                    }
5648                    if (mUserController.isUserRunningLocked(user, 0)) {
5649                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5650                        finishForceStopPackageLocked(packageName, pkgUid);
5651                    }
5652                }
5653            }
5654        } finally {
5655            Binder.restoreCallingIdentity(callingId);
5656        }
5657    }
5658
5659    @Override
5660    public void addPackageDependency(String packageName) {
5661        synchronized (this) {
5662            int callingPid = Binder.getCallingPid();
5663            if (callingPid == Process.myPid()) {
5664                //  Yeah, um, no.
5665                return;
5666            }
5667            ProcessRecord proc;
5668            synchronized (mPidsSelfLocked) {
5669                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5670            }
5671            if (proc != null) {
5672                if (proc.pkgDeps == null) {
5673                    proc.pkgDeps = new ArraySet<String>(1);
5674                }
5675                proc.pkgDeps.add(packageName);
5676            }
5677        }
5678    }
5679
5680    /*
5681     * The pkg name and app id have to be specified.
5682     */
5683    @Override
5684    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5685        if (pkg == null) {
5686            return;
5687        }
5688        // Make sure the uid is valid.
5689        if (appid < 0) {
5690            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5691            return;
5692        }
5693        int callerUid = Binder.getCallingUid();
5694        // Only the system server can kill an application
5695        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5696            // Post an aysnc message to kill the application
5697            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5698            msg.arg1 = appid;
5699            msg.arg2 = 0;
5700            Bundle bundle = new Bundle();
5701            bundle.putString("pkg", pkg);
5702            bundle.putString("reason", reason);
5703            msg.obj = bundle;
5704            mHandler.sendMessage(msg);
5705        } else {
5706            throw new SecurityException(callerUid + " cannot kill pkg: " +
5707                    pkg);
5708        }
5709    }
5710
5711    @Override
5712    public void closeSystemDialogs(String reason) {
5713        enforceNotIsolatedCaller("closeSystemDialogs");
5714
5715        final int pid = Binder.getCallingPid();
5716        final int uid = Binder.getCallingUid();
5717        final long origId = Binder.clearCallingIdentity();
5718        try {
5719            synchronized (this) {
5720                // Only allow this from foreground processes, so that background
5721                // applications can't abuse it to prevent system UI from being shown.
5722                if (uid >= Process.FIRST_APPLICATION_UID) {
5723                    ProcessRecord proc;
5724                    synchronized (mPidsSelfLocked) {
5725                        proc = mPidsSelfLocked.get(pid);
5726                    }
5727                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5728                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5729                                + " from background process " + proc);
5730                        return;
5731                    }
5732                }
5733                closeSystemDialogsLocked(reason);
5734            }
5735        } finally {
5736            Binder.restoreCallingIdentity(origId);
5737        }
5738    }
5739
5740    void closeSystemDialogsLocked(String reason) {
5741        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5743                | Intent.FLAG_RECEIVER_FOREGROUND);
5744        if (reason != null) {
5745            intent.putExtra("reason", reason);
5746        }
5747        mWindowManager.closeSystemDialogs(reason);
5748
5749        mStackSupervisor.closeSystemDialogsLocked();
5750
5751        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5752                AppOpsManager.OP_NONE, null, false, false,
5753                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5754    }
5755
5756    @Override
5757    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5758        enforceNotIsolatedCaller("getProcessMemoryInfo");
5759        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5760        for (int i=pids.length-1; i>=0; i--) {
5761            ProcessRecord proc;
5762            int oomAdj;
5763            synchronized (this) {
5764                synchronized (mPidsSelfLocked) {
5765                    proc = mPidsSelfLocked.get(pids[i]);
5766                    oomAdj = proc != null ? proc.setAdj : 0;
5767                }
5768            }
5769            infos[i] = new Debug.MemoryInfo();
5770            Debug.getMemoryInfo(pids[i], infos[i]);
5771            if (proc != null) {
5772                synchronized (this) {
5773                    if (proc.thread != null && proc.setAdj == oomAdj) {
5774                        // Record this for posterity if the process has been stable.
5775                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5776                                infos[i].getTotalUss(), false, proc.pkgList);
5777                    }
5778                }
5779            }
5780        }
5781        return infos;
5782    }
5783
5784    @Override
5785    public long[] getProcessPss(int[] pids) {
5786        enforceNotIsolatedCaller("getProcessPss");
5787        long[] pss = new long[pids.length];
5788        for (int i=pids.length-1; i>=0; i--) {
5789            ProcessRecord proc;
5790            int oomAdj;
5791            synchronized (this) {
5792                synchronized (mPidsSelfLocked) {
5793                    proc = mPidsSelfLocked.get(pids[i]);
5794                    oomAdj = proc != null ? proc.setAdj : 0;
5795                }
5796            }
5797            long[] tmpUss = new long[1];
5798            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5799            if (proc != null) {
5800                synchronized (this) {
5801                    if (proc.thread != null && proc.setAdj == oomAdj) {
5802                        // Record this for posterity if the process has been stable.
5803                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5804                    }
5805                }
5806            }
5807        }
5808        return pss;
5809    }
5810
5811    @Override
5812    public void killApplicationProcess(String processName, int uid) {
5813        if (processName == null) {
5814            return;
5815        }
5816
5817        int callerUid = Binder.getCallingUid();
5818        // Only the system server can kill an application
5819        if (callerUid == Process.SYSTEM_UID) {
5820            synchronized (this) {
5821                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5822                if (app != null && app.thread != null) {
5823                    try {
5824                        app.thread.scheduleSuicide();
5825                    } catch (RemoteException e) {
5826                        // If the other end already died, then our work here is done.
5827                    }
5828                } else {
5829                    Slog.w(TAG, "Process/uid not found attempting kill of "
5830                            + processName + " / " + uid);
5831                }
5832            }
5833        } else {
5834            throw new SecurityException(callerUid + " cannot kill app process: " +
5835                    processName);
5836        }
5837    }
5838
5839    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5840        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5841                false, true, false, false, UserHandle.getUserId(uid), reason);
5842    }
5843
5844    private void finishForceStopPackageLocked(final String packageName, int uid) {
5845        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5846                Uri.fromParts("package", packageName, null));
5847        if (!mProcessesReady) {
5848            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5849                    | Intent.FLAG_RECEIVER_FOREGROUND);
5850        }
5851        intent.putExtra(Intent.EXTRA_UID, uid);
5852        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5853        broadcastIntentLocked(null, null, intent,
5854                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5855                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5856    }
5857
5858
5859    private final boolean killPackageProcessesLocked(String packageName, int appId,
5860            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5861            boolean doit, boolean evenPersistent, String reason) {
5862        ArrayList<ProcessRecord> procs = new ArrayList<>();
5863
5864        // Remove all processes this package may have touched: all with the
5865        // same UID (except for the system or root user), and all whose name
5866        // matches the package name.
5867        final int NP = mProcessNames.getMap().size();
5868        for (int ip=0; ip<NP; ip++) {
5869            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5870            final int NA = apps.size();
5871            for (int ia=0; ia<NA; ia++) {
5872                ProcessRecord app = apps.valueAt(ia);
5873                if (app.persistent && !evenPersistent) {
5874                    // we don't kill persistent processes
5875                    continue;
5876                }
5877                if (app.removed) {
5878                    if (doit) {
5879                        procs.add(app);
5880                    }
5881                    continue;
5882                }
5883
5884                // Skip process if it doesn't meet our oom adj requirement.
5885                if (app.setAdj < minOomAdj) {
5886                    continue;
5887                }
5888
5889                // If no package is specified, we call all processes under the
5890                // give user id.
5891                if (packageName == null) {
5892                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5893                        continue;
5894                    }
5895                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5896                        continue;
5897                    }
5898                // Package has been specified, we want to hit all processes
5899                // that match it.  We need to qualify this by the processes
5900                // that are running under the specified app and user ID.
5901                } else {
5902                    final boolean isDep = app.pkgDeps != null
5903                            && app.pkgDeps.contains(packageName);
5904                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5905                        continue;
5906                    }
5907                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5908                        continue;
5909                    }
5910                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5911                        continue;
5912                    }
5913                }
5914
5915                // Process has passed all conditions, kill it!
5916                if (!doit) {
5917                    return true;
5918                }
5919                app.removed = true;
5920                procs.add(app);
5921            }
5922        }
5923
5924        int N = procs.size();
5925        for (int i=0; i<N; i++) {
5926            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5927        }
5928        updateOomAdjLocked();
5929        return N > 0;
5930    }
5931
5932    private void cleanupDisabledPackageComponentsLocked(
5933            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5934
5935        Set<String> disabledClasses = null;
5936        boolean packageDisabled = false;
5937        IPackageManager pm = AppGlobals.getPackageManager();
5938
5939        if (changedClasses == null) {
5940            // Nothing changed...
5941            return;
5942        }
5943
5944        // Determine enable/disable state of the package and its components.
5945        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5946        for (int i = changedClasses.length - 1; i >= 0; i--) {
5947            final String changedClass = changedClasses[i];
5948
5949            if (changedClass.equals(packageName)) {
5950                try {
5951                    // Entire package setting changed
5952                    enabled = pm.getApplicationEnabledSetting(packageName,
5953                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5954                } catch (Exception e) {
5955                    // No such package/component; probably racing with uninstall.  In any
5956                    // event it means we have nothing further to do here.
5957                    return;
5958                }
5959                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5960                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5961                if (packageDisabled) {
5962                    // Entire package is disabled.
5963                    // No need to continue to check component states.
5964                    disabledClasses = null;
5965                    break;
5966                }
5967            } else {
5968                try {
5969                    enabled = pm.getComponentEnabledSetting(
5970                            new ComponentName(packageName, changedClass),
5971                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5972                } catch (Exception e) {
5973                    // As above, probably racing with uninstall.
5974                    return;
5975                }
5976                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5977                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5978                    if (disabledClasses == null) {
5979                        disabledClasses = new ArraySet<>(changedClasses.length);
5980                    }
5981                    disabledClasses.add(changedClass);
5982                }
5983            }
5984        }
5985
5986        if (!packageDisabled && disabledClasses == null) {
5987            // Nothing to do here...
5988            return;
5989        }
5990
5991        // Clean-up disabled activities.
5992        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5993                packageName, disabledClasses, true, false, userId) && mBooted) {
5994            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5995            mStackSupervisor.scheduleIdleLocked();
5996        }
5997
5998        // Clean-up disabled tasks
5999        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6000
6001        // Clean-up disabled services.
6002        mServices.bringDownDisabledPackageServicesLocked(
6003                packageName, disabledClasses, userId, false, killProcess, true);
6004
6005        // Clean-up disabled providers.
6006        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6007        mProviderMap.collectPackageProvidersLocked(
6008                packageName, disabledClasses, true, false, userId, providers);
6009        for (int i = providers.size() - 1; i >= 0; i--) {
6010            removeDyingProviderLocked(null, providers.get(i), true);
6011        }
6012
6013        // Clean-up disabled broadcast receivers.
6014        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6015            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6016                    packageName, disabledClasses, userId, true);
6017        }
6018
6019    }
6020
6021    final boolean clearBroadcastQueueForUserLocked(int userId) {
6022        boolean didSomething = false;
6023        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6024            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6025                    null, null, userId, true);
6026        }
6027        return didSomething;
6028    }
6029
6030    final boolean forceStopPackageLocked(String packageName, int appId,
6031            boolean callerWillRestart, boolean purgeCache, boolean doit,
6032            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6033        int i;
6034
6035        if (userId == UserHandle.USER_ALL && packageName == null) {
6036            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6037        }
6038
6039        if (appId < 0 && packageName != null) {
6040            try {
6041                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6042                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6043            } catch (RemoteException e) {
6044            }
6045        }
6046
6047        if (doit) {
6048            if (packageName != null) {
6049                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6050                        + " user=" + userId + ": " + reason);
6051            } else {
6052                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6053            }
6054
6055            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6056        }
6057
6058        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6059                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6060                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6061
6062        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6063                packageName, null, doit, evenPersistent, userId)) {
6064            if (!doit) {
6065                return true;
6066            }
6067            didSomething = true;
6068        }
6069
6070        if (mServices.bringDownDisabledPackageServicesLocked(
6071                packageName, null, userId, evenPersistent, true, doit)) {
6072            if (!doit) {
6073                return true;
6074            }
6075            didSomething = true;
6076        }
6077
6078        if (packageName == null) {
6079            // Remove all sticky broadcasts from this user.
6080            mStickyBroadcasts.remove(userId);
6081        }
6082
6083        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6084        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6085                userId, providers)) {
6086            if (!doit) {
6087                return true;
6088            }
6089            didSomething = true;
6090        }
6091        for (i = providers.size() - 1; i >= 0; i--) {
6092            removeDyingProviderLocked(null, providers.get(i), true);
6093        }
6094
6095        // Remove transient permissions granted from/to this package/user
6096        removeUriPermissionsForPackageLocked(packageName, userId, false);
6097
6098        if (doit) {
6099            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6100                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6101                        packageName, null, userId, doit);
6102            }
6103        }
6104
6105        if (packageName == null || uninstalling) {
6106            // Remove pending intents.  For now we only do this when force
6107            // stopping users, because we have some problems when doing this
6108            // for packages -- app widgets are not currently cleaned up for
6109            // such packages, so they can be left with bad pending intents.
6110            if (mIntentSenderRecords.size() > 0) {
6111                Iterator<WeakReference<PendingIntentRecord>> it
6112                        = mIntentSenderRecords.values().iterator();
6113                while (it.hasNext()) {
6114                    WeakReference<PendingIntentRecord> wpir = it.next();
6115                    if (wpir == null) {
6116                        it.remove();
6117                        continue;
6118                    }
6119                    PendingIntentRecord pir = wpir.get();
6120                    if (pir == null) {
6121                        it.remove();
6122                        continue;
6123                    }
6124                    if (packageName == null) {
6125                        // Stopping user, remove all objects for the user.
6126                        if (pir.key.userId != userId) {
6127                            // Not the same user, skip it.
6128                            continue;
6129                        }
6130                    } else {
6131                        if (UserHandle.getAppId(pir.uid) != appId) {
6132                            // Different app id, skip it.
6133                            continue;
6134                        }
6135                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6136                            // Different user, skip it.
6137                            continue;
6138                        }
6139                        if (!pir.key.packageName.equals(packageName)) {
6140                            // Different package, skip it.
6141                            continue;
6142                        }
6143                    }
6144                    if (!doit) {
6145                        return true;
6146                    }
6147                    didSomething = true;
6148                    it.remove();
6149                    pir.canceled = true;
6150                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6151                        pir.key.activity.pendingResults.remove(pir.ref);
6152                    }
6153                }
6154            }
6155        }
6156
6157        if (doit) {
6158            if (purgeCache && packageName != null) {
6159                AttributeCache ac = AttributeCache.instance();
6160                if (ac != null) {
6161                    ac.removePackage(packageName);
6162                }
6163            }
6164            if (mBooted) {
6165                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6166                mStackSupervisor.scheduleIdleLocked();
6167            }
6168        }
6169
6170        return didSomething;
6171    }
6172
6173    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6174        ProcessRecord old = mProcessNames.remove(name, uid);
6175        if (old != null) {
6176            old.uidRecord.numProcs--;
6177            if (old.uidRecord.numProcs == 0) {
6178                // No more processes using this uid, tell clients it is gone.
6179                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6180                        "No more processes in " + old.uidRecord);
6181                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6182                mActiveUids.remove(uid);
6183                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6184            }
6185            old.uidRecord = null;
6186        }
6187        mIsolatedProcesses.remove(uid);
6188        return old;
6189    }
6190
6191    private final void addProcessNameLocked(ProcessRecord proc) {
6192        // We shouldn't already have a process under this name, but just in case we
6193        // need to clean up whatever may be there now.
6194        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6195        if (old == proc && proc.persistent) {
6196            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6197            Slog.w(TAG, "Re-adding persistent process " + proc);
6198        } else if (old != null) {
6199            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6200        }
6201        UidRecord uidRec = mActiveUids.get(proc.uid);
6202        if (uidRec == null) {
6203            uidRec = new UidRecord(proc.uid);
6204            // This is the first appearance of the uid, report it now!
6205            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6206                    "Creating new process uid: " + uidRec);
6207            mActiveUids.put(proc.uid, uidRec);
6208            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6209            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6210        }
6211        proc.uidRecord = uidRec;
6212        uidRec.numProcs++;
6213        mProcessNames.put(proc.processName, proc.uid, proc);
6214        if (proc.isolated) {
6215            mIsolatedProcesses.put(proc.uid, proc);
6216        }
6217    }
6218
6219    boolean removeProcessLocked(ProcessRecord app,
6220            boolean callerWillRestart, boolean allowRestart, String reason) {
6221        final String name = app.processName;
6222        final int uid = app.uid;
6223        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6224            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6225
6226        ProcessRecord old = mProcessNames.get(name, uid);
6227        if (old != app) {
6228            // This process is no longer active, so nothing to do.
6229            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6230            return false;
6231        }
6232        removeProcessNameLocked(name, uid);
6233        if (mHeavyWeightProcess == app) {
6234            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6235                    mHeavyWeightProcess.userId, 0));
6236            mHeavyWeightProcess = null;
6237        }
6238        boolean needRestart = false;
6239        if (app.pid > 0 && app.pid != MY_PID) {
6240            int pid = app.pid;
6241            synchronized (mPidsSelfLocked) {
6242                mPidsSelfLocked.remove(pid);
6243                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6244            }
6245            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6246            if (app.isolated) {
6247                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6248            }
6249            boolean willRestart = false;
6250            if (app.persistent && !app.isolated) {
6251                if (!callerWillRestart) {
6252                    willRestart = true;
6253                } else {
6254                    needRestart = true;
6255                }
6256            }
6257            app.kill(reason, true);
6258            handleAppDiedLocked(app, willRestart, allowRestart);
6259            if (willRestart) {
6260                removeLruProcessLocked(app);
6261                addAppLocked(app.info, false, null /* ABI override */);
6262            }
6263        } else {
6264            mRemovedProcesses.add(app);
6265        }
6266
6267        return needRestart;
6268    }
6269
6270    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6271        cleanupAppInLaunchingProvidersLocked(app, true);
6272        removeProcessLocked(app, false, true, "timeout publishing content providers");
6273    }
6274
6275    private final void processStartTimedOutLocked(ProcessRecord app) {
6276        final int pid = app.pid;
6277        boolean gone = false;
6278        synchronized (mPidsSelfLocked) {
6279            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6280            if (knownApp != null && knownApp.thread == null) {
6281                mPidsSelfLocked.remove(pid);
6282                gone = true;
6283            }
6284        }
6285
6286        if (gone) {
6287            Slog.w(TAG, "Process " + app + " failed to attach");
6288            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6289                    pid, app.uid, app.processName);
6290            removeProcessNameLocked(app.processName, app.uid);
6291            if (mHeavyWeightProcess == app) {
6292                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6293                        mHeavyWeightProcess.userId, 0));
6294                mHeavyWeightProcess = null;
6295            }
6296            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6297            if (app.isolated) {
6298                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6299            }
6300            // Take care of any launching providers waiting for this process.
6301            cleanupAppInLaunchingProvidersLocked(app, true);
6302            // Take care of any services that are waiting for the process.
6303            mServices.processStartTimedOutLocked(app);
6304            app.kill("start timeout", true);
6305            removeLruProcessLocked(app);
6306            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6307                Slog.w(TAG, "Unattached app died before backup, skipping");
6308                try {
6309                    IBackupManager bm = IBackupManager.Stub.asInterface(
6310                            ServiceManager.getService(Context.BACKUP_SERVICE));
6311                    bm.agentDisconnected(app.info.packageName);
6312                } catch (RemoteException e) {
6313                    // Can't happen; the backup manager is local
6314                }
6315            }
6316            if (isPendingBroadcastProcessLocked(pid)) {
6317                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6318                skipPendingBroadcastLocked(pid);
6319            }
6320        } else {
6321            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6322        }
6323    }
6324
6325    private final boolean attachApplicationLocked(IApplicationThread thread,
6326            int pid) {
6327
6328        // Find the application record that is being attached...  either via
6329        // the pid if we are running in multiple processes, or just pull the
6330        // next app record if we are emulating process with anonymous threads.
6331        ProcessRecord app;
6332        if (pid != MY_PID && pid >= 0) {
6333            synchronized (mPidsSelfLocked) {
6334                app = mPidsSelfLocked.get(pid);
6335            }
6336        } else {
6337            app = null;
6338        }
6339
6340        if (app == null) {
6341            Slog.w(TAG, "No pending application record for pid " + pid
6342                    + " (IApplicationThread " + thread + "); dropping process");
6343            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6344            if (pid > 0 && pid != MY_PID) {
6345                Process.killProcessQuiet(pid);
6346                //TODO: killProcessGroup(app.info.uid, pid);
6347            } else {
6348                try {
6349                    thread.scheduleExit();
6350                } catch (Exception e) {
6351                    // Ignore exceptions.
6352                }
6353            }
6354            return false;
6355        }
6356
6357        // If this application record is still attached to a previous
6358        // process, clean it up now.
6359        if (app.thread != null) {
6360            handleAppDiedLocked(app, true, true);
6361        }
6362
6363        // Tell the process all about itself.
6364
6365        if (DEBUG_ALL) Slog.v(
6366                TAG, "Binding process pid " + pid + " to record " + app);
6367
6368        final String processName = app.processName;
6369        try {
6370            AppDeathRecipient adr = new AppDeathRecipient(
6371                    app, pid, thread);
6372            thread.asBinder().linkToDeath(adr, 0);
6373            app.deathRecipient = adr;
6374        } catch (RemoteException e) {
6375            app.resetPackageList(mProcessStats);
6376            startProcessLocked(app, "link fail", processName);
6377            return false;
6378        }
6379
6380        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6381
6382        app.makeActive(thread, mProcessStats);
6383        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6384        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6385        app.forcingToForeground = null;
6386        updateProcessForegroundLocked(app, false, false);
6387        app.hasShownUi = false;
6388        app.debugging = false;
6389        app.cached = false;
6390        app.killedByAm = false;
6391
6392        // We carefully use the same state that PackageManager uses for
6393        // filtering, since we use this flag to decide if we need to install
6394        // providers when user is unlocked later
6395        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6396
6397        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6398
6399        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6400        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6401
6402        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6403            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6404            msg.obj = app;
6405            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6406        }
6407
6408        if (!normalMode) {
6409            Slog.i(TAG, "Launching preboot mode app: " + app);
6410        }
6411
6412        if (DEBUG_ALL) Slog.v(
6413            TAG, "New app record " + app
6414            + " thread=" + thread.asBinder() + " pid=" + pid);
6415        try {
6416            int testMode = IApplicationThread.DEBUG_OFF;
6417            if (mDebugApp != null && mDebugApp.equals(processName)) {
6418                testMode = mWaitForDebugger
6419                    ? IApplicationThread.DEBUG_WAIT
6420                    : IApplicationThread.DEBUG_ON;
6421                app.debugging = true;
6422                if (mDebugTransient) {
6423                    mDebugApp = mOrigDebugApp;
6424                    mWaitForDebugger = mOrigWaitForDebugger;
6425                }
6426            }
6427            String profileFile = app.instrumentationProfileFile;
6428            ParcelFileDescriptor profileFd = null;
6429            int samplingInterval = 0;
6430            boolean profileAutoStop = false;
6431            if (mProfileApp != null && mProfileApp.equals(processName)) {
6432                mProfileProc = app;
6433                profileFile = mProfileFile;
6434                profileFd = mProfileFd;
6435                samplingInterval = mSamplingInterval;
6436                profileAutoStop = mAutoStopProfiler;
6437            }
6438            boolean enableTrackAllocation = false;
6439            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6440                enableTrackAllocation = true;
6441                mTrackAllocationApp = null;
6442            }
6443
6444            // If the app is being launched for restore or full backup, set it up specially
6445            boolean isRestrictedBackupMode = false;
6446            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6447                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6448                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6449                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6450                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6451            }
6452
6453            if (app.instrumentationClass != null) {
6454                notifyPackageUse(app.instrumentationClass.getPackageName(),
6455                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6456            }
6457            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6458                    + processName + " with config " + mConfiguration);
6459            ApplicationInfo appInfo = app.instrumentationInfo != null
6460                    ? app.instrumentationInfo : app.info;
6461            app.compat = compatibilityInfoForPackageLocked(appInfo);
6462            if (profileFd != null) {
6463                profileFd = profileFd.dup();
6464            }
6465            ProfilerInfo profilerInfo = profileFile == null ? null
6466                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6467            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6468                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6469                    app.instrumentationUiAutomationConnection, testMode,
6470                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6471                    isRestrictedBackupMode || !normalMode, app.persistent,
6472                    new Configuration(mConfiguration), app.compat,
6473                    getCommonServicesLocked(app.isolated),
6474                    mCoreSettingsObserver.getCoreSettingsLocked());
6475            updateLruProcessLocked(app, false, null);
6476            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6477        } catch (Exception e) {
6478            // todo: Yikes!  What should we do?  For now we will try to
6479            // start another process, but that could easily get us in
6480            // an infinite loop of restarting processes...
6481            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6482
6483            app.resetPackageList(mProcessStats);
6484            app.unlinkDeathRecipient();
6485            startProcessLocked(app, "bind fail", processName);
6486            return false;
6487        }
6488
6489        // Remove this record from the list of starting applications.
6490        mPersistentStartingProcesses.remove(app);
6491        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6492                "Attach application locked removing on hold: " + app);
6493        mProcessesOnHold.remove(app);
6494
6495        boolean badApp = false;
6496        boolean didSomething = false;
6497
6498        // See if the top visible activity is waiting to run in this process...
6499        if (normalMode) {
6500            try {
6501                if (mStackSupervisor.attachApplicationLocked(app)) {
6502                    didSomething = true;
6503                }
6504            } catch (Exception e) {
6505                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6506                badApp = true;
6507            }
6508        }
6509
6510        // Find any services that should be running in this process...
6511        if (!badApp) {
6512            try {
6513                didSomething |= mServices.attachApplicationLocked(app, processName);
6514            } catch (Exception e) {
6515                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6516                badApp = true;
6517            }
6518        }
6519
6520        // Check if a next-broadcast receiver is in this process...
6521        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6522            try {
6523                didSomething |= sendPendingBroadcastsLocked(app);
6524            } catch (Exception e) {
6525                // If the app died trying to launch the receiver we declare it 'bad'
6526                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6527                badApp = true;
6528            }
6529        }
6530
6531        // Check whether the next backup agent is in this process...
6532        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6533            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6534                    "New app is backup target, launching agent for " + app);
6535            notifyPackageUse(mBackupTarget.appInfo.packageName,
6536                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6537            try {
6538                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6539                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6540                        mBackupTarget.backupMode);
6541            } catch (Exception e) {
6542                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6543                badApp = true;
6544            }
6545        }
6546
6547        if (badApp) {
6548            app.kill("error during init", true);
6549            handleAppDiedLocked(app, false, true);
6550            return false;
6551        }
6552
6553        if (!didSomething) {
6554            updateOomAdjLocked();
6555        }
6556
6557        return true;
6558    }
6559
6560    @Override
6561    public final void attachApplication(IApplicationThread thread) {
6562        synchronized (this) {
6563            int callingPid = Binder.getCallingPid();
6564            final long origId = Binder.clearCallingIdentity();
6565            attachApplicationLocked(thread, callingPid);
6566            Binder.restoreCallingIdentity(origId);
6567        }
6568    }
6569
6570    @Override
6571    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6572        final long origId = Binder.clearCallingIdentity();
6573        synchronized (this) {
6574            ActivityStack stack = ActivityRecord.getStackLocked(token);
6575            if (stack != null) {
6576                ActivityRecord r =
6577                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6578                if (stopProfiling) {
6579                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6580                        try {
6581                            mProfileFd.close();
6582                        } catch (IOException e) {
6583                        }
6584                        clearProfilerLocked();
6585                    }
6586                }
6587            }
6588        }
6589        Binder.restoreCallingIdentity(origId);
6590    }
6591
6592    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6593        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6594                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6595    }
6596
6597    void enableScreenAfterBoot() {
6598        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6599                SystemClock.uptimeMillis());
6600        mWindowManager.enableScreenAfterBoot();
6601
6602        synchronized (this) {
6603            updateEventDispatchingLocked();
6604        }
6605    }
6606
6607    @Override
6608    public void showBootMessage(final CharSequence msg, final boolean always) {
6609        if (Binder.getCallingUid() != Process.myUid()) {
6610            // These days only the core system can call this, so apps can't get in
6611            // the way of what we show about running them.
6612        }
6613        mWindowManager.showBootMessage(msg, always);
6614    }
6615
6616    @Override
6617    public void keyguardWaitingForActivityDrawn() {
6618        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6619        final long token = Binder.clearCallingIdentity();
6620        try {
6621            synchronized (this) {
6622                if (DEBUG_LOCKSCREEN) logLockScreen("");
6623                mWindowManager.keyguardWaitingForActivityDrawn();
6624                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6625                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6626                    updateSleepIfNeededLocked();
6627                }
6628            }
6629        } finally {
6630            Binder.restoreCallingIdentity(token);
6631        }
6632    }
6633
6634    @Override
6635    public void keyguardGoingAway(int flags) {
6636        enforceNotIsolatedCaller("keyguardGoingAway");
6637        final long token = Binder.clearCallingIdentity();
6638        try {
6639            synchronized (this) {
6640                if (DEBUG_LOCKSCREEN) logLockScreen("");
6641                mWindowManager.keyguardGoingAway(flags);
6642                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6643                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6644                    updateSleepIfNeededLocked();
6645
6646                    // Some stack visibility might change (e.g. docked stack)
6647                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6648                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6649                }
6650            }
6651        } finally {
6652            Binder.restoreCallingIdentity(token);
6653        }
6654    }
6655
6656    final void finishBooting() {
6657        synchronized (this) {
6658            if (!mBootAnimationComplete) {
6659                mCallFinishBooting = true;
6660                return;
6661            }
6662            mCallFinishBooting = false;
6663        }
6664
6665        ArraySet<String> completedIsas = new ArraySet<String>();
6666        for (String abi : Build.SUPPORTED_ABIS) {
6667            Process.establishZygoteConnectionForAbi(abi);
6668            final String instructionSet = VMRuntime.getInstructionSet(abi);
6669            if (!completedIsas.contains(instructionSet)) {
6670                try {
6671                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6672                } catch (InstallerException e) {
6673                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6674                            e.getMessage() +")");
6675                }
6676                completedIsas.add(instructionSet);
6677            }
6678        }
6679
6680        IntentFilter pkgFilter = new IntentFilter();
6681        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6682        pkgFilter.addDataScheme("package");
6683        mContext.registerReceiver(new BroadcastReceiver() {
6684            @Override
6685            public void onReceive(Context context, Intent intent) {
6686                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6687                if (pkgs != null) {
6688                    for (String pkg : pkgs) {
6689                        synchronized (ActivityManagerService.this) {
6690                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6691                                    0, "query restart")) {
6692                                setResultCode(Activity.RESULT_OK);
6693                                return;
6694                            }
6695                        }
6696                    }
6697                }
6698            }
6699        }, pkgFilter);
6700
6701        IntentFilter dumpheapFilter = new IntentFilter();
6702        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6703        mContext.registerReceiver(new BroadcastReceiver() {
6704            @Override
6705            public void onReceive(Context context, Intent intent) {
6706                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6707                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6708                } else {
6709                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6710                }
6711            }
6712        }, dumpheapFilter);
6713
6714        // Let system services know.
6715        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6716
6717        synchronized (this) {
6718            // Ensure that any processes we had put on hold are now started
6719            // up.
6720            final int NP = mProcessesOnHold.size();
6721            if (NP > 0) {
6722                ArrayList<ProcessRecord> procs =
6723                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6724                for (int ip=0; ip<NP; ip++) {
6725                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6726                            + procs.get(ip));
6727                    startProcessLocked(procs.get(ip), "on-hold", null);
6728                }
6729            }
6730
6731            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6732                // Start looking for apps that are abusing wake locks.
6733                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6734                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6735                // Tell anyone interested that we are done booting!
6736                SystemProperties.set("sys.boot_completed", "1");
6737
6738                // And trigger dev.bootcomplete if we are not showing encryption progress
6739                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6740                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6741                    SystemProperties.set("dev.bootcomplete", "1");
6742                }
6743                mUserController.sendBootCompletedLocked(
6744                        new IIntentReceiver.Stub() {
6745                            @Override
6746                            public void performReceive(Intent intent, int resultCode,
6747                                    String data, Bundle extras, boolean ordered,
6748                                    boolean sticky, int sendingUser) {
6749                                synchronized (ActivityManagerService.this) {
6750                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6751                                            true, false);
6752                                }
6753                            }
6754                        });
6755                scheduleStartProfilesLocked();
6756            }
6757        }
6758    }
6759
6760    @Override
6761    public void bootAnimationComplete() {
6762        final boolean callFinishBooting;
6763        synchronized (this) {
6764            callFinishBooting = mCallFinishBooting;
6765            mBootAnimationComplete = true;
6766        }
6767        if (callFinishBooting) {
6768            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6769            finishBooting();
6770            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6771        }
6772    }
6773
6774    final void ensureBootCompleted() {
6775        boolean booting;
6776        boolean enableScreen;
6777        synchronized (this) {
6778            booting = mBooting;
6779            mBooting = false;
6780            enableScreen = !mBooted;
6781            mBooted = true;
6782        }
6783
6784        if (booting) {
6785            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6786            finishBooting();
6787            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6788        }
6789
6790        if (enableScreen) {
6791            enableScreenAfterBoot();
6792        }
6793    }
6794
6795    @Override
6796    public final void activityResumed(IBinder token) {
6797        final long origId = Binder.clearCallingIdentity();
6798        synchronized(this) {
6799            ActivityStack stack = ActivityRecord.getStackLocked(token);
6800            if (stack != null) {
6801                stack.activityResumedLocked(token);
6802            }
6803        }
6804        Binder.restoreCallingIdentity(origId);
6805    }
6806
6807    @Override
6808    public final void activityPaused(IBinder token) {
6809        final long origId = Binder.clearCallingIdentity();
6810        synchronized(this) {
6811            ActivityStack stack = ActivityRecord.getStackLocked(token);
6812            if (stack != null) {
6813                stack.activityPausedLocked(token, false);
6814            }
6815        }
6816        Binder.restoreCallingIdentity(origId);
6817    }
6818
6819    @Override
6820    public final void activityStopped(IBinder token, Bundle icicle,
6821            PersistableBundle persistentState, CharSequence description) {
6822        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6823
6824        // Refuse possible leaked file descriptors
6825        if (icicle != null && icicle.hasFileDescriptors()) {
6826            throw new IllegalArgumentException("File descriptors passed in Bundle");
6827        }
6828
6829        final long origId = Binder.clearCallingIdentity();
6830
6831        synchronized (this) {
6832            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6833            if (r != null) {
6834                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6835            }
6836        }
6837
6838        trimApplications();
6839
6840        Binder.restoreCallingIdentity(origId);
6841    }
6842
6843    @Override
6844    public final void activityDestroyed(IBinder token) {
6845        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6846        synchronized (this) {
6847            ActivityStack stack = ActivityRecord.getStackLocked(token);
6848            if (stack != null) {
6849                stack.activityDestroyedLocked(token, "activityDestroyed");
6850            }
6851        }
6852    }
6853
6854    @Override
6855    public final void activityRelaunched(IBinder token) {
6856        final long origId = Binder.clearCallingIdentity();
6857        synchronized (this) {
6858            mStackSupervisor.activityRelaunchedLocked(token);
6859        }
6860        Binder.restoreCallingIdentity(origId);
6861    }
6862
6863    @Override
6864    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6865            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6866        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6867                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6868        synchronized (this) {
6869            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6870            if (record == null) {
6871                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6872                        + "found for: " + token);
6873            }
6874            record.setSizeConfigurations(horizontalSizeConfiguration,
6875                    verticalSizeConfigurations, smallestSizeConfigurations);
6876        }
6877    }
6878
6879    @Override
6880    public final void backgroundResourcesReleased(IBinder token) {
6881        final long origId = Binder.clearCallingIdentity();
6882        try {
6883            synchronized (this) {
6884                ActivityStack stack = ActivityRecord.getStackLocked(token);
6885                if (stack != null) {
6886                    stack.backgroundResourcesReleased();
6887                }
6888            }
6889        } finally {
6890            Binder.restoreCallingIdentity(origId);
6891        }
6892    }
6893
6894    @Override
6895    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6896        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6897    }
6898
6899    @Override
6900    public final void notifyEnterAnimationComplete(IBinder token) {
6901        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6902    }
6903
6904    @Override
6905    public String getCallingPackage(IBinder token) {
6906        synchronized (this) {
6907            ActivityRecord r = getCallingRecordLocked(token);
6908            return r != null ? r.info.packageName : null;
6909        }
6910    }
6911
6912    @Override
6913    public ComponentName getCallingActivity(IBinder token) {
6914        synchronized (this) {
6915            ActivityRecord r = getCallingRecordLocked(token);
6916            return r != null ? r.intent.getComponent() : null;
6917        }
6918    }
6919
6920    private ActivityRecord getCallingRecordLocked(IBinder token) {
6921        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6922        if (r == null) {
6923            return null;
6924        }
6925        return r.resultTo;
6926    }
6927
6928    @Override
6929    public ComponentName getActivityClassForToken(IBinder token) {
6930        synchronized(this) {
6931            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6932            if (r == null) {
6933                return null;
6934            }
6935            return r.intent.getComponent();
6936        }
6937    }
6938
6939    @Override
6940    public String getPackageForToken(IBinder token) {
6941        synchronized(this) {
6942            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6943            if (r == null) {
6944                return null;
6945            }
6946            return r.packageName;
6947        }
6948    }
6949
6950    @Override
6951    public boolean isRootVoiceInteraction(IBinder token) {
6952        synchronized(this) {
6953            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6954            if (r == null) {
6955                return false;
6956            }
6957            return r.rootVoiceInteraction;
6958        }
6959    }
6960
6961    @Override
6962    public IIntentSender getIntentSender(int type,
6963            String packageName, IBinder token, String resultWho,
6964            int requestCode, Intent[] intents, String[] resolvedTypes,
6965            int flags, Bundle bOptions, int userId) {
6966        enforceNotIsolatedCaller("getIntentSender");
6967        // Refuse possible leaked file descriptors
6968        if (intents != null) {
6969            if (intents.length < 1) {
6970                throw new IllegalArgumentException("Intents array length must be >= 1");
6971            }
6972            for (int i=0; i<intents.length; i++) {
6973                Intent intent = intents[i];
6974                if (intent != null) {
6975                    if (intent.hasFileDescriptors()) {
6976                        throw new IllegalArgumentException("File descriptors passed in Intent");
6977                    }
6978                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6979                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6980                        throw new IllegalArgumentException(
6981                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6982                    }
6983                    intents[i] = new Intent(intent);
6984                }
6985            }
6986            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6987                throw new IllegalArgumentException(
6988                        "Intent array length does not match resolvedTypes length");
6989            }
6990        }
6991        if (bOptions != null) {
6992            if (bOptions.hasFileDescriptors()) {
6993                throw new IllegalArgumentException("File descriptors passed in options");
6994            }
6995        }
6996
6997        synchronized(this) {
6998            int callingUid = Binder.getCallingUid();
6999            int origUserId = userId;
7000            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7001                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7002                    ALLOW_NON_FULL, "getIntentSender", null);
7003            if (origUserId == UserHandle.USER_CURRENT) {
7004                // We don't want to evaluate this until the pending intent is
7005                // actually executed.  However, we do want to always do the
7006                // security checking for it above.
7007                userId = UserHandle.USER_CURRENT;
7008            }
7009            try {
7010                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7011                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7012                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7013                    if (!UserHandle.isSameApp(callingUid, uid)) {
7014                        String msg = "Permission Denial: getIntentSender() from pid="
7015                            + Binder.getCallingPid()
7016                            + ", uid=" + Binder.getCallingUid()
7017                            + ", (need uid=" + uid + ")"
7018                            + " is not allowed to send as package " + packageName;
7019                        Slog.w(TAG, msg);
7020                        throw new SecurityException(msg);
7021                    }
7022                }
7023
7024                return getIntentSenderLocked(type, packageName, callingUid, userId,
7025                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7026
7027            } catch (RemoteException e) {
7028                throw new SecurityException(e);
7029            }
7030        }
7031    }
7032
7033    IIntentSender getIntentSenderLocked(int type, String packageName,
7034            int callingUid, int userId, IBinder token, String resultWho,
7035            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7036            Bundle bOptions) {
7037        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7038        ActivityRecord activity = null;
7039        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7040            activity = ActivityRecord.isInStackLocked(token);
7041            if (activity == null) {
7042                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7043                return null;
7044            }
7045            if (activity.finishing) {
7046                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7047                return null;
7048            }
7049        }
7050
7051        // We're going to be splicing together extras before sending, so we're
7052        // okay poking into any contained extras.
7053        if (intents != null) {
7054            for (int i = 0; i < intents.length; i++) {
7055                intents[i].setDefusable(true);
7056            }
7057        }
7058        Bundle.setDefusable(bOptions, true);
7059
7060        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7061        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7062        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7063        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7064                |PendingIntent.FLAG_UPDATE_CURRENT);
7065
7066        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7067                type, packageName, activity, resultWho,
7068                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7069        WeakReference<PendingIntentRecord> ref;
7070        ref = mIntentSenderRecords.get(key);
7071        PendingIntentRecord rec = ref != null ? ref.get() : null;
7072        if (rec != null) {
7073            if (!cancelCurrent) {
7074                if (updateCurrent) {
7075                    if (rec.key.requestIntent != null) {
7076                        rec.key.requestIntent.replaceExtras(intents != null ?
7077                                intents[intents.length - 1] : null);
7078                    }
7079                    if (intents != null) {
7080                        intents[intents.length-1] = rec.key.requestIntent;
7081                        rec.key.allIntents = intents;
7082                        rec.key.allResolvedTypes = resolvedTypes;
7083                    } else {
7084                        rec.key.allIntents = null;
7085                        rec.key.allResolvedTypes = null;
7086                    }
7087                }
7088                return rec;
7089            }
7090            rec.canceled = true;
7091            mIntentSenderRecords.remove(key);
7092        }
7093        if (noCreate) {
7094            return rec;
7095        }
7096        rec = new PendingIntentRecord(this, key, callingUid);
7097        mIntentSenderRecords.put(key, rec.ref);
7098        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7099            if (activity.pendingResults == null) {
7100                activity.pendingResults
7101                        = new HashSet<WeakReference<PendingIntentRecord>>();
7102            }
7103            activity.pendingResults.add(rec.ref);
7104        }
7105        return rec;
7106    }
7107
7108    @Override
7109    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7110            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7111        if (target instanceof PendingIntentRecord) {
7112            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7113                    finishedReceiver, requiredPermission, options);
7114        } else {
7115            if (intent == null) {
7116                // Weird case: someone has given us their own custom IIntentSender, and now
7117                // they have someone else trying to send to it but of course this isn't
7118                // really a PendingIntent, so there is no base Intent, and the caller isn't
7119                // supplying an Intent... but we never want to dispatch a null Intent to
7120                // a receiver, so um...  let's make something up.
7121                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7122                intent = new Intent(Intent.ACTION_MAIN);
7123            }
7124            try {
7125                target.send(code, intent, resolvedType, null, requiredPermission, options);
7126            } catch (RemoteException e) {
7127            }
7128            // Platform code can rely on getting a result back when the send is done, but if
7129            // this intent sender is from outside of the system we can't rely on it doing that.
7130            // So instead we don't give it the result receiver, and instead just directly
7131            // report the finish immediately.
7132            if (finishedReceiver != null) {
7133                try {
7134                    finishedReceiver.performReceive(intent, 0,
7135                            null, null, false, false, UserHandle.getCallingUserId());
7136                } catch (RemoteException e) {
7137                }
7138            }
7139            return 0;
7140        }
7141    }
7142
7143    /**
7144     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7145     *
7146     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7147     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7148     */
7149    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7150        if (DEBUG_WHITELISTS) {
7151            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7152                    + targetUid + ", " + duration + ")");
7153        }
7154        synchronized (mPidsSelfLocked) {
7155            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7156            if (pr == null) {
7157                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7158                return;
7159            }
7160            if (!pr.whitelistManager) {
7161                if (DEBUG_WHITELISTS) {
7162                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7163                            + callerPid + " is not allowed");
7164                }
7165                return;
7166            }
7167        }
7168
7169        final long token = Binder.clearCallingIdentity();
7170        try {
7171            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7172                    true, "pe from uid:" + callerUid);
7173        } finally {
7174            Binder.restoreCallingIdentity(token);
7175        }
7176    }
7177
7178    @Override
7179    public void cancelIntentSender(IIntentSender sender) {
7180        if (!(sender instanceof PendingIntentRecord)) {
7181            return;
7182        }
7183        synchronized(this) {
7184            PendingIntentRecord rec = (PendingIntentRecord)sender;
7185            try {
7186                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7187                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7188                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7189                    String msg = "Permission Denial: cancelIntentSender() from pid="
7190                        + Binder.getCallingPid()
7191                        + ", uid=" + Binder.getCallingUid()
7192                        + " is not allowed to cancel packges "
7193                        + rec.key.packageName;
7194                    Slog.w(TAG, msg);
7195                    throw new SecurityException(msg);
7196                }
7197            } catch (RemoteException e) {
7198                throw new SecurityException(e);
7199            }
7200            cancelIntentSenderLocked(rec, true);
7201        }
7202    }
7203
7204    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7205        rec.canceled = true;
7206        mIntentSenderRecords.remove(rec.key);
7207        if (cleanActivity && rec.key.activity != null) {
7208            rec.key.activity.pendingResults.remove(rec.ref);
7209        }
7210    }
7211
7212    @Override
7213    public String getPackageForIntentSender(IIntentSender pendingResult) {
7214        if (!(pendingResult instanceof PendingIntentRecord)) {
7215            return null;
7216        }
7217        try {
7218            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7219            return res.key.packageName;
7220        } catch (ClassCastException e) {
7221        }
7222        return null;
7223    }
7224
7225    @Override
7226    public int getUidForIntentSender(IIntentSender sender) {
7227        if (sender instanceof PendingIntentRecord) {
7228            try {
7229                PendingIntentRecord res = (PendingIntentRecord)sender;
7230                return res.uid;
7231            } catch (ClassCastException e) {
7232            }
7233        }
7234        return -1;
7235    }
7236
7237    @Override
7238    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7239        if (!(pendingResult instanceof PendingIntentRecord)) {
7240            return false;
7241        }
7242        try {
7243            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7244            if (res.key.allIntents == null) {
7245                return false;
7246            }
7247            for (int i=0; i<res.key.allIntents.length; i++) {
7248                Intent intent = res.key.allIntents[i];
7249                if (intent.getPackage() != null && intent.getComponent() != null) {
7250                    return false;
7251                }
7252            }
7253            return true;
7254        } catch (ClassCastException e) {
7255        }
7256        return false;
7257    }
7258
7259    @Override
7260    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7261        if (!(pendingResult instanceof PendingIntentRecord)) {
7262            return false;
7263        }
7264        try {
7265            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7266            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7267                return true;
7268            }
7269            return false;
7270        } catch (ClassCastException e) {
7271        }
7272        return false;
7273    }
7274
7275    @Override
7276    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7277        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7278                "getIntentForIntentSender()");
7279        if (!(pendingResult instanceof PendingIntentRecord)) {
7280            return null;
7281        }
7282        try {
7283            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7284            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7285        } catch (ClassCastException e) {
7286        }
7287        return null;
7288    }
7289
7290    @Override
7291    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7292        if (!(pendingResult instanceof PendingIntentRecord)) {
7293            return null;
7294        }
7295        try {
7296            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7297            synchronized (this) {
7298                return getTagForIntentSenderLocked(res, prefix);
7299            }
7300        } catch (ClassCastException e) {
7301        }
7302        return null;
7303    }
7304
7305    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7306        final Intent intent = res.key.requestIntent;
7307        if (intent != null) {
7308            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7309                    || res.lastTagPrefix.equals(prefix))) {
7310                return res.lastTag;
7311            }
7312            res.lastTagPrefix = prefix;
7313            final StringBuilder sb = new StringBuilder(128);
7314            if (prefix != null) {
7315                sb.append(prefix);
7316            }
7317            if (intent.getAction() != null) {
7318                sb.append(intent.getAction());
7319            } else if (intent.getComponent() != null) {
7320                intent.getComponent().appendShortString(sb);
7321            } else {
7322                sb.append("?");
7323            }
7324            return res.lastTag = sb.toString();
7325        }
7326        return null;
7327    }
7328
7329    @Override
7330    public void setProcessLimit(int max) {
7331        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7332                "setProcessLimit()");
7333        synchronized (this) {
7334            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7335            mProcessLimitOverride = max;
7336        }
7337        trimApplications();
7338    }
7339
7340    @Override
7341    public int getProcessLimit() {
7342        synchronized (this) {
7343            return mProcessLimitOverride;
7344        }
7345    }
7346
7347    void foregroundTokenDied(ForegroundToken token) {
7348        synchronized (ActivityManagerService.this) {
7349            synchronized (mPidsSelfLocked) {
7350                ForegroundToken cur
7351                    = mForegroundProcesses.get(token.pid);
7352                if (cur != token) {
7353                    return;
7354                }
7355                mForegroundProcesses.remove(token.pid);
7356                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7357                if (pr == null) {
7358                    return;
7359                }
7360                pr.forcingToForeground = null;
7361                updateProcessForegroundLocked(pr, false, false);
7362            }
7363            updateOomAdjLocked();
7364        }
7365    }
7366
7367    @Override
7368    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7369        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7370                "setProcessForeground()");
7371        synchronized(this) {
7372            boolean changed = false;
7373
7374            synchronized (mPidsSelfLocked) {
7375                ProcessRecord pr = mPidsSelfLocked.get(pid);
7376                if (pr == null && isForeground) {
7377                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7378                    return;
7379                }
7380                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7381                if (oldToken != null) {
7382                    oldToken.token.unlinkToDeath(oldToken, 0);
7383                    mForegroundProcesses.remove(pid);
7384                    if (pr != null) {
7385                        pr.forcingToForeground = null;
7386                    }
7387                    changed = true;
7388                }
7389                if (isForeground && token != null) {
7390                    ForegroundToken newToken = new ForegroundToken() {
7391                        @Override
7392                        public void binderDied() {
7393                            foregroundTokenDied(this);
7394                        }
7395                    };
7396                    newToken.pid = pid;
7397                    newToken.token = token;
7398                    try {
7399                        token.linkToDeath(newToken, 0);
7400                        mForegroundProcesses.put(pid, newToken);
7401                        pr.forcingToForeground = token;
7402                        changed = true;
7403                    } catch (RemoteException e) {
7404                        // If the process died while doing this, we will later
7405                        // do the cleanup with the process death link.
7406                    }
7407                }
7408            }
7409
7410            if (changed) {
7411                updateOomAdjLocked();
7412            }
7413        }
7414    }
7415
7416    @Override
7417    public boolean isAppForeground(int uid) throws RemoteException {
7418        synchronized (this) {
7419            UidRecord uidRec = mActiveUids.get(uid);
7420            if (uidRec == null || uidRec.idle) {
7421                return false;
7422            }
7423            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7424        }
7425    }
7426
7427    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7428    // be guarded by permission checking.
7429    int getUidState(int uid) {
7430        synchronized (this) {
7431            UidRecord uidRec = mActiveUids.get(uid);
7432            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7433        }
7434    }
7435
7436    @Override
7437    public boolean isInMultiWindowMode(IBinder token) {
7438        final long origId = Binder.clearCallingIdentity();
7439        try {
7440            synchronized(this) {
7441                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7442                if (r == null) {
7443                    return false;
7444                }
7445                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7446                return !r.task.mFullscreen;
7447            }
7448        } finally {
7449            Binder.restoreCallingIdentity(origId);
7450        }
7451    }
7452
7453    @Override
7454    public boolean isInPictureInPictureMode(IBinder token) {
7455        final long origId = Binder.clearCallingIdentity();
7456        try {
7457            synchronized(this) {
7458                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7459                if (stack == null) {
7460                    return false;
7461                }
7462                return stack.mStackId == PINNED_STACK_ID;
7463            }
7464        } finally {
7465            Binder.restoreCallingIdentity(origId);
7466        }
7467    }
7468
7469    @Override
7470    public void enterPictureInPictureMode(IBinder token) {
7471        final long origId = Binder.clearCallingIdentity();
7472        try {
7473            synchronized(this) {
7474                if (!mSupportsPictureInPicture) {
7475                    throw new IllegalStateException("enterPictureInPictureMode: "
7476                            + "Device doesn't support picture-in-picture mode.");
7477                }
7478
7479                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7480
7481                if (r == null) {
7482                    throw new IllegalStateException("enterPictureInPictureMode: "
7483                            + "Can't find activity for token=" + token);
7484                }
7485
7486                if (!r.supportsPictureInPicture()) {
7487                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7488                            + "Picture-In-Picture not supported for r=" + r);
7489                }
7490
7491                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7492                // current bounds.
7493                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7494                final Rect bounds = (pinnedStack != null)
7495                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7496
7497                mStackSupervisor.moveActivityToPinnedStackLocked(
7498                        r, "enterPictureInPictureMode", bounds);
7499            }
7500        } finally {
7501            Binder.restoreCallingIdentity(origId);
7502        }
7503    }
7504
7505    // =========================================================
7506    // PROCESS INFO
7507    // =========================================================
7508
7509    static class ProcessInfoService extends IProcessInfoService.Stub {
7510        final ActivityManagerService mActivityManagerService;
7511        ProcessInfoService(ActivityManagerService activityManagerService) {
7512            mActivityManagerService = activityManagerService;
7513        }
7514
7515        @Override
7516        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7517            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7518                    /*in*/ pids, /*out*/ states, null);
7519        }
7520
7521        @Override
7522        public void getProcessStatesAndOomScoresFromPids(
7523                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7524            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7525                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7526        }
7527    }
7528
7529    /**
7530     * For each PID in the given input array, write the current process state
7531     * for that process into the states array, or -1 to indicate that no
7532     * process with the given PID exists. If scores array is provided, write
7533     * the oom score for the process into the scores array, with INVALID_ADJ
7534     * indicating the PID doesn't exist.
7535     */
7536    public void getProcessStatesAndOomScoresForPIDs(
7537            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7538        if (scores != null) {
7539            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7540                    "getProcessStatesAndOomScoresForPIDs()");
7541        }
7542
7543        if (pids == null) {
7544            throw new NullPointerException("pids");
7545        } else if (states == null) {
7546            throw new NullPointerException("states");
7547        } else if (pids.length != states.length) {
7548            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7549        } else if (scores != null && pids.length != scores.length) {
7550            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7551        }
7552
7553        synchronized (mPidsSelfLocked) {
7554            for (int i = 0; i < pids.length; i++) {
7555                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7556                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7557                        pr.curProcState;
7558                if (scores != null) {
7559                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7560                }
7561            }
7562        }
7563    }
7564
7565    // =========================================================
7566    // PERMISSIONS
7567    // =========================================================
7568
7569    static class PermissionController extends IPermissionController.Stub {
7570        ActivityManagerService mActivityManagerService;
7571        PermissionController(ActivityManagerService activityManagerService) {
7572            mActivityManagerService = activityManagerService;
7573        }
7574
7575        @Override
7576        public boolean checkPermission(String permission, int pid, int uid) {
7577            return mActivityManagerService.checkPermission(permission, pid,
7578                    uid) == PackageManager.PERMISSION_GRANTED;
7579        }
7580
7581        @Override
7582        public String[] getPackagesForUid(int uid) {
7583            return mActivityManagerService.mContext.getPackageManager()
7584                    .getPackagesForUid(uid);
7585        }
7586
7587        @Override
7588        public boolean isRuntimePermission(String permission) {
7589            try {
7590                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7591                        .getPermissionInfo(permission, 0);
7592                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7593            } catch (NameNotFoundException nnfe) {
7594                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7595            }
7596            return false;
7597        }
7598    }
7599
7600    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7601        @Override
7602        public int checkComponentPermission(String permission, int pid, int uid,
7603                int owningUid, boolean exported) {
7604            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7605                    owningUid, exported);
7606        }
7607
7608        @Override
7609        public Object getAMSLock() {
7610            return ActivityManagerService.this;
7611        }
7612    }
7613
7614    /**
7615     * This can be called with or without the global lock held.
7616     */
7617    int checkComponentPermission(String permission, int pid, int uid,
7618            int owningUid, boolean exported) {
7619        if (pid == MY_PID) {
7620            return PackageManager.PERMISSION_GRANTED;
7621        }
7622        return ActivityManager.checkComponentPermission(permission, uid,
7623                owningUid, exported);
7624    }
7625
7626    /**
7627     * As the only public entry point for permissions checking, this method
7628     * can enforce the semantic that requesting a check on a null global
7629     * permission is automatically denied.  (Internally a null permission
7630     * string is used when calling {@link #checkComponentPermission} in cases
7631     * when only uid-based security is needed.)
7632     *
7633     * This can be called with or without the global lock held.
7634     */
7635    @Override
7636    public int checkPermission(String permission, int pid, int uid) {
7637        if (permission == null) {
7638            return PackageManager.PERMISSION_DENIED;
7639        }
7640        return checkComponentPermission(permission, pid, uid, -1, true);
7641    }
7642
7643    @Override
7644    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7645        if (permission == null) {
7646            return PackageManager.PERMISSION_DENIED;
7647        }
7648
7649        // We might be performing an operation on behalf of an indirect binder
7650        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7651        // client identity accordingly before proceeding.
7652        Identity tlsIdentity = sCallerIdentity.get();
7653        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7654            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7655                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7656            uid = tlsIdentity.uid;
7657            pid = tlsIdentity.pid;
7658        }
7659
7660        return checkComponentPermission(permission, pid, uid, -1, true);
7661    }
7662
7663    /**
7664     * Binder IPC calls go through the public entry point.
7665     * This can be called with or without the global lock held.
7666     */
7667    int checkCallingPermission(String permission) {
7668        return checkPermission(permission,
7669                Binder.getCallingPid(),
7670                UserHandle.getAppId(Binder.getCallingUid()));
7671    }
7672
7673    /**
7674     * This can be called with or without the global lock held.
7675     */
7676    void enforceCallingPermission(String permission, String func) {
7677        if (checkCallingPermission(permission)
7678                == PackageManager.PERMISSION_GRANTED) {
7679            return;
7680        }
7681
7682        String msg = "Permission Denial: " + func + " from pid="
7683                + Binder.getCallingPid()
7684                + ", uid=" + Binder.getCallingUid()
7685                + " requires " + permission;
7686        Slog.w(TAG, msg);
7687        throw new SecurityException(msg);
7688    }
7689
7690    /**
7691     * Determine if UID is holding permissions required to access {@link Uri} in
7692     * the given {@link ProviderInfo}. Final permission checking is always done
7693     * in {@link ContentProvider}.
7694     */
7695    private final boolean checkHoldingPermissionsLocked(
7696            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7697        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7698                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7699        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7700            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7701                    != PERMISSION_GRANTED) {
7702                return false;
7703            }
7704        }
7705        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7706    }
7707
7708    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7709            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7710        if (pi.applicationInfo.uid == uid) {
7711            return true;
7712        } else if (!pi.exported) {
7713            return false;
7714        }
7715
7716        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7717        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7718        try {
7719            // check if target holds top-level <provider> permissions
7720            if (!readMet && pi.readPermission != null && considerUidPermissions
7721                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7722                readMet = true;
7723            }
7724            if (!writeMet && pi.writePermission != null && considerUidPermissions
7725                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7726                writeMet = true;
7727            }
7728
7729            // track if unprotected read/write is allowed; any denied
7730            // <path-permission> below removes this ability
7731            boolean allowDefaultRead = pi.readPermission == null;
7732            boolean allowDefaultWrite = pi.writePermission == null;
7733
7734            // check if target holds any <path-permission> that match uri
7735            final PathPermission[] pps = pi.pathPermissions;
7736            if (pps != null) {
7737                final String path = grantUri.uri.getPath();
7738                int i = pps.length;
7739                while (i > 0 && (!readMet || !writeMet)) {
7740                    i--;
7741                    PathPermission pp = pps[i];
7742                    if (pp.match(path)) {
7743                        if (!readMet) {
7744                            final String pprperm = pp.getReadPermission();
7745                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7746                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7747                                    + ": match=" + pp.match(path)
7748                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7749                            if (pprperm != null) {
7750                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7751                                        == PERMISSION_GRANTED) {
7752                                    readMet = true;
7753                                } else {
7754                                    allowDefaultRead = false;
7755                                }
7756                            }
7757                        }
7758                        if (!writeMet) {
7759                            final String ppwperm = pp.getWritePermission();
7760                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7761                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7762                                    + ": match=" + pp.match(path)
7763                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7764                            if (ppwperm != null) {
7765                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7766                                        == PERMISSION_GRANTED) {
7767                                    writeMet = true;
7768                                } else {
7769                                    allowDefaultWrite = false;
7770                                }
7771                            }
7772                        }
7773                    }
7774                }
7775            }
7776
7777            // grant unprotected <provider> read/write, if not blocked by
7778            // <path-permission> above
7779            if (allowDefaultRead) readMet = true;
7780            if (allowDefaultWrite) writeMet = true;
7781
7782        } catch (RemoteException e) {
7783            return false;
7784        }
7785
7786        return readMet && writeMet;
7787    }
7788
7789    public int getAppStartMode(int uid, String packageName) {
7790        synchronized (this) {
7791            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7792        }
7793    }
7794
7795    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7796            boolean allowWhenForeground) {
7797        UidRecord uidRec = mActiveUids.get(uid);
7798        if (!mLenientBackgroundCheck) {
7799            if (!allowWhenForeground || uidRec == null
7800                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7801                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7802                        packageName) != AppOpsManager.MODE_ALLOWED) {
7803                    return ActivityManager.APP_START_MODE_DELAYED;
7804                }
7805            }
7806
7807        } else if (uidRec == null || uidRec.idle) {
7808            if (callingPid >= 0) {
7809                ProcessRecord proc;
7810                synchronized (mPidsSelfLocked) {
7811                    proc = mPidsSelfLocked.get(callingPid);
7812                }
7813                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7814                    // Whoever is instigating this is in the foreground, so we will allow it
7815                    // to go through.
7816                    return ActivityManager.APP_START_MODE_NORMAL;
7817                }
7818            }
7819            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7820                    != AppOpsManager.MODE_ALLOWED) {
7821                return ActivityManager.APP_START_MODE_DELAYED;
7822            }
7823        }
7824        return ActivityManager.APP_START_MODE_NORMAL;
7825    }
7826
7827    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7828        ProviderInfo pi = null;
7829        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7830        if (cpr != null) {
7831            pi = cpr.info;
7832        } else {
7833            try {
7834                pi = AppGlobals.getPackageManager().resolveContentProvider(
7835                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7836                        userHandle);
7837            } catch (RemoteException ex) {
7838            }
7839        }
7840        return pi;
7841    }
7842
7843    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7844        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7845        if (targetUris != null) {
7846            return targetUris.get(grantUri);
7847        }
7848        return null;
7849    }
7850
7851    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7852            String targetPkg, int targetUid, GrantUri grantUri) {
7853        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7854        if (targetUris == null) {
7855            targetUris = Maps.newArrayMap();
7856            mGrantedUriPermissions.put(targetUid, targetUris);
7857        }
7858
7859        UriPermission perm = targetUris.get(grantUri);
7860        if (perm == null) {
7861            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7862            targetUris.put(grantUri, perm);
7863        }
7864
7865        return perm;
7866    }
7867
7868    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7869            final int modeFlags) {
7870        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7871        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7872                : UriPermission.STRENGTH_OWNED;
7873
7874        // Root gets to do everything.
7875        if (uid == 0) {
7876            return true;
7877        }
7878
7879        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7880        if (perms == null) return false;
7881
7882        // First look for exact match
7883        final UriPermission exactPerm = perms.get(grantUri);
7884        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7885            return true;
7886        }
7887
7888        // No exact match, look for prefixes
7889        final int N = perms.size();
7890        for (int i = 0; i < N; i++) {
7891            final UriPermission perm = perms.valueAt(i);
7892            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7893                    && perm.getStrength(modeFlags) >= minStrength) {
7894                return true;
7895            }
7896        }
7897
7898        return false;
7899    }
7900
7901    /**
7902     * @param uri This uri must NOT contain an embedded userId.
7903     * @param userId The userId in which the uri is to be resolved.
7904     */
7905    @Override
7906    public int checkUriPermission(Uri uri, int pid, int uid,
7907            final int modeFlags, int userId, IBinder callerToken) {
7908        enforceNotIsolatedCaller("checkUriPermission");
7909
7910        // Another redirected-binder-call permissions check as in
7911        // {@link checkPermissionWithToken}.
7912        Identity tlsIdentity = sCallerIdentity.get();
7913        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7914            uid = tlsIdentity.uid;
7915            pid = tlsIdentity.pid;
7916        }
7917
7918        // Our own process gets to do everything.
7919        if (pid == MY_PID) {
7920            return PackageManager.PERMISSION_GRANTED;
7921        }
7922        synchronized (this) {
7923            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7924                    ? PackageManager.PERMISSION_GRANTED
7925                    : PackageManager.PERMISSION_DENIED;
7926        }
7927    }
7928
7929    /**
7930     * Check if the targetPkg can be granted permission to access uri by
7931     * the callingUid using the given modeFlags.  Throws a security exception
7932     * if callingUid is not allowed to do this.  Returns the uid of the target
7933     * if the URI permission grant should be performed; returns -1 if it is not
7934     * needed (for example targetPkg already has permission to access the URI).
7935     * If you already know the uid of the target, you can supply it in
7936     * lastTargetUid else set that to -1.
7937     */
7938    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7939            final int modeFlags, int lastTargetUid) {
7940        if (!Intent.isAccessUriMode(modeFlags)) {
7941            return -1;
7942        }
7943
7944        if (targetPkg != null) {
7945            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7946                    "Checking grant " + targetPkg + " permission to " + grantUri);
7947        }
7948
7949        final IPackageManager pm = AppGlobals.getPackageManager();
7950
7951        // If this is not a content: uri, we can't do anything with it.
7952        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7953            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7954                    "Can't grant URI permission for non-content URI: " + grantUri);
7955            return -1;
7956        }
7957
7958        final String authority = grantUri.uri.getAuthority();
7959        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7960                MATCH_DEBUG_TRIAGED_MISSING);
7961        if (pi == null) {
7962            Slog.w(TAG, "No content provider found for permission check: " +
7963                    grantUri.uri.toSafeString());
7964            return -1;
7965        }
7966
7967        int targetUid = lastTargetUid;
7968        if (targetUid < 0 && targetPkg != null) {
7969            try {
7970                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7971                        UserHandle.getUserId(callingUid));
7972                if (targetUid < 0) {
7973                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7974                            "Can't grant URI permission no uid for: " + targetPkg);
7975                    return -1;
7976                }
7977            } catch (RemoteException ex) {
7978                return -1;
7979            }
7980        }
7981
7982        if (targetUid >= 0) {
7983            // First...  does the target actually need this permission?
7984            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7985                // No need to grant the target this permission.
7986                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7987                        "Target " + targetPkg + " already has full permission to " + grantUri);
7988                return -1;
7989            }
7990        } else {
7991            // First...  there is no target package, so can anyone access it?
7992            boolean allowed = pi.exported;
7993            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7994                if (pi.readPermission != null) {
7995                    allowed = false;
7996                }
7997            }
7998            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7999                if (pi.writePermission != null) {
8000                    allowed = false;
8001                }
8002            }
8003            if (allowed) {
8004                return -1;
8005            }
8006        }
8007
8008        /* There is a special cross user grant if:
8009         * - The target is on another user.
8010         * - Apps on the current user can access the uri without any uid permissions.
8011         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8012         * grant uri permissions.
8013         */
8014        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8015                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8016                modeFlags, false /*without considering the uid permissions*/);
8017
8018        // Second...  is the provider allowing granting of URI permissions?
8019        if (!specialCrossUserGrant) {
8020            if (!pi.grantUriPermissions) {
8021                throw new SecurityException("Provider " + pi.packageName
8022                        + "/" + pi.name
8023                        + " does not allow granting of Uri permissions (uri "
8024                        + grantUri + ")");
8025            }
8026            if (pi.uriPermissionPatterns != null) {
8027                final int N = pi.uriPermissionPatterns.length;
8028                boolean allowed = false;
8029                for (int i=0; i<N; i++) {
8030                    if (pi.uriPermissionPatterns[i] != null
8031                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8032                        allowed = true;
8033                        break;
8034                    }
8035                }
8036                if (!allowed) {
8037                    throw new SecurityException("Provider " + pi.packageName
8038                            + "/" + pi.name
8039                            + " does not allow granting of permission to path of Uri "
8040                            + grantUri);
8041                }
8042            }
8043        }
8044
8045        // Third...  does the caller itself have permission to access
8046        // this uri?
8047        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8048            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8049                // Require they hold a strong enough Uri permission
8050                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8051                    throw new SecurityException("Uid " + callingUid
8052                            + " does not have permission to uri " + grantUri);
8053                }
8054            }
8055        }
8056        return targetUid;
8057    }
8058
8059    /**
8060     * @param uri This uri must NOT contain an embedded userId.
8061     * @param userId The userId in which the uri is to be resolved.
8062     */
8063    @Override
8064    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8065            final int modeFlags, int userId) {
8066        enforceNotIsolatedCaller("checkGrantUriPermission");
8067        synchronized(this) {
8068            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8069                    new GrantUri(userId, uri, false), modeFlags, -1);
8070        }
8071    }
8072
8073    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8074            final int modeFlags, UriPermissionOwner owner) {
8075        if (!Intent.isAccessUriMode(modeFlags)) {
8076            return;
8077        }
8078
8079        // So here we are: the caller has the assumed permission
8080        // to the uri, and the target doesn't.  Let's now give this to
8081        // the target.
8082
8083        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8084                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8085
8086        final String authority = grantUri.uri.getAuthority();
8087        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8088                MATCH_DEBUG_TRIAGED_MISSING);
8089        if (pi == null) {
8090            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8091            return;
8092        }
8093
8094        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8095            grantUri.prefix = true;
8096        }
8097        final UriPermission perm = findOrCreateUriPermissionLocked(
8098                pi.packageName, targetPkg, targetUid, grantUri);
8099        perm.grantModes(modeFlags, owner);
8100    }
8101
8102    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8103            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8104        if (targetPkg == null) {
8105            throw new NullPointerException("targetPkg");
8106        }
8107        int targetUid;
8108        final IPackageManager pm = AppGlobals.getPackageManager();
8109        try {
8110            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8111        } catch (RemoteException ex) {
8112            return;
8113        }
8114
8115        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8116                targetUid);
8117        if (targetUid < 0) {
8118            return;
8119        }
8120
8121        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8122                owner);
8123    }
8124
8125    static class NeededUriGrants extends ArrayList<GrantUri> {
8126        final String targetPkg;
8127        final int targetUid;
8128        final int flags;
8129
8130        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8131            this.targetPkg = targetPkg;
8132            this.targetUid = targetUid;
8133            this.flags = flags;
8134        }
8135    }
8136
8137    /**
8138     * Like checkGrantUriPermissionLocked, but takes an Intent.
8139     */
8140    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8141            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8142        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8143                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8144                + " clip=" + (intent != null ? intent.getClipData() : null)
8145                + " from " + intent + "; flags=0x"
8146                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8147
8148        if (targetPkg == null) {
8149            throw new NullPointerException("targetPkg");
8150        }
8151
8152        if (intent == null) {
8153            return null;
8154        }
8155        Uri data = intent.getData();
8156        ClipData clip = intent.getClipData();
8157        if (data == null && clip == null) {
8158            return null;
8159        }
8160        // Default userId for uris in the intent (if they don't specify it themselves)
8161        int contentUserHint = intent.getContentUserHint();
8162        if (contentUserHint == UserHandle.USER_CURRENT) {
8163            contentUserHint = UserHandle.getUserId(callingUid);
8164        }
8165        final IPackageManager pm = AppGlobals.getPackageManager();
8166        int targetUid;
8167        if (needed != null) {
8168            targetUid = needed.targetUid;
8169        } else {
8170            try {
8171                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8172                        targetUserId);
8173            } catch (RemoteException ex) {
8174                return null;
8175            }
8176            if (targetUid < 0) {
8177                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8178                        "Can't grant URI permission no uid for: " + targetPkg
8179                        + " on user " + targetUserId);
8180                return null;
8181            }
8182        }
8183        if (data != null) {
8184            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8185            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8186                    targetUid);
8187            if (targetUid > 0) {
8188                if (needed == null) {
8189                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8190                }
8191                needed.add(grantUri);
8192            }
8193        }
8194        if (clip != null) {
8195            for (int i=0; i<clip.getItemCount(); i++) {
8196                Uri uri = clip.getItemAt(i).getUri();
8197                if (uri != null) {
8198                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8199                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8200                            targetUid);
8201                    if (targetUid > 0) {
8202                        if (needed == null) {
8203                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8204                        }
8205                        needed.add(grantUri);
8206                    }
8207                } else {
8208                    Intent clipIntent = clip.getItemAt(i).getIntent();
8209                    if (clipIntent != null) {
8210                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8211                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8212                        if (newNeeded != null) {
8213                            needed = newNeeded;
8214                        }
8215                    }
8216                }
8217            }
8218        }
8219
8220        return needed;
8221    }
8222
8223    /**
8224     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8225     */
8226    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8227            UriPermissionOwner owner) {
8228        if (needed != null) {
8229            for (int i=0; i<needed.size(); i++) {
8230                GrantUri grantUri = needed.get(i);
8231                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8232                        grantUri, needed.flags, owner);
8233            }
8234        }
8235    }
8236
8237    void grantUriPermissionFromIntentLocked(int callingUid,
8238            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8239        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8240                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8241        if (needed == null) {
8242            return;
8243        }
8244
8245        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8246    }
8247
8248    /**
8249     * @param uri This uri must NOT contain an embedded userId.
8250     * @param userId The userId in which the uri is to be resolved.
8251     */
8252    @Override
8253    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8254            final int modeFlags, int userId) {
8255        enforceNotIsolatedCaller("grantUriPermission");
8256        GrantUri grantUri = new GrantUri(userId, uri, false);
8257        synchronized(this) {
8258            final ProcessRecord r = getRecordForAppLocked(caller);
8259            if (r == null) {
8260                throw new SecurityException("Unable to find app for caller "
8261                        + caller
8262                        + " when granting permission to uri " + grantUri);
8263            }
8264            if (targetPkg == null) {
8265                throw new IllegalArgumentException("null target");
8266            }
8267            if (grantUri == null) {
8268                throw new IllegalArgumentException("null uri");
8269            }
8270
8271            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8272                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8273                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8274                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8275
8276            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8277                    UserHandle.getUserId(r.uid));
8278        }
8279    }
8280
8281    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8282        if (perm.modeFlags == 0) {
8283            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8284                    perm.targetUid);
8285            if (perms != null) {
8286                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8287                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8288
8289                perms.remove(perm.uri);
8290                if (perms.isEmpty()) {
8291                    mGrantedUriPermissions.remove(perm.targetUid);
8292                }
8293            }
8294        }
8295    }
8296
8297    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8298        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8299                "Revoking all granted permissions to " + grantUri);
8300
8301        final IPackageManager pm = AppGlobals.getPackageManager();
8302        final String authority = grantUri.uri.getAuthority();
8303        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8304                MATCH_DEBUG_TRIAGED_MISSING);
8305        if (pi == null) {
8306            Slog.w(TAG, "No content provider found for permission revoke: "
8307                    + grantUri.toSafeString());
8308            return;
8309        }
8310
8311        // Does the caller have this permission on the URI?
8312        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8313            // If they don't have direct access to the URI, then revoke any
8314            // ownerless URI permissions that have been granted to them.
8315            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8316            if (perms != null) {
8317                boolean persistChanged = false;
8318                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8319                    final UriPermission perm = it.next();
8320                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8321                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8322                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8323                                "Revoking non-owned " + perm.targetUid
8324                                + " permission to " + perm.uri);
8325                        persistChanged |= perm.revokeModes(
8326                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8327                        if (perm.modeFlags == 0) {
8328                            it.remove();
8329                        }
8330                    }
8331                }
8332                if (perms.isEmpty()) {
8333                    mGrantedUriPermissions.remove(callingUid);
8334                }
8335                if (persistChanged) {
8336                    schedulePersistUriGrants();
8337                }
8338            }
8339            return;
8340        }
8341
8342        boolean persistChanged = false;
8343
8344        // Go through all of the permissions and remove any that match.
8345        int N = mGrantedUriPermissions.size();
8346        for (int i = 0; i < N; i++) {
8347            final int targetUid = mGrantedUriPermissions.keyAt(i);
8348            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8349
8350            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8351                final UriPermission perm = it.next();
8352                if (perm.uri.sourceUserId == grantUri.sourceUserId
8353                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8354                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8355                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8356                    persistChanged |= perm.revokeModes(
8357                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8358                    if (perm.modeFlags == 0) {
8359                        it.remove();
8360                    }
8361                }
8362            }
8363
8364            if (perms.isEmpty()) {
8365                mGrantedUriPermissions.remove(targetUid);
8366                N--;
8367                i--;
8368            }
8369        }
8370
8371        if (persistChanged) {
8372            schedulePersistUriGrants();
8373        }
8374    }
8375
8376    /**
8377     * @param uri This uri must NOT contain an embedded userId.
8378     * @param userId The userId in which the uri is to be resolved.
8379     */
8380    @Override
8381    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8382            int userId) {
8383        enforceNotIsolatedCaller("revokeUriPermission");
8384        synchronized(this) {
8385            final ProcessRecord r = getRecordForAppLocked(caller);
8386            if (r == null) {
8387                throw new SecurityException("Unable to find app for caller "
8388                        + caller
8389                        + " when revoking permission to uri " + uri);
8390            }
8391            if (uri == null) {
8392                Slog.w(TAG, "revokeUriPermission: null uri");
8393                return;
8394            }
8395
8396            if (!Intent.isAccessUriMode(modeFlags)) {
8397                return;
8398            }
8399
8400            final String authority = uri.getAuthority();
8401            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8402                    MATCH_DEBUG_TRIAGED_MISSING);
8403            if (pi == null) {
8404                Slog.w(TAG, "No content provider found for permission revoke: "
8405                        + uri.toSafeString());
8406                return;
8407            }
8408
8409            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8410        }
8411    }
8412
8413    /**
8414     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8415     * given package.
8416     *
8417     * @param packageName Package name to match, or {@code null} to apply to all
8418     *            packages.
8419     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8420     *            to all users.
8421     * @param persistable If persistable grants should be removed.
8422     */
8423    private void removeUriPermissionsForPackageLocked(
8424            String packageName, int userHandle, boolean persistable) {
8425        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8426            throw new IllegalArgumentException("Must narrow by either package or user");
8427        }
8428
8429        boolean persistChanged = false;
8430
8431        int N = mGrantedUriPermissions.size();
8432        for (int i = 0; i < N; i++) {
8433            final int targetUid = mGrantedUriPermissions.keyAt(i);
8434            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8435
8436            // Only inspect grants matching user
8437            if (userHandle == UserHandle.USER_ALL
8438                    || userHandle == UserHandle.getUserId(targetUid)) {
8439                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8440                    final UriPermission perm = it.next();
8441
8442                    // Only inspect grants matching package
8443                    if (packageName == null || perm.sourcePkg.equals(packageName)
8444                            || perm.targetPkg.equals(packageName)) {
8445                        persistChanged |= perm.revokeModes(persistable
8446                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8447
8448                        // Only remove when no modes remain; any persisted grants
8449                        // will keep this alive.
8450                        if (perm.modeFlags == 0) {
8451                            it.remove();
8452                        }
8453                    }
8454                }
8455
8456                if (perms.isEmpty()) {
8457                    mGrantedUriPermissions.remove(targetUid);
8458                    N--;
8459                    i--;
8460                }
8461            }
8462        }
8463
8464        if (persistChanged) {
8465            schedulePersistUriGrants();
8466        }
8467    }
8468
8469    @Override
8470    public IBinder newUriPermissionOwner(String name) {
8471        enforceNotIsolatedCaller("newUriPermissionOwner");
8472        synchronized(this) {
8473            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8474            return owner.getExternalTokenLocked();
8475        }
8476    }
8477
8478    @Override
8479    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8480        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8481        synchronized(this) {
8482            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8483            if (r == null) {
8484                throw new IllegalArgumentException("Activity does not exist; token="
8485                        + activityToken);
8486            }
8487            return r.getUriPermissionsLocked().getExternalTokenLocked();
8488        }
8489    }
8490    /**
8491     * @param uri This uri must NOT contain an embedded userId.
8492     * @param sourceUserId The userId in which the uri is to be resolved.
8493     * @param targetUserId The userId of the app that receives the grant.
8494     */
8495    @Override
8496    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8497            final int modeFlags, int sourceUserId, int targetUserId) {
8498        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8499                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8500                "grantUriPermissionFromOwner", null);
8501        synchronized(this) {
8502            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8503            if (owner == null) {
8504                throw new IllegalArgumentException("Unknown owner: " + token);
8505            }
8506            if (fromUid != Binder.getCallingUid()) {
8507                if (Binder.getCallingUid() != Process.myUid()) {
8508                    // Only system code can grant URI permissions on behalf
8509                    // of other users.
8510                    throw new SecurityException("nice try");
8511                }
8512            }
8513            if (targetPkg == null) {
8514                throw new IllegalArgumentException("null target");
8515            }
8516            if (uri == null) {
8517                throw new IllegalArgumentException("null uri");
8518            }
8519
8520            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8521                    modeFlags, owner, targetUserId);
8522        }
8523    }
8524
8525    /**
8526     * @param uri This uri must NOT contain an embedded userId.
8527     * @param userId The userId in which the uri is to be resolved.
8528     */
8529    @Override
8530    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8531        synchronized(this) {
8532            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8533            if (owner == null) {
8534                throw new IllegalArgumentException("Unknown owner: " + token);
8535            }
8536
8537            if (uri == null) {
8538                owner.removeUriPermissionsLocked(mode);
8539            } else {
8540                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8541            }
8542        }
8543    }
8544
8545    private void schedulePersistUriGrants() {
8546        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8547            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8548                    10 * DateUtils.SECOND_IN_MILLIS);
8549        }
8550    }
8551
8552    private void writeGrantedUriPermissions() {
8553        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8554
8555        // Snapshot permissions so we can persist without lock
8556        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8557        synchronized (this) {
8558            final int size = mGrantedUriPermissions.size();
8559            for (int i = 0; i < size; i++) {
8560                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8561                for (UriPermission perm : perms.values()) {
8562                    if (perm.persistedModeFlags != 0) {
8563                        persist.add(perm.snapshot());
8564                    }
8565                }
8566            }
8567        }
8568
8569        FileOutputStream fos = null;
8570        try {
8571            fos = mGrantFile.startWrite();
8572
8573            XmlSerializer out = new FastXmlSerializer();
8574            out.setOutput(fos, StandardCharsets.UTF_8.name());
8575            out.startDocument(null, true);
8576            out.startTag(null, TAG_URI_GRANTS);
8577            for (UriPermission.Snapshot perm : persist) {
8578                out.startTag(null, TAG_URI_GRANT);
8579                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8580                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8581                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8582                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8583                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8584                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8585                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8586                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8587                out.endTag(null, TAG_URI_GRANT);
8588            }
8589            out.endTag(null, TAG_URI_GRANTS);
8590            out.endDocument();
8591
8592            mGrantFile.finishWrite(fos);
8593        } catch (IOException e) {
8594            if (fos != null) {
8595                mGrantFile.failWrite(fos);
8596            }
8597        }
8598    }
8599
8600    private void readGrantedUriPermissionsLocked() {
8601        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8602
8603        final long now = System.currentTimeMillis();
8604
8605        FileInputStream fis = null;
8606        try {
8607            fis = mGrantFile.openRead();
8608            final XmlPullParser in = Xml.newPullParser();
8609            in.setInput(fis, StandardCharsets.UTF_8.name());
8610
8611            int type;
8612            while ((type = in.next()) != END_DOCUMENT) {
8613                final String tag = in.getName();
8614                if (type == START_TAG) {
8615                    if (TAG_URI_GRANT.equals(tag)) {
8616                        final int sourceUserId;
8617                        final int targetUserId;
8618                        final int userHandle = readIntAttribute(in,
8619                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8620                        if (userHandle != UserHandle.USER_NULL) {
8621                            // For backwards compatibility.
8622                            sourceUserId = userHandle;
8623                            targetUserId = userHandle;
8624                        } else {
8625                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8626                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8627                        }
8628                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8629                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8630                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8631                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8632                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8633                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8634
8635                        // Sanity check that provider still belongs to source package
8636                        // Both direct boot aware and unaware packages are fine as we
8637                        // will do filtering at query time to avoid multiple parsing.
8638                        final ProviderInfo pi = getProviderInfoLocked(
8639                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8640                                        | MATCH_DIRECT_BOOT_UNAWARE);
8641                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8642                            int targetUid = -1;
8643                            try {
8644                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8645                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8646                            } catch (RemoteException e) {
8647                            }
8648                            if (targetUid != -1) {
8649                                final UriPermission perm = findOrCreateUriPermissionLocked(
8650                                        sourcePkg, targetPkg, targetUid,
8651                                        new GrantUri(sourceUserId, uri, prefix));
8652                                perm.initPersistedModes(modeFlags, createdTime);
8653                            }
8654                        } else {
8655                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8656                                    + " but instead found " + pi);
8657                        }
8658                    }
8659                }
8660            }
8661        } catch (FileNotFoundException e) {
8662            // Missing grants is okay
8663        } catch (IOException e) {
8664            Slog.wtf(TAG, "Failed reading Uri grants", e);
8665        } catch (XmlPullParserException e) {
8666            Slog.wtf(TAG, "Failed reading Uri grants", e);
8667        } finally {
8668            IoUtils.closeQuietly(fis);
8669        }
8670    }
8671
8672    /**
8673     * @param uri This uri must NOT contain an embedded userId.
8674     * @param userId The userId in which the uri is to be resolved.
8675     */
8676    @Override
8677    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8678        enforceNotIsolatedCaller("takePersistableUriPermission");
8679
8680        Preconditions.checkFlagsArgument(modeFlags,
8681                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8682
8683        synchronized (this) {
8684            final int callingUid = Binder.getCallingUid();
8685            boolean persistChanged = false;
8686            GrantUri grantUri = new GrantUri(userId, uri, false);
8687
8688            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8689                    new GrantUri(userId, uri, false));
8690            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8691                    new GrantUri(userId, uri, true));
8692
8693            final boolean exactValid = (exactPerm != null)
8694                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8695            final boolean prefixValid = (prefixPerm != null)
8696                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8697
8698            if (!(exactValid || prefixValid)) {
8699                throw new SecurityException("No persistable permission grants found for UID "
8700                        + callingUid + " and Uri " + grantUri.toSafeString());
8701            }
8702
8703            if (exactValid) {
8704                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8705            }
8706            if (prefixValid) {
8707                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8708            }
8709
8710            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8711
8712            if (persistChanged) {
8713                schedulePersistUriGrants();
8714            }
8715        }
8716    }
8717
8718    /**
8719     * @param uri This uri must NOT contain an embedded userId.
8720     * @param userId The userId in which the uri is to be resolved.
8721     */
8722    @Override
8723    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8724        enforceNotIsolatedCaller("releasePersistableUriPermission");
8725
8726        Preconditions.checkFlagsArgument(modeFlags,
8727                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8728
8729        synchronized (this) {
8730            final int callingUid = Binder.getCallingUid();
8731            boolean persistChanged = false;
8732
8733            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8734                    new GrantUri(userId, uri, false));
8735            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8736                    new GrantUri(userId, uri, true));
8737            if (exactPerm == null && prefixPerm == null) {
8738                throw new SecurityException("No permission grants found for UID " + callingUid
8739                        + " and Uri " + uri.toSafeString());
8740            }
8741
8742            if (exactPerm != null) {
8743                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8744                removeUriPermissionIfNeededLocked(exactPerm);
8745            }
8746            if (prefixPerm != null) {
8747                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8748                removeUriPermissionIfNeededLocked(prefixPerm);
8749            }
8750
8751            if (persistChanged) {
8752                schedulePersistUriGrants();
8753            }
8754        }
8755    }
8756
8757    /**
8758     * Prune any older {@link UriPermission} for the given UID until outstanding
8759     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8760     *
8761     * @return if any mutations occured that require persisting.
8762     */
8763    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8764        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8765        if (perms == null) return false;
8766        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8767
8768        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8769        for (UriPermission perm : perms.values()) {
8770            if (perm.persistedModeFlags != 0) {
8771                persisted.add(perm);
8772            }
8773        }
8774
8775        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8776        if (trimCount <= 0) return false;
8777
8778        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8779        for (int i = 0; i < trimCount; i++) {
8780            final UriPermission perm = persisted.get(i);
8781
8782            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8783                    "Trimming grant created at " + perm.persistedCreateTime);
8784
8785            perm.releasePersistableModes(~0);
8786            removeUriPermissionIfNeededLocked(perm);
8787        }
8788
8789        return true;
8790    }
8791
8792    @Override
8793    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8794            String packageName, boolean incoming) {
8795        enforceNotIsolatedCaller("getPersistedUriPermissions");
8796        Preconditions.checkNotNull(packageName, "packageName");
8797
8798        final int callingUid = Binder.getCallingUid();
8799        final IPackageManager pm = AppGlobals.getPackageManager();
8800        try {
8801            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8802                    UserHandle.getUserId(callingUid));
8803            if (packageUid != callingUid) {
8804                throw new SecurityException(
8805                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8806            }
8807        } catch (RemoteException e) {
8808            throw new SecurityException("Failed to verify package name ownership");
8809        }
8810
8811        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8812        synchronized (this) {
8813            if (incoming) {
8814                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8815                        callingUid);
8816                if (perms == null) {
8817                    Slog.w(TAG, "No permission grants found for " + packageName);
8818                } else {
8819                    final int userId = UserHandle.getUserId(callingUid);
8820                    Set<String> existingAuthorities = null;
8821
8822                    for (UriPermission perm : perms.values()) {
8823                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8824                            // Is this provider available in the current boot state? If the user
8825                            // is not running and unlocked we check if the provider package exists.
8826                            if (!mUserController.isUserRunningLocked(userId,
8827                                    ActivityManager.FLAG_AND_UNLOCKED)) {
8828                                String authority = perm.uri.uri.getAuthority();
8829                                if (existingAuthorities == null
8830                                        || !existingAuthorities.contains(authority)) {
8831                                    ProviderInfo providerInfo = getProviderInfoLocked(authority,
8832                                            userId, MATCH_DEBUG_TRIAGED_MISSING);
8833                                    if (providerInfo != null) {
8834                                        if (existingAuthorities == null) {
8835                                            existingAuthorities = new ArraySet<>();
8836                                        }
8837                                        existingAuthorities.add(authority);
8838                                    } else {
8839                                        continue;
8840                                    }
8841                                }
8842                            }
8843                            result.add(perm.buildPersistedPublicApiObject());
8844                        }
8845                    }
8846                }
8847            } else {
8848                final int size = mGrantedUriPermissions.size();
8849                for (int i = 0; i < size; i++) {
8850                    final ArrayMap<GrantUri, UriPermission> perms =
8851                            mGrantedUriPermissions.valueAt(i);
8852                    for (UriPermission perm : perms.values()) {
8853                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8854                            result.add(perm.buildPersistedPublicApiObject());
8855                        }
8856                    }
8857                }
8858            }
8859        }
8860        return new ParceledListSlice<android.content.UriPermission>(result);
8861    }
8862
8863    @Override
8864    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8865            String packageName, int userId) {
8866        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8867                "getGrantedUriPermissions");
8868
8869        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8870        synchronized (this) {
8871            final int size = mGrantedUriPermissions.size();
8872            for (int i = 0; i < size; i++) {
8873                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8874                for (UriPermission perm : perms.values()) {
8875                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8876                            && perm.persistedModeFlags != 0) {
8877                        result.add(perm.buildPersistedPublicApiObject());
8878                    }
8879                }
8880            }
8881        }
8882        return new ParceledListSlice<android.content.UriPermission>(result);
8883    }
8884
8885    @Override
8886    public void clearGrantedUriPermissions(String packageName, int userId) {
8887        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8888                "clearGrantedUriPermissions");
8889        removeUriPermissionsForPackageLocked(packageName, userId, true);
8890    }
8891
8892    @Override
8893    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8894        synchronized (this) {
8895            ProcessRecord app =
8896                who != null ? getRecordForAppLocked(who) : null;
8897            if (app == null) return;
8898
8899            Message msg = Message.obtain();
8900            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8901            msg.obj = app;
8902            msg.arg1 = waiting ? 1 : 0;
8903            mUiHandler.sendMessage(msg);
8904        }
8905    }
8906
8907    @Override
8908    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8909        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8910        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8911        outInfo.availMem = Process.getFreeMemory();
8912        outInfo.totalMem = Process.getTotalMemory();
8913        outInfo.threshold = homeAppMem;
8914        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8915        outInfo.hiddenAppThreshold = cachedAppMem;
8916        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8917                ProcessList.SERVICE_ADJ);
8918        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8919                ProcessList.VISIBLE_APP_ADJ);
8920        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8921                ProcessList.FOREGROUND_APP_ADJ);
8922    }
8923
8924    // =========================================================
8925    // TASK MANAGEMENT
8926    // =========================================================
8927
8928    @Override
8929    public List<IAppTask> getAppTasks(String callingPackage) {
8930        int callingUid = Binder.getCallingUid();
8931        long ident = Binder.clearCallingIdentity();
8932
8933        synchronized(this) {
8934            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8935            try {
8936                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8937
8938                final int N = mRecentTasks.size();
8939                for (int i = 0; i < N; i++) {
8940                    TaskRecord tr = mRecentTasks.get(i);
8941                    // Skip tasks that do not match the caller.  We don't need to verify
8942                    // callingPackage, because we are also limiting to callingUid and know
8943                    // that will limit to the correct security sandbox.
8944                    if (tr.effectiveUid != callingUid) {
8945                        continue;
8946                    }
8947                    Intent intent = tr.getBaseIntent();
8948                    if (intent == null ||
8949                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8950                        continue;
8951                    }
8952                    ActivityManager.RecentTaskInfo taskInfo =
8953                            createRecentTaskInfoFromTaskRecord(tr);
8954                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8955                    list.add(taskImpl);
8956                }
8957            } finally {
8958                Binder.restoreCallingIdentity(ident);
8959            }
8960            return list;
8961        }
8962    }
8963
8964    @Override
8965    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8966        final int callingUid = Binder.getCallingUid();
8967        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8968
8969        synchronized(this) {
8970            if (DEBUG_ALL) Slog.v(
8971                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8972
8973            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8974                    callingUid);
8975
8976            // TODO: Improve with MRU list from all ActivityStacks.
8977            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8978        }
8979
8980        return list;
8981    }
8982
8983    /**
8984     * Creates a new RecentTaskInfo from a TaskRecord.
8985     */
8986    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8987        // Update the task description to reflect any changes in the task stack
8988        tr.updateTaskDescription();
8989
8990        // Compose the recent task info
8991        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8992        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8993        rti.persistentId = tr.taskId;
8994        rti.baseIntent = new Intent(tr.getBaseIntent());
8995        rti.origActivity = tr.origActivity;
8996        rti.realActivity = tr.realActivity;
8997        rti.description = tr.lastDescription;
8998        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8999        rti.userId = tr.userId;
9000        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9001        rti.firstActiveTime = tr.firstActiveTime;
9002        rti.lastActiveTime = tr.lastActiveTime;
9003        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9004        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9005        rti.numActivities = 0;
9006        if (tr.mBounds != null) {
9007            rti.bounds = new Rect(tr.mBounds);
9008        }
9009        rti.isDockable = tr.canGoInDockedStack();
9010        rti.resizeMode = tr.mResizeMode;
9011
9012        ActivityRecord base = null;
9013        ActivityRecord top = null;
9014        ActivityRecord tmp;
9015
9016        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9017            tmp = tr.mActivities.get(i);
9018            if (tmp.finishing) {
9019                continue;
9020            }
9021            base = tmp;
9022            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9023                top = base;
9024            }
9025            rti.numActivities++;
9026        }
9027
9028        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9029        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9030
9031        return rti;
9032    }
9033
9034    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9035        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9036                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9037        if (!allowed) {
9038            if (checkPermission(android.Manifest.permission.GET_TASKS,
9039                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9040                // Temporary compatibility: some existing apps on the system image may
9041                // still be requesting the old permission and not switched to the new
9042                // one; if so, we'll still allow them full access.  This means we need
9043                // to see if they are holding the old permission and are a system app.
9044                try {
9045                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9046                        allowed = true;
9047                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9048                                + " is using old GET_TASKS but privileged; allowing");
9049                    }
9050                } catch (RemoteException e) {
9051                }
9052            }
9053        }
9054        if (!allowed) {
9055            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9056                    + " does not hold REAL_GET_TASKS; limiting output");
9057        }
9058        return allowed;
9059    }
9060
9061    @Override
9062    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9063        final int callingUid = Binder.getCallingUid();
9064        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9065                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9066
9067        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9068        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9069        synchronized (this) {
9070            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9071                    callingUid);
9072            final boolean detailed = checkCallingPermission(
9073                    android.Manifest.permission.GET_DETAILED_TASKS)
9074                    == PackageManager.PERMISSION_GRANTED;
9075
9076            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9077                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9078                return Collections.emptyList();
9079            }
9080            mRecentTasks.loadUserRecentsLocked(userId);
9081
9082            final int recentsCount = mRecentTasks.size();
9083            ArrayList<ActivityManager.RecentTaskInfo> res =
9084                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9085
9086            final Set<Integer> includedUsers;
9087            if (includeProfiles) {
9088                includedUsers = mUserController.getProfileIds(userId);
9089            } else {
9090                includedUsers = new HashSet<>();
9091            }
9092            includedUsers.add(Integer.valueOf(userId));
9093
9094            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9095                TaskRecord tr = mRecentTasks.get(i);
9096                // Only add calling user or related users recent tasks
9097                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9098                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9099                    continue;
9100                }
9101
9102                if (tr.realActivitySuspended) {
9103                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9104                    continue;
9105                }
9106
9107                // Return the entry if desired by the caller.  We always return
9108                // the first entry, because callers always expect this to be the
9109                // foreground app.  We may filter others if the caller has
9110                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9111                // we should exclude the entry.
9112
9113                if (i == 0
9114                        || withExcluded
9115                        || (tr.intent == null)
9116                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9117                                == 0)) {
9118                    if (!allowed) {
9119                        // If the caller doesn't have the GET_TASKS permission, then only
9120                        // allow them to see a small subset of tasks -- their own and home.
9121                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9122                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9123                            continue;
9124                        }
9125                    }
9126                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9127                        if (tr.stack != null && tr.stack.isHomeStack()) {
9128                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9129                                    "Skipping, home stack task: " + tr);
9130                            continue;
9131                        }
9132                    }
9133                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9134                        final ActivityStack stack = tr.stack;
9135                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9136                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9137                                    "Skipping, top task in docked stack: " + tr);
9138                            continue;
9139                        }
9140                    }
9141                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9142                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9143                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9144                                    "Skipping, pinned stack task: " + tr);
9145                            continue;
9146                        }
9147                    }
9148                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9149                        // Don't include auto remove tasks that are finished or finishing.
9150                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9151                                "Skipping, auto-remove without activity: " + tr);
9152                        continue;
9153                    }
9154                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9155                            && !tr.isAvailable) {
9156                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9157                                "Skipping, unavail real act: " + tr);
9158                        continue;
9159                    }
9160
9161                    if (!tr.mUserSetupComplete) {
9162                        // Don't include task launched while user is not done setting-up.
9163                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9164                                "Skipping, user setup not complete: " + tr);
9165                        continue;
9166                    }
9167
9168                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9169                    if (!detailed) {
9170                        rti.baseIntent.replaceExtras((Bundle)null);
9171                    }
9172
9173                    res.add(rti);
9174                    maxNum--;
9175                }
9176            }
9177            return res;
9178        }
9179    }
9180
9181    @Override
9182    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9183        synchronized (this) {
9184            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9185                    "getTaskThumbnail()");
9186            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9187                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9188            if (tr != null) {
9189                return tr.getTaskThumbnailLocked();
9190            }
9191        }
9192        return null;
9193    }
9194
9195    @Override
9196    public int addAppTask(IBinder activityToken, Intent intent,
9197            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9198        final int callingUid = Binder.getCallingUid();
9199        final long callingIdent = Binder.clearCallingIdentity();
9200
9201        try {
9202            synchronized (this) {
9203                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9204                if (r == null) {
9205                    throw new IllegalArgumentException("Activity does not exist; token="
9206                            + activityToken);
9207                }
9208                ComponentName comp = intent.getComponent();
9209                if (comp == null) {
9210                    throw new IllegalArgumentException("Intent " + intent
9211                            + " must specify explicit component");
9212                }
9213                if (thumbnail.getWidth() != mThumbnailWidth
9214                        || thumbnail.getHeight() != mThumbnailHeight) {
9215                    throw new IllegalArgumentException("Bad thumbnail size: got "
9216                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9217                            + mThumbnailWidth + "x" + mThumbnailHeight);
9218                }
9219                if (intent.getSelector() != null) {
9220                    intent.setSelector(null);
9221                }
9222                if (intent.getSourceBounds() != null) {
9223                    intent.setSourceBounds(null);
9224                }
9225                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9226                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9227                        // The caller has added this as an auto-remove task...  that makes no
9228                        // sense, so turn off auto-remove.
9229                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9230                    }
9231                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9232                    // Must be a new task.
9233                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9234                }
9235                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9236                    mLastAddedTaskActivity = null;
9237                }
9238                ActivityInfo ainfo = mLastAddedTaskActivity;
9239                if (ainfo == null) {
9240                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9241                            comp, 0, UserHandle.getUserId(callingUid));
9242                    if (ainfo.applicationInfo.uid != callingUid) {
9243                        throw new SecurityException(
9244                                "Can't add task for another application: target uid="
9245                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9246                    }
9247                }
9248
9249                // Use the full screen as the context for the task thumbnail
9250                final Point displaySize = new Point();
9251                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9252                r.task.stack.getDisplaySize(displaySize);
9253                thumbnailInfo.taskWidth = displaySize.x;
9254                thumbnailInfo.taskHeight = displaySize.y;
9255                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9256
9257                TaskRecord task = new TaskRecord(this,
9258                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9259                        ainfo, intent, description, thumbnailInfo);
9260
9261                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9262                if (trimIdx >= 0) {
9263                    // If this would have caused a trim, then we'll abort because that
9264                    // means it would be added at the end of the list but then just removed.
9265                    return INVALID_TASK_ID;
9266                }
9267
9268                final int N = mRecentTasks.size();
9269                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9270                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9271                    tr.removedFromRecents();
9272                }
9273
9274                task.inRecents = true;
9275                mRecentTasks.add(task);
9276                r.task.stack.addTask(task, false, "addAppTask");
9277
9278                task.setLastThumbnailLocked(thumbnail);
9279                task.freeLastThumbnail();
9280
9281                return task.taskId;
9282            }
9283        } finally {
9284            Binder.restoreCallingIdentity(callingIdent);
9285        }
9286    }
9287
9288    @Override
9289    public Point getAppTaskThumbnailSize() {
9290        synchronized (this) {
9291            return new Point(mThumbnailWidth,  mThumbnailHeight);
9292        }
9293    }
9294
9295    @Override
9296    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9297        synchronized (this) {
9298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9299            if (r != null) {
9300                r.setTaskDescription(td);
9301                r.task.updateTaskDescription();
9302            }
9303        }
9304    }
9305
9306    @Override
9307    public void setTaskResizeable(int taskId, int resizeableMode) {
9308        synchronized (this) {
9309            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9310                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9311            if (task == null) {
9312                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9313                return;
9314            }
9315            if (task.mResizeMode != resizeableMode) {
9316                task.mResizeMode = resizeableMode;
9317                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9318                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9319                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9320            }
9321        }
9322    }
9323
9324    @Override
9325    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9326        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9327        long ident = Binder.clearCallingIdentity();
9328        try {
9329            synchronized (this) {
9330                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9331                if (task == null) {
9332                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9333                    return;
9334                }
9335                int stackId = task.stack.mStackId;
9336                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9337                // in crop windows resize mode or if the task size is affected by the docked stack
9338                // changing size. No need to update configuration.
9339                if (bounds != null && task.inCropWindowsResizeMode()
9340                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9341                    mWindowManager.scrollTask(task.taskId, bounds);
9342                    return;
9343                }
9344
9345                // Place the task in the right stack if it isn't there already based on
9346                // the requested bounds.
9347                // The stack transition logic is:
9348                // - a null bounds on a freeform task moves that task to fullscreen
9349                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9350                //   that task to freeform
9351                // - otherwise the task is not moved
9352                if (!StackId.isTaskResizeAllowed(stackId)) {
9353                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9354                }
9355                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9356                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9357                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9358                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9359                }
9360                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9361                if (stackId != task.stack.mStackId) {
9362                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9363                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9364                    preserveWindow = false;
9365                }
9366
9367                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9368                        false /* deferResume */);
9369            }
9370        } finally {
9371            Binder.restoreCallingIdentity(ident);
9372        }
9373    }
9374
9375    @Override
9376    public Rect getTaskBounds(int taskId) {
9377        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9378        long ident = Binder.clearCallingIdentity();
9379        Rect rect = new Rect();
9380        try {
9381            synchronized (this) {
9382                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9383                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9384                if (task == null) {
9385                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9386                    return rect;
9387                }
9388                if (task.stack != null) {
9389                    // Return the bounds from window manager since it will be adjusted for various
9390                    // things like the presense of a docked stack for tasks that aren't resizeable.
9391                    mWindowManager.getTaskBounds(task.taskId, rect);
9392                } else {
9393                    // Task isn't in window manager yet since it isn't associated with a stack.
9394                    // Return the persist value from activity manager
9395                    if (task.mBounds != null) {
9396                        rect.set(task.mBounds);
9397                    } else if (task.mLastNonFullscreenBounds != null) {
9398                        rect.set(task.mLastNonFullscreenBounds);
9399                    }
9400                }
9401            }
9402        } finally {
9403            Binder.restoreCallingIdentity(ident);
9404        }
9405        return rect;
9406    }
9407
9408    @Override
9409    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9410        if (userId != UserHandle.getCallingUserId()) {
9411            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9412                    "getTaskDescriptionIcon");
9413        }
9414        final File passedIconFile = new File(filePath);
9415        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9416                passedIconFile.getName());
9417        if (!legitIconFile.getPath().equals(filePath)
9418                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9419            throw new IllegalArgumentException("Bad file path: " + filePath
9420                    + " passed for userId " + userId);
9421        }
9422        return mRecentTasks.getTaskDescriptionIcon(filePath);
9423    }
9424
9425    @Override
9426    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9427            throws RemoteException {
9428        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9429                opts.getCustomInPlaceResId() == 0) {
9430            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9431                    "with valid animation");
9432        }
9433        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9434        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9435                opts.getCustomInPlaceResId());
9436        mWindowManager.executeAppTransition();
9437    }
9438
9439    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9440            boolean removeFromRecents) {
9441        if (removeFromRecents) {
9442            mRecentTasks.remove(tr);
9443            tr.removedFromRecents();
9444        }
9445        ComponentName component = tr.getBaseIntent().getComponent();
9446        if (component == null) {
9447            Slog.w(TAG, "No component for base intent of task: " + tr);
9448            return;
9449        }
9450
9451        // Find any running services associated with this app and stop if needed.
9452        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9453
9454        if (!killProcess) {
9455            return;
9456        }
9457
9458        // Determine if the process(es) for this task should be killed.
9459        final String pkg = component.getPackageName();
9460        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9461        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9462        for (int i = 0; i < pmap.size(); i++) {
9463
9464            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9465            for (int j = 0; j < uids.size(); j++) {
9466                ProcessRecord proc = uids.valueAt(j);
9467                if (proc.userId != tr.userId) {
9468                    // Don't kill process for a different user.
9469                    continue;
9470                }
9471                if (proc == mHomeProcess) {
9472                    // Don't kill the home process along with tasks from the same package.
9473                    continue;
9474                }
9475                if (!proc.pkgList.containsKey(pkg)) {
9476                    // Don't kill process that is not associated with this task.
9477                    continue;
9478                }
9479
9480                for (int k = 0; k < proc.activities.size(); k++) {
9481                    TaskRecord otherTask = proc.activities.get(k).task;
9482                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9483                        // Don't kill process(es) that has an activity in a different task that is
9484                        // also in recents.
9485                        return;
9486                    }
9487                }
9488
9489                if (proc.foregroundServices) {
9490                    // Don't kill process(es) with foreground service.
9491                    return;
9492                }
9493
9494                // Add process to kill list.
9495                procsToKill.add(proc);
9496            }
9497        }
9498
9499        // Kill the running processes.
9500        for (int i = 0; i < procsToKill.size(); i++) {
9501            ProcessRecord pr = procsToKill.get(i);
9502            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9503                    && pr.curReceiver == null) {
9504                pr.kill("remove task", true);
9505            } else {
9506                // We delay killing processes that are not in the background or running a receiver.
9507                pr.waitingToKill = "remove task";
9508            }
9509        }
9510    }
9511
9512    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9513        // Remove all tasks with activities in the specified package from the list of recent tasks
9514        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9515            TaskRecord tr = mRecentTasks.get(i);
9516            if (tr.userId != userId) continue;
9517
9518            ComponentName cn = tr.intent.getComponent();
9519            if (cn != null && cn.getPackageName().equals(packageName)) {
9520                // If the package name matches, remove the task.
9521                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9522            }
9523        }
9524    }
9525
9526    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9527            int userId) {
9528
9529        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9530            TaskRecord tr = mRecentTasks.get(i);
9531            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9532                continue;
9533            }
9534
9535            ComponentName cn = tr.intent.getComponent();
9536            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9537                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9538            if (sameComponent) {
9539                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9540            }
9541        }
9542    }
9543
9544    /**
9545     * Removes the task with the specified task id.
9546     *
9547     * @param taskId Identifier of the task to be removed.
9548     * @param killProcess Kill any process associated with the task if possible.
9549     * @param removeFromRecents Whether to also remove the task from recents.
9550     * @return Returns true if the given task was found and removed.
9551     */
9552    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9553            boolean removeFromRecents) {
9554        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9555                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9556        if (tr != null) {
9557            tr.removeTaskActivitiesLocked();
9558            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9559            if (tr.isPersistable) {
9560                notifyTaskPersisterLocked(null, true);
9561            }
9562            return true;
9563        }
9564        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9565        return false;
9566    }
9567
9568    @Override
9569    public void removeStack(int stackId) {
9570        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9571        if (stackId == HOME_STACK_ID) {
9572            throw new IllegalArgumentException("Removing home stack is not allowed.");
9573        }
9574
9575        synchronized (this) {
9576            final long ident = Binder.clearCallingIdentity();
9577            try {
9578                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9579                if (stack == null) {
9580                    return;
9581                }
9582                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9583                for (int i = tasks.size() - 1; i >= 0; i--) {
9584                    removeTaskByIdLocked(
9585                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9586                }
9587            } finally {
9588                Binder.restoreCallingIdentity(ident);
9589            }
9590        }
9591    }
9592
9593    @Override
9594    public boolean removeTask(int taskId) {
9595        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9596        synchronized (this) {
9597            final long ident = Binder.clearCallingIdentity();
9598            try {
9599                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9600            } finally {
9601                Binder.restoreCallingIdentity(ident);
9602            }
9603        }
9604    }
9605
9606    /**
9607     * TODO: Add mController hook
9608     */
9609    @Override
9610    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9611        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9612
9613        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9614        synchronized(this) {
9615            moveTaskToFrontLocked(taskId, flags, bOptions);
9616        }
9617    }
9618
9619    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9620        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9621
9622        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9623                Binder.getCallingUid(), -1, -1, "Task to front")) {
9624            ActivityOptions.abort(options);
9625            return;
9626        }
9627        final long origId = Binder.clearCallingIdentity();
9628        try {
9629            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9630            if (task == null) {
9631                Slog.d(TAG, "Could not find task for id: "+ taskId);
9632                return;
9633            }
9634            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9635                mStackSupervisor.showLockTaskToast();
9636                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9637                return;
9638            }
9639            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9640            if (prev != null && prev.isRecentsActivity()) {
9641                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9642            }
9643            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9644                    false /* forceNonResizable */);
9645        } finally {
9646            Binder.restoreCallingIdentity(origId);
9647        }
9648        ActivityOptions.abort(options);
9649    }
9650
9651    /**
9652     * Moves an activity, and all of the other activities within the same task, to the bottom
9653     * of the history stack.  The activity's order within the task is unchanged.
9654     *
9655     * @param token A reference to the activity we wish to move
9656     * @param nonRoot If false then this only works if the activity is the root
9657     *                of a task; if true it will work for any activity in a task.
9658     * @return Returns true if the move completed, false if not.
9659     */
9660    @Override
9661    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9662        enforceNotIsolatedCaller("moveActivityTaskToBack");
9663        synchronized(this) {
9664            final long origId = Binder.clearCallingIdentity();
9665            try {
9666                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9667                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9668                if (task != null) {
9669                    if (mStackSupervisor.isLockedTask(task)) {
9670                        mStackSupervisor.showLockTaskToast();
9671                        return false;
9672                    }
9673                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9674                }
9675            } finally {
9676                Binder.restoreCallingIdentity(origId);
9677            }
9678        }
9679        return false;
9680    }
9681
9682    @Override
9683    public void moveTaskBackwards(int task) {
9684        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9685                "moveTaskBackwards()");
9686
9687        synchronized(this) {
9688            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9689                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9690                return;
9691            }
9692            final long origId = Binder.clearCallingIdentity();
9693            moveTaskBackwardsLocked(task);
9694            Binder.restoreCallingIdentity(origId);
9695        }
9696    }
9697
9698    private final void moveTaskBackwardsLocked(int task) {
9699        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9700    }
9701
9702    @Override
9703    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9704            IActivityContainerCallback callback) throws RemoteException {
9705        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9706        synchronized (this) {
9707            if (parentActivityToken == null) {
9708                throw new IllegalArgumentException("parent token must not be null");
9709            }
9710            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9711            if (r == null) {
9712                return null;
9713            }
9714            if (callback == null) {
9715                throw new IllegalArgumentException("callback must not be null");
9716            }
9717            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9718        }
9719    }
9720
9721    @Override
9722    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9723        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9724        synchronized (this) {
9725            mStackSupervisor.deleteActivityContainer(container);
9726        }
9727    }
9728
9729    @Override
9730    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9731        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9732        synchronized (this) {
9733            final int stackId = mStackSupervisor.getNextStackId();
9734            final ActivityStack stack =
9735                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9736            if (stack == null) {
9737                return null;
9738            }
9739            return stack.mActivityContainer;
9740        }
9741    }
9742
9743    @Override
9744    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9745        synchronized (this) {
9746            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9747            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9748                return stack.mActivityContainer.getDisplayId();
9749            }
9750            return Display.DEFAULT_DISPLAY;
9751        }
9752    }
9753
9754    @Override
9755    public int getActivityStackId(IBinder token) throws RemoteException {
9756        synchronized (this) {
9757            ActivityStack stack = ActivityRecord.getStackLocked(token);
9758            if (stack == null) {
9759                return INVALID_STACK_ID;
9760            }
9761            return stack.mStackId;
9762        }
9763    }
9764
9765    @Override
9766    public void exitFreeformMode(IBinder token) throws RemoteException {
9767        synchronized (this) {
9768            long ident = Binder.clearCallingIdentity();
9769            try {
9770                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9771                if (r == null) {
9772                    throw new IllegalArgumentException(
9773                            "exitFreeformMode: No activity record matching token=" + token);
9774                }
9775                final ActivityStack stack = r.getStackLocked(token);
9776                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9777                    throw new IllegalStateException(
9778                            "exitFreeformMode: You can only go fullscreen from freeform.");
9779                }
9780                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9781                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9782                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9783            } finally {
9784                Binder.restoreCallingIdentity(ident);
9785            }
9786        }
9787    }
9788
9789    @Override
9790    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9792        if (stackId == HOME_STACK_ID) {
9793            throw new IllegalArgumentException(
9794                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9795        }
9796        synchronized (this) {
9797            long ident = Binder.clearCallingIdentity();
9798            try {
9799                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9800                        + " to stackId=" + stackId + " toTop=" + toTop);
9801                if (stackId == DOCKED_STACK_ID) {
9802                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9803                            null /* initialBounds */);
9804                }
9805                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9806                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9807                if (result && stackId == DOCKED_STACK_ID) {
9808                    // If task moved to docked stack - show recents if needed.
9809                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9810                            "moveTaskToDockedStack");
9811                }
9812            } finally {
9813                Binder.restoreCallingIdentity(ident);
9814            }
9815        }
9816    }
9817
9818    @Override
9819    public void swapDockedAndFullscreenStack() throws RemoteException {
9820        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9821        synchronized (this) {
9822            long ident = Binder.clearCallingIdentity();
9823            try {
9824                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9825                        FULLSCREEN_WORKSPACE_STACK_ID);
9826                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9827                        : null;
9828                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9829                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9830                        : null;
9831                if (topTask == null || tasks == null || tasks.size() == 0) {
9832                    Slog.w(TAG,
9833                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9834                    return;
9835                }
9836
9837                // TODO: App transition
9838                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9839
9840                // Defer the resume so resume/pausing while moving stacks is dangerous.
9841                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9842                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9843                        ANIMATE, true /* deferResume */);
9844                final int size = tasks.size();
9845                for (int i = 0; i < size; i++) {
9846                    final int id = tasks.get(i).taskId;
9847                    if (id == topTask.taskId) {
9848                        continue;
9849                    }
9850                    mStackSupervisor.moveTaskToStackLocked(id,
9851                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9852                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9853                }
9854
9855                // Because we deferred the resume, to avoid conflicts with stack switches while
9856                // resuming, we need to do it after all the tasks are moved.
9857                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9858                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9859
9860                mWindowManager.executeAppTransition();
9861            } finally {
9862                Binder.restoreCallingIdentity(ident);
9863            }
9864        }
9865    }
9866
9867    /**
9868     * Moves the input task to the docked stack.
9869     *
9870     * @param taskId Id of task to move.
9871     * @param createMode The mode the docked stack should be created in if it doesn't exist
9872     *                   already. See
9873     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9874     *                   and
9875     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9876     * @param toTop If the task and stack should be moved to the top.
9877     * @param animate Whether we should play an animation for the moving the task
9878     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9879     *                      docked stack. Pass {@code null} to use default bounds.
9880     */
9881    @Override
9882    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9883            Rect initialBounds, boolean moveHomeStackFront) {
9884        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9885        synchronized (this) {
9886            long ident = Binder.clearCallingIdentity();
9887            try {
9888                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9889                        + " to createMode=" + createMode + " toTop=" + toTop);
9890                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9891                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9892                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9893                        animate, DEFER_RESUME);
9894                if (moved) {
9895                    if (moveHomeStackFront) {
9896                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9897                    }
9898                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9899                }
9900                return moved;
9901            } finally {
9902                Binder.restoreCallingIdentity(ident);
9903            }
9904        }
9905    }
9906
9907    /**
9908     * Moves the top activity in the input stackId to the pinned stack.
9909     *
9910     * @param stackId Id of stack to move the top activity to pinned stack.
9911     * @param bounds Bounds to use for pinned stack.
9912     *
9913     * @return True if the top activity of the input stack was successfully moved to the pinned
9914     *          stack.
9915     */
9916    @Override
9917    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9918        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9919        synchronized (this) {
9920            if (!mSupportsPictureInPicture) {
9921                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9922                        + "Device doesn't support picture-in-pciture mode");
9923            }
9924
9925            long ident = Binder.clearCallingIdentity();
9926            try {
9927                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9928            } finally {
9929                Binder.restoreCallingIdentity(ident);
9930            }
9931        }
9932    }
9933
9934    @Override
9935    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9936            boolean preserveWindows, boolean animate, int animationDuration) {
9937        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9938        long ident = Binder.clearCallingIdentity();
9939        try {
9940            synchronized (this) {
9941                if (animate) {
9942                    if (stackId == PINNED_STACK_ID) {
9943                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9944                    } else {
9945                        throw new IllegalArgumentException("Stack: " + stackId
9946                                + " doesn't support animated resize.");
9947                    }
9948                } else {
9949                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9950                            null /* tempTaskInsetBounds */, preserveWindows,
9951                            allowResizeInDockedMode, !DEFER_RESUME);
9952                }
9953            }
9954        } finally {
9955            Binder.restoreCallingIdentity(ident);
9956        }
9957    }
9958
9959    @Override
9960    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9961            Rect tempDockedTaskInsetBounds,
9962            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9963        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9964                "resizeDockedStack()");
9965        long ident = Binder.clearCallingIdentity();
9966        try {
9967            synchronized (this) {
9968                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9969                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9970                        PRESERVE_WINDOWS);
9971            }
9972        } finally {
9973            Binder.restoreCallingIdentity(ident);
9974        }
9975    }
9976
9977    @Override
9978    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9979        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9980                "resizePinnedStack()");
9981        final long ident = Binder.clearCallingIdentity();
9982        try {
9983            synchronized (this) {
9984                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9985            }
9986        } finally {
9987            Binder.restoreCallingIdentity(ident);
9988        }
9989    }
9990
9991    @Override
9992    public void positionTaskInStack(int taskId, int stackId, int position) {
9993        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9994        if (stackId == HOME_STACK_ID) {
9995            throw new IllegalArgumentException(
9996                    "positionTaskInStack: Attempt to change the position of task "
9997                    + taskId + " in/to home stack");
9998        }
9999        synchronized (this) {
10000            long ident = Binder.clearCallingIdentity();
10001            try {
10002                if (DEBUG_STACK) Slog.d(TAG_STACK,
10003                        "positionTaskInStack: positioning task=" + taskId
10004                        + " in stackId=" + stackId + " at position=" + position);
10005                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10006            } finally {
10007                Binder.restoreCallingIdentity(ident);
10008            }
10009        }
10010    }
10011
10012    @Override
10013    public List<StackInfo> getAllStackInfos() {
10014        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10015        long ident = Binder.clearCallingIdentity();
10016        try {
10017            synchronized (this) {
10018                return mStackSupervisor.getAllStackInfosLocked();
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    @Override
10026    public StackInfo getStackInfo(int stackId) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10028        long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                return mStackSupervisor.getStackInfoLocked(stackId);
10032            }
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    @Override
10039    public boolean isInHomeStack(int taskId) {
10040        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10041        long ident = Binder.clearCallingIdentity();
10042        try {
10043            synchronized (this) {
10044                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10045                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10046                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10047            }
10048        } finally {
10049            Binder.restoreCallingIdentity(ident);
10050        }
10051    }
10052
10053    @Override
10054    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10055        synchronized(this) {
10056            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10057        }
10058    }
10059
10060    @Override
10061    public void updateDeviceOwner(String packageName) {
10062        final int callingUid = Binder.getCallingUid();
10063        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10064            throw new SecurityException("updateDeviceOwner called from non-system process");
10065        }
10066        synchronized (this) {
10067            mDeviceOwnerName = packageName;
10068        }
10069    }
10070
10071    @Override
10072    public void updateLockTaskPackages(int userId, String[] packages) {
10073        final int callingUid = Binder.getCallingUid();
10074        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10075            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10076                    "updateLockTaskPackages()");
10077        }
10078        synchronized (this) {
10079            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10080                    Arrays.toString(packages));
10081            mLockTaskPackages.put(userId, packages);
10082            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10083        }
10084    }
10085
10086
10087    void startLockTaskModeLocked(TaskRecord task) {
10088        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10089        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10090            return;
10091        }
10092
10093        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10094        // is initiated by system after the pinning request was shown and locked mode is initiated
10095        // by an authorized app directly
10096        final int callingUid = Binder.getCallingUid();
10097        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10098        long ident = Binder.clearCallingIdentity();
10099        try {
10100            if (!isSystemInitiated) {
10101                task.mLockTaskUid = callingUid;
10102                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10103                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10104                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10105                    StatusBarManagerInternal statusBarManager =
10106                            LocalServices.getService(StatusBarManagerInternal.class);
10107                    if (statusBarManager != null) {
10108                        statusBarManager.showScreenPinningRequest(task.taskId);
10109                    }
10110                    return;
10111                }
10112
10113                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10114                if (stack == null || task != stack.topTask()) {
10115                    throw new IllegalArgumentException("Invalid task, not in foreground");
10116                }
10117            }
10118            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10119                    "Locking fully");
10120            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10121                    ActivityManager.LOCK_TASK_MODE_PINNED :
10122                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10123                    "startLockTask", true);
10124        } finally {
10125            Binder.restoreCallingIdentity(ident);
10126        }
10127    }
10128
10129    @Override
10130    public void startLockTaskMode(int taskId) {
10131        synchronized (this) {
10132            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10133            if (task != null) {
10134                startLockTaskModeLocked(task);
10135            }
10136        }
10137    }
10138
10139    @Override
10140    public void startLockTaskMode(IBinder token) {
10141        synchronized (this) {
10142            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10143            if (r == null) {
10144                return;
10145            }
10146            final TaskRecord task = r.task;
10147            if (task != null) {
10148                startLockTaskModeLocked(task);
10149            }
10150        }
10151    }
10152
10153    @Override
10154    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10155        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10156        // This makes inner call to look as if it was initiated by system.
10157        long ident = Binder.clearCallingIdentity();
10158        try {
10159            synchronized (this) {
10160                startLockTaskMode(taskId);
10161            }
10162        } finally {
10163            Binder.restoreCallingIdentity(ident);
10164        }
10165    }
10166
10167    @Override
10168    public void stopLockTaskMode() {
10169        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10170        if (lockTask == null) {
10171            // Our work here is done.
10172            return;
10173        }
10174
10175        final int callingUid = Binder.getCallingUid();
10176        final int lockTaskUid = lockTask.mLockTaskUid;
10177        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10178        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10179            // Done.
10180            return;
10181        } else {
10182            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10183            // It is possible lockTaskMode was started by the system process because
10184            // android:lockTaskMode is set to a locking value in the application manifest
10185            // instead of the app calling startLockTaskMode. In this case
10186            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10187            // {@link TaskRecord.effectiveUid} instead. Also caller with
10188            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10189            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10190                    && callingUid != lockTaskUid
10191                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10192                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10193                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10194            }
10195        }
10196        long ident = Binder.clearCallingIdentity();
10197        try {
10198            Log.d(TAG, "stopLockTaskMode");
10199            // Stop lock task
10200            synchronized (this) {
10201                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10202                        "stopLockTask", true);
10203            }
10204            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10205            if (tm != null) {
10206                tm.showInCallScreen(false);
10207            }
10208        } finally {
10209            Binder.restoreCallingIdentity(ident);
10210        }
10211    }
10212
10213    /**
10214     * This API should be called by SystemUI only when user perform certain action to dismiss
10215     * lock task mode. We should only dismiss pinned lock task mode in this case.
10216     */
10217    @Override
10218    public void stopSystemLockTaskMode() throws RemoteException {
10219        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10220            stopLockTaskMode();
10221        } else {
10222            mStackSupervisor.showLockTaskToast();
10223        }
10224    }
10225
10226    @Override
10227    public boolean isInLockTaskMode() {
10228        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10229    }
10230
10231    @Override
10232    public int getLockTaskModeState() {
10233        synchronized (this) {
10234            return mStackSupervisor.getLockTaskModeState();
10235        }
10236    }
10237
10238    @Override
10239    public void showLockTaskEscapeMessage(IBinder token) {
10240        synchronized (this) {
10241            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10242            if (r == null) {
10243                return;
10244            }
10245            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10246        }
10247    }
10248
10249    // =========================================================
10250    // CONTENT PROVIDERS
10251    // =========================================================
10252
10253    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10254        List<ProviderInfo> providers = null;
10255        try {
10256            providers = AppGlobals.getPackageManager()
10257                    .queryContentProviders(app.processName, app.uid,
10258                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10259                                    | MATCH_DEBUG_TRIAGED_MISSING)
10260                    .getList();
10261        } catch (RemoteException ex) {
10262        }
10263        if (DEBUG_MU) Slog.v(TAG_MU,
10264                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10265        int userId = app.userId;
10266        if (providers != null) {
10267            int N = providers.size();
10268            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10269            for (int i=0; i<N; i++) {
10270                // TODO: keep logic in sync with installEncryptionUnawareProviders
10271                ProviderInfo cpi =
10272                    (ProviderInfo)providers.get(i);
10273                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10274                        cpi.name, cpi.flags);
10275                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10276                    // This is a singleton provider, but a user besides the
10277                    // default user is asking to initialize a process it runs
10278                    // in...  well, no, it doesn't actually run in this process,
10279                    // it runs in the process of the default user.  Get rid of it.
10280                    providers.remove(i);
10281                    N--;
10282                    i--;
10283                    continue;
10284                }
10285
10286                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10287                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10288                if (cpr == null) {
10289                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10290                    mProviderMap.putProviderByClass(comp, cpr);
10291                }
10292                if (DEBUG_MU) Slog.v(TAG_MU,
10293                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10294                app.pubProviders.put(cpi.name, cpr);
10295                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10296                    // Don't add this if it is a platform component that is marked
10297                    // to run in multiple processes, because this is actually
10298                    // part of the framework so doesn't make sense to track as a
10299                    // separate apk in the process.
10300                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10301                            mProcessStats);
10302                }
10303                notifyPackageUse(cpi.applicationInfo.packageName,
10304                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10305            }
10306        }
10307        return providers;
10308    }
10309
10310    /**
10311     * Check if {@link ProcessRecord} has a possible chance at accessing the
10312     * given {@link ProviderInfo}. Final permission checking is always done
10313     * in {@link ContentProvider}.
10314     */
10315    private final String checkContentProviderPermissionLocked(
10316            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10317        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10318        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10319        boolean checkedGrants = false;
10320        if (checkUser) {
10321            // Looking for cross-user grants before enforcing the typical cross-users permissions
10322            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10323            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10324                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10325                    return null;
10326                }
10327                checkedGrants = true;
10328            }
10329            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10330                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10331            if (userId != tmpTargetUserId) {
10332                // When we actually went to determine the final targer user ID, this ended
10333                // up different than our initial check for the authority.  This is because
10334                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10335                // SELF.  So we need to re-check the grants again.
10336                checkedGrants = false;
10337            }
10338        }
10339        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10340                cpi.applicationInfo.uid, cpi.exported)
10341                == PackageManager.PERMISSION_GRANTED) {
10342            return null;
10343        }
10344        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10345                cpi.applicationInfo.uid, cpi.exported)
10346                == PackageManager.PERMISSION_GRANTED) {
10347            return null;
10348        }
10349
10350        PathPermission[] pps = cpi.pathPermissions;
10351        if (pps != null) {
10352            int i = pps.length;
10353            while (i > 0) {
10354                i--;
10355                PathPermission pp = pps[i];
10356                String pprperm = pp.getReadPermission();
10357                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10358                        cpi.applicationInfo.uid, cpi.exported)
10359                        == PackageManager.PERMISSION_GRANTED) {
10360                    return null;
10361                }
10362                String ppwperm = pp.getWritePermission();
10363                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10364                        cpi.applicationInfo.uid, cpi.exported)
10365                        == PackageManager.PERMISSION_GRANTED) {
10366                    return null;
10367                }
10368            }
10369        }
10370        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10371            return null;
10372        }
10373
10374        String msg;
10375        if (!cpi.exported) {
10376            msg = "Permission Denial: opening provider " + cpi.name
10377                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10378                    + ", uid=" + callingUid + ") that is not exported from uid "
10379                    + cpi.applicationInfo.uid;
10380        } else {
10381            msg = "Permission Denial: opening provider " + cpi.name
10382                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10383                    + ", uid=" + callingUid + ") requires "
10384                    + cpi.readPermission + " or " + cpi.writePermission;
10385        }
10386        Slog.w(TAG, msg);
10387        return msg;
10388    }
10389
10390    /**
10391     * Returns if the ContentProvider has granted a uri to callingUid
10392     */
10393    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10394        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10395        if (perms != null) {
10396            for (int i=perms.size()-1; i>=0; i--) {
10397                GrantUri grantUri = perms.keyAt(i);
10398                if (grantUri.sourceUserId == userId || !checkUser) {
10399                    if (matchesProvider(grantUri.uri, cpi)) {
10400                        return true;
10401                    }
10402                }
10403            }
10404        }
10405        return false;
10406    }
10407
10408    /**
10409     * Returns true if the uri authority is one of the authorities specified in the provider.
10410     */
10411    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10412        String uriAuth = uri.getAuthority();
10413        String cpiAuth = cpi.authority;
10414        if (cpiAuth.indexOf(';') == -1) {
10415            return cpiAuth.equals(uriAuth);
10416        }
10417        String[] cpiAuths = cpiAuth.split(";");
10418        int length = cpiAuths.length;
10419        for (int i = 0; i < length; i++) {
10420            if (cpiAuths[i].equals(uriAuth)) return true;
10421        }
10422        return false;
10423    }
10424
10425    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10426            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10427        if (r != null) {
10428            for (int i=0; i<r.conProviders.size(); i++) {
10429                ContentProviderConnection conn = r.conProviders.get(i);
10430                if (conn.provider == cpr) {
10431                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10432                            "Adding provider requested by "
10433                            + r.processName + " from process "
10434                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10435                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10436                    if (stable) {
10437                        conn.stableCount++;
10438                        conn.numStableIncs++;
10439                    } else {
10440                        conn.unstableCount++;
10441                        conn.numUnstableIncs++;
10442                    }
10443                    return conn;
10444                }
10445            }
10446            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10447            if (stable) {
10448                conn.stableCount = 1;
10449                conn.numStableIncs = 1;
10450            } else {
10451                conn.unstableCount = 1;
10452                conn.numUnstableIncs = 1;
10453            }
10454            cpr.connections.add(conn);
10455            r.conProviders.add(conn);
10456            startAssociationLocked(r.uid, r.processName, r.curProcState,
10457                    cpr.uid, cpr.name, cpr.info.processName);
10458            return conn;
10459        }
10460        cpr.addExternalProcessHandleLocked(externalProcessToken);
10461        return null;
10462    }
10463
10464    boolean decProviderCountLocked(ContentProviderConnection conn,
10465            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10466        if (conn != null) {
10467            cpr = conn.provider;
10468            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10469                    "Removing provider requested by "
10470                    + conn.client.processName + " from process "
10471                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10472                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10473            if (stable) {
10474                conn.stableCount--;
10475            } else {
10476                conn.unstableCount--;
10477            }
10478            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10479                cpr.connections.remove(conn);
10480                conn.client.conProviders.remove(conn);
10481                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10482                    // The client is more important than last activity -- note the time this
10483                    // is happening, so we keep the old provider process around a bit as last
10484                    // activity to avoid thrashing it.
10485                    if (cpr.proc != null) {
10486                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10487                    }
10488                }
10489                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10490                return true;
10491            }
10492            return false;
10493        }
10494        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10495        return false;
10496    }
10497
10498    private void checkTime(long startTime, String where) {
10499        long now = SystemClock.uptimeMillis();
10500        if ((now-startTime) > 50) {
10501            // If we are taking more than 50ms, log about it.
10502            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10503        }
10504    }
10505
10506    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10507            String name, IBinder token, boolean stable, int userId) {
10508        ContentProviderRecord cpr;
10509        ContentProviderConnection conn = null;
10510        ProviderInfo cpi = null;
10511
10512        synchronized(this) {
10513            long startTime = SystemClock.uptimeMillis();
10514
10515            ProcessRecord r = null;
10516            if (caller != null) {
10517                r = getRecordForAppLocked(caller);
10518                if (r == null) {
10519                    throw new SecurityException(
10520                            "Unable to find app for caller " + caller
10521                          + " (pid=" + Binder.getCallingPid()
10522                          + ") when getting content provider " + name);
10523                }
10524            }
10525
10526            boolean checkCrossUser = true;
10527
10528            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10529
10530            // First check if this content provider has been published...
10531            cpr = mProviderMap.getProviderByName(name, userId);
10532            // If that didn't work, check if it exists for user 0 and then
10533            // verify that it's a singleton provider before using it.
10534            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10535                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10536                if (cpr != null) {
10537                    cpi = cpr.info;
10538                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10539                            cpi.name, cpi.flags)
10540                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10541                        userId = UserHandle.USER_SYSTEM;
10542                        checkCrossUser = false;
10543                    } else {
10544                        cpr = null;
10545                        cpi = null;
10546                    }
10547                }
10548            }
10549
10550            boolean providerRunning = cpr != null;
10551            if (providerRunning) {
10552                cpi = cpr.info;
10553                String msg;
10554                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10555                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10556                        != null) {
10557                    throw new SecurityException(msg);
10558                }
10559                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10560
10561                if (r != null && cpr.canRunHere(r)) {
10562                    // This provider has been published or is in the process
10563                    // of being published...  but it is also allowed to run
10564                    // in the caller's process, so don't make a connection
10565                    // and just let the caller instantiate its own instance.
10566                    ContentProviderHolder holder = cpr.newHolder(null);
10567                    // don't give caller the provider object, it needs
10568                    // to make its own.
10569                    holder.provider = null;
10570                    return holder;
10571                }
10572
10573                final long origId = Binder.clearCallingIdentity();
10574
10575                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10576
10577                // In this case the provider instance already exists, so we can
10578                // return it right away.
10579                conn = incProviderCountLocked(r, cpr, token, stable);
10580                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10581                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10582                        // If this is a perceptible app accessing the provider,
10583                        // make sure to count it as being accessed and thus
10584                        // back up on the LRU list.  This is good because
10585                        // content providers are often expensive to start.
10586                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10587                        updateLruProcessLocked(cpr.proc, false, null);
10588                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10589                    }
10590                }
10591
10592                if (cpr.proc != null) {
10593                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10594                    boolean success = updateOomAdjLocked(cpr.proc);
10595                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10596                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10597                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10598                    // NOTE: there is still a race here where a signal could be
10599                    // pending on the process even though we managed to update its
10600                    // adj level.  Not sure what to do about this, but at least
10601                    // the race is now smaller.
10602                    if (!success) {
10603                        // Uh oh...  it looks like the provider's process
10604                        // has been killed on us.  We need to wait for a new
10605                        // process to be started, and make sure its death
10606                        // doesn't kill our process.
10607                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10608                                + " is crashing; detaching " + r);
10609                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10610                        checkTime(startTime, "getContentProviderImpl: before appDied");
10611                        appDiedLocked(cpr.proc);
10612                        checkTime(startTime, "getContentProviderImpl: after appDied");
10613                        if (!lastRef) {
10614                            // This wasn't the last ref our process had on
10615                            // the provider...  we have now been killed, bail.
10616                            return null;
10617                        }
10618                        providerRunning = false;
10619                        conn = null;
10620                    }
10621                }
10622
10623                Binder.restoreCallingIdentity(origId);
10624            }
10625
10626            if (!providerRunning) {
10627                try {
10628                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10629                    cpi = AppGlobals.getPackageManager().
10630                        resolveContentProvider(name,
10631                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10632                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10633                } catch (RemoteException ex) {
10634                }
10635                if (cpi == null) {
10636                    return null;
10637                }
10638                // If the provider is a singleton AND
10639                // (it's a call within the same user || the provider is a
10640                // privileged app)
10641                // Then allow connecting to the singleton provider
10642                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10643                        cpi.name, cpi.flags)
10644                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10645                if (singleton) {
10646                    userId = UserHandle.USER_SYSTEM;
10647                }
10648                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10649                checkTime(startTime, "getContentProviderImpl: got app info for user");
10650
10651                String msg;
10652                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10653                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10654                        != null) {
10655                    throw new SecurityException(msg);
10656                }
10657                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10658
10659                if (!mProcessesReady
10660                        && !cpi.processName.equals("system")) {
10661                    // If this content provider does not run in the system
10662                    // process, and the system is not yet ready to run other
10663                    // processes, then fail fast instead of hanging.
10664                    throw new IllegalArgumentException(
10665                            "Attempt to launch content provider before system ready");
10666                }
10667
10668                // Make sure that the user who owns this provider is running.  If not,
10669                // we don't want to allow it to run.
10670                if (!mUserController.isUserRunningLocked(userId, 0)) {
10671                    Slog.w(TAG, "Unable to launch app "
10672                            + cpi.applicationInfo.packageName + "/"
10673                            + cpi.applicationInfo.uid + " for provider "
10674                            + name + ": user " + userId + " is stopped");
10675                    return null;
10676                }
10677
10678                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10679                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10680                cpr = mProviderMap.getProviderByClass(comp, userId);
10681                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10682                final boolean firstClass = cpr == null;
10683                if (firstClass) {
10684                    final long ident = Binder.clearCallingIdentity();
10685
10686                    // If permissions need a review before any of the app components can run,
10687                    // we return no provider and launch a review activity if the calling app
10688                    // is in the foreground.
10689                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10690                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10691                            return null;
10692                        }
10693                    }
10694
10695                    try {
10696                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10697                        ApplicationInfo ai =
10698                            AppGlobals.getPackageManager().
10699                                getApplicationInfo(
10700                                        cpi.applicationInfo.packageName,
10701                                        STOCK_PM_FLAGS, userId);
10702                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10703                        if (ai == null) {
10704                            Slog.w(TAG, "No package info for content provider "
10705                                    + cpi.name);
10706                            return null;
10707                        }
10708                        ai = getAppInfoForUser(ai, userId);
10709                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10710                    } catch (RemoteException ex) {
10711                        // pm is in same process, this will never happen.
10712                    } finally {
10713                        Binder.restoreCallingIdentity(ident);
10714                    }
10715                }
10716
10717                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10718
10719                if (r != null && cpr.canRunHere(r)) {
10720                    // If this is a multiprocess provider, then just return its
10721                    // info and allow the caller to instantiate it.  Only do
10722                    // this if the provider is the same user as the caller's
10723                    // process, or can run as root (so can be in any process).
10724                    return cpr.newHolder(null);
10725                }
10726
10727                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10728                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10729                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10730
10731                // This is single process, and our app is now connecting to it.
10732                // See if we are already in the process of launching this
10733                // provider.
10734                final int N = mLaunchingProviders.size();
10735                int i;
10736                for (i = 0; i < N; i++) {
10737                    if (mLaunchingProviders.get(i) == cpr) {
10738                        break;
10739                    }
10740                }
10741
10742                // If the provider is not already being launched, then get it
10743                // started.
10744                if (i >= N) {
10745                    final long origId = Binder.clearCallingIdentity();
10746
10747                    try {
10748                        // Content provider is now in use, its package can't be stopped.
10749                        try {
10750                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10751                            AppGlobals.getPackageManager().setPackageStoppedState(
10752                                    cpr.appInfo.packageName, false, userId);
10753                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10754                        } catch (RemoteException e) {
10755                        } catch (IllegalArgumentException e) {
10756                            Slog.w(TAG, "Failed trying to unstop package "
10757                                    + cpr.appInfo.packageName + ": " + e);
10758                        }
10759
10760                        // Use existing process if already started
10761                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10762                        ProcessRecord proc = getProcessRecordLocked(
10763                                cpi.processName, cpr.appInfo.uid, false);
10764                        if (proc != null && proc.thread != null) {
10765                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10766                                    "Installing in existing process " + proc);
10767                            if (!proc.pubProviders.containsKey(cpi.name)) {
10768                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10769                                proc.pubProviders.put(cpi.name, cpr);
10770                                try {
10771                                    proc.thread.scheduleInstallProvider(cpi);
10772                                } catch (RemoteException e) {
10773                                }
10774                            }
10775                        } else {
10776                            checkTime(startTime, "getContentProviderImpl: before start process");
10777                            proc = startProcessLocked(cpi.processName,
10778                                    cpr.appInfo, false, 0, "content provider",
10779                                    new ComponentName(cpi.applicationInfo.packageName,
10780                                            cpi.name), false, false, false);
10781                            checkTime(startTime, "getContentProviderImpl: after start process");
10782                            if (proc == null) {
10783                                Slog.w(TAG, "Unable to launch app "
10784                                        + cpi.applicationInfo.packageName + "/"
10785                                        + cpi.applicationInfo.uid + " for provider "
10786                                        + name + ": process is bad");
10787                                return null;
10788                            }
10789                        }
10790                        cpr.launchingApp = proc;
10791                        mLaunchingProviders.add(cpr);
10792                    } finally {
10793                        Binder.restoreCallingIdentity(origId);
10794                    }
10795                }
10796
10797                checkTime(startTime, "getContentProviderImpl: updating data structures");
10798
10799                // Make sure the provider is published (the same provider class
10800                // may be published under multiple names).
10801                if (firstClass) {
10802                    mProviderMap.putProviderByClass(comp, cpr);
10803                }
10804
10805                mProviderMap.putProviderByName(name, cpr);
10806                conn = incProviderCountLocked(r, cpr, token, stable);
10807                if (conn != null) {
10808                    conn.waiting = true;
10809                }
10810            }
10811            checkTime(startTime, "getContentProviderImpl: done!");
10812        }
10813
10814        // Wait for the provider to be published...
10815        synchronized (cpr) {
10816            while (cpr.provider == null) {
10817                if (cpr.launchingApp == null) {
10818                    Slog.w(TAG, "Unable to launch app "
10819                            + cpi.applicationInfo.packageName + "/"
10820                            + cpi.applicationInfo.uid + " for provider "
10821                            + name + ": launching app became null");
10822                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10823                            UserHandle.getUserId(cpi.applicationInfo.uid),
10824                            cpi.applicationInfo.packageName,
10825                            cpi.applicationInfo.uid, name);
10826                    return null;
10827                }
10828                try {
10829                    if (DEBUG_MU) Slog.v(TAG_MU,
10830                            "Waiting to start provider " + cpr
10831                            + " launchingApp=" + cpr.launchingApp);
10832                    if (conn != null) {
10833                        conn.waiting = true;
10834                    }
10835                    cpr.wait();
10836                } catch (InterruptedException ex) {
10837                } finally {
10838                    if (conn != null) {
10839                        conn.waiting = false;
10840                    }
10841                }
10842            }
10843        }
10844        return cpr != null ? cpr.newHolder(conn) : null;
10845    }
10846
10847    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10848            ProcessRecord r, final int userId) {
10849        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10850                cpi.packageName, userId)) {
10851
10852            final boolean callerForeground = r == null || r.setSchedGroup
10853                    != ProcessList.SCHED_GROUP_BACKGROUND;
10854
10855            // Show a permission review UI only for starting from a foreground app
10856            if (!callerForeground) {
10857                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10858                        + cpi.packageName + " requires a permissions review");
10859                return false;
10860            }
10861
10862            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10863            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10864                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10865            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10866
10867            if (DEBUG_PERMISSIONS_REVIEW) {
10868                Slog.i(TAG, "u" + userId + " Launching permission review "
10869                        + "for package " + cpi.packageName);
10870            }
10871
10872            final UserHandle userHandle = new UserHandle(userId);
10873            mHandler.post(new Runnable() {
10874                @Override
10875                public void run() {
10876                    mContext.startActivityAsUser(intent, userHandle);
10877                }
10878            });
10879
10880            return false;
10881        }
10882
10883        return true;
10884    }
10885
10886    PackageManagerInternal getPackageManagerInternalLocked() {
10887        if (mPackageManagerInt == null) {
10888            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10889        }
10890        return mPackageManagerInt;
10891    }
10892
10893    @Override
10894    public final ContentProviderHolder getContentProvider(
10895            IApplicationThread caller, String name, int userId, boolean stable) {
10896        enforceNotIsolatedCaller("getContentProvider");
10897        if (caller == null) {
10898            String msg = "null IApplicationThread when getting content provider "
10899                    + name;
10900            Slog.w(TAG, msg);
10901            throw new SecurityException(msg);
10902        }
10903        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10904        // with cross-user grant.
10905        return getContentProviderImpl(caller, name, null, stable, userId);
10906    }
10907
10908    public ContentProviderHolder getContentProviderExternal(
10909            String name, int userId, IBinder token) {
10910        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10911            "Do not have permission in call getContentProviderExternal()");
10912        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10913                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10914        return getContentProviderExternalUnchecked(name, token, userId);
10915    }
10916
10917    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10918            IBinder token, int userId) {
10919        return getContentProviderImpl(null, name, token, true, userId);
10920    }
10921
10922    /**
10923     * Drop a content provider from a ProcessRecord's bookkeeping
10924     */
10925    public void removeContentProvider(IBinder connection, boolean stable) {
10926        enforceNotIsolatedCaller("removeContentProvider");
10927        long ident = Binder.clearCallingIdentity();
10928        try {
10929            synchronized (this) {
10930                ContentProviderConnection conn;
10931                try {
10932                    conn = (ContentProviderConnection)connection;
10933                } catch (ClassCastException e) {
10934                    String msg ="removeContentProvider: " + connection
10935                            + " not a ContentProviderConnection";
10936                    Slog.w(TAG, msg);
10937                    throw new IllegalArgumentException(msg);
10938                }
10939                if (conn == null) {
10940                    throw new NullPointerException("connection is null");
10941                }
10942                if (decProviderCountLocked(conn, null, null, stable)) {
10943                    updateOomAdjLocked();
10944                }
10945            }
10946        } finally {
10947            Binder.restoreCallingIdentity(ident);
10948        }
10949    }
10950
10951    public void removeContentProviderExternal(String name, IBinder token) {
10952        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10953            "Do not have permission in call removeContentProviderExternal()");
10954        int userId = UserHandle.getCallingUserId();
10955        long ident = Binder.clearCallingIdentity();
10956        try {
10957            removeContentProviderExternalUnchecked(name, token, userId);
10958        } finally {
10959            Binder.restoreCallingIdentity(ident);
10960        }
10961    }
10962
10963    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10964        synchronized (this) {
10965            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10966            if(cpr == null) {
10967                //remove from mProvidersByClass
10968                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10969                return;
10970            }
10971
10972            //update content provider record entry info
10973            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10974            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10975            if (localCpr.hasExternalProcessHandles()) {
10976                if (localCpr.removeExternalProcessHandleLocked(token)) {
10977                    updateOomAdjLocked();
10978                } else {
10979                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10980                            + " with no external reference for token: "
10981                            + token + ".");
10982                }
10983            } else {
10984                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10985                        + " with no external references.");
10986            }
10987        }
10988    }
10989
10990    public final void publishContentProviders(IApplicationThread caller,
10991            List<ContentProviderHolder> providers) {
10992        if (providers == null) {
10993            return;
10994        }
10995
10996        enforceNotIsolatedCaller("publishContentProviders");
10997        synchronized (this) {
10998            final ProcessRecord r = getRecordForAppLocked(caller);
10999            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11000            if (r == null) {
11001                throw new SecurityException(
11002                        "Unable to find app for caller " + caller
11003                      + " (pid=" + Binder.getCallingPid()
11004                      + ") when publishing content providers");
11005            }
11006
11007            final long origId = Binder.clearCallingIdentity();
11008
11009            final int N = providers.size();
11010            for (int i = 0; i < N; i++) {
11011                ContentProviderHolder src = providers.get(i);
11012                if (src == null || src.info == null || src.provider == null) {
11013                    continue;
11014                }
11015                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11016                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11017                if (dst != null) {
11018                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11019                    mProviderMap.putProviderByClass(comp, dst);
11020                    String names[] = dst.info.authority.split(";");
11021                    for (int j = 0; j < names.length; j++) {
11022                        mProviderMap.putProviderByName(names[j], dst);
11023                    }
11024
11025                    int launchingCount = mLaunchingProviders.size();
11026                    int j;
11027                    boolean wasInLaunchingProviders = false;
11028                    for (j = 0; j < launchingCount; j++) {
11029                        if (mLaunchingProviders.get(j) == dst) {
11030                            mLaunchingProviders.remove(j);
11031                            wasInLaunchingProviders = true;
11032                            j--;
11033                            launchingCount--;
11034                        }
11035                    }
11036                    if (wasInLaunchingProviders) {
11037                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11038                    }
11039                    synchronized (dst) {
11040                        dst.provider = src.provider;
11041                        dst.proc = r;
11042                        dst.notifyAll();
11043                    }
11044                    updateOomAdjLocked(r);
11045                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11046                            src.info.authority);
11047                }
11048            }
11049
11050            Binder.restoreCallingIdentity(origId);
11051        }
11052    }
11053
11054    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11055        ContentProviderConnection conn;
11056        try {
11057            conn = (ContentProviderConnection)connection;
11058        } catch (ClassCastException e) {
11059            String msg ="refContentProvider: " + connection
11060                    + " not a ContentProviderConnection";
11061            Slog.w(TAG, msg);
11062            throw new IllegalArgumentException(msg);
11063        }
11064        if (conn == null) {
11065            throw new NullPointerException("connection is null");
11066        }
11067
11068        synchronized (this) {
11069            if (stable > 0) {
11070                conn.numStableIncs += stable;
11071            }
11072            stable = conn.stableCount + stable;
11073            if (stable < 0) {
11074                throw new IllegalStateException("stableCount < 0: " + stable);
11075            }
11076
11077            if (unstable > 0) {
11078                conn.numUnstableIncs += unstable;
11079            }
11080            unstable = conn.unstableCount + unstable;
11081            if (unstable < 0) {
11082                throw new IllegalStateException("unstableCount < 0: " + unstable);
11083            }
11084
11085            if ((stable+unstable) <= 0) {
11086                throw new IllegalStateException("ref counts can't go to zero here: stable="
11087                        + stable + " unstable=" + unstable);
11088            }
11089            conn.stableCount = stable;
11090            conn.unstableCount = unstable;
11091            return !conn.dead;
11092        }
11093    }
11094
11095    public void unstableProviderDied(IBinder connection) {
11096        ContentProviderConnection conn;
11097        try {
11098            conn = (ContentProviderConnection)connection;
11099        } catch (ClassCastException e) {
11100            String msg ="refContentProvider: " + connection
11101                    + " not a ContentProviderConnection";
11102            Slog.w(TAG, msg);
11103            throw new IllegalArgumentException(msg);
11104        }
11105        if (conn == null) {
11106            throw new NullPointerException("connection is null");
11107        }
11108
11109        // Safely retrieve the content provider associated with the connection.
11110        IContentProvider provider;
11111        synchronized (this) {
11112            provider = conn.provider.provider;
11113        }
11114
11115        if (provider == null) {
11116            // Um, yeah, we're way ahead of you.
11117            return;
11118        }
11119
11120        // Make sure the caller is being honest with us.
11121        if (provider.asBinder().pingBinder()) {
11122            // Er, no, still looks good to us.
11123            synchronized (this) {
11124                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11125                        + " says " + conn + " died, but we don't agree");
11126                return;
11127            }
11128        }
11129
11130        // Well look at that!  It's dead!
11131        synchronized (this) {
11132            if (conn.provider.provider != provider) {
11133                // But something changed...  good enough.
11134                return;
11135            }
11136
11137            ProcessRecord proc = conn.provider.proc;
11138            if (proc == null || proc.thread == null) {
11139                // Seems like the process is already cleaned up.
11140                return;
11141            }
11142
11143            // As far as we're concerned, this is just like receiving a
11144            // death notification...  just a bit prematurely.
11145            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11146                    + ") early provider death");
11147            final long ident = Binder.clearCallingIdentity();
11148            try {
11149                appDiedLocked(proc);
11150            } finally {
11151                Binder.restoreCallingIdentity(ident);
11152            }
11153        }
11154    }
11155
11156    @Override
11157    public void appNotRespondingViaProvider(IBinder connection) {
11158        enforceCallingPermission(
11159                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11160
11161        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11162        if (conn == null) {
11163            Slog.w(TAG, "ContentProviderConnection is null");
11164            return;
11165        }
11166
11167        final ProcessRecord host = conn.provider.proc;
11168        if (host == null) {
11169            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11170            return;
11171        }
11172
11173        mHandler.post(new Runnable() {
11174            @Override
11175            public void run() {
11176                mAppErrors.appNotResponding(host, null, null, false,
11177                        "ContentProvider not responding");
11178            }
11179        });
11180    }
11181
11182    public final void installSystemProviders() {
11183        List<ProviderInfo> providers;
11184        synchronized (this) {
11185            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11186            providers = generateApplicationProvidersLocked(app);
11187            if (providers != null) {
11188                for (int i=providers.size()-1; i>=0; i--) {
11189                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11190                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11191                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11192                                + ": not system .apk");
11193                        providers.remove(i);
11194                    }
11195                }
11196            }
11197        }
11198        if (providers != null) {
11199            mSystemThread.installSystemProviders(providers);
11200        }
11201
11202        mCoreSettingsObserver = new CoreSettingsObserver(this);
11203        mFontScaleSettingObserver = new FontScaleSettingObserver();
11204
11205        //mUsageStatsService.monitorPackages();
11206    }
11207
11208    private void startPersistentApps(int matchFlags) {
11209        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11210
11211        synchronized (this) {
11212            try {
11213                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11214                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11215                for (ApplicationInfo app : apps) {
11216                    if (!"android".equals(app.packageName)) {
11217                        addAppLocked(app, false, null /* ABI override */);
11218                    }
11219                }
11220            } catch (RemoteException ex) {
11221            }
11222        }
11223    }
11224
11225    /**
11226     * When a user is unlocked, we need to install encryption-unaware providers
11227     * belonging to any running apps.
11228     */
11229    private void installEncryptionUnawareProviders(int userId) {
11230        // We're only interested in providers that are encryption unaware, and
11231        // we don't care about uninstalled apps, since there's no way they're
11232        // running at this point.
11233        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11234
11235        synchronized (this) {
11236            final int NP = mProcessNames.getMap().size();
11237            for (int ip = 0; ip < NP; ip++) {
11238                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11239                final int NA = apps.size();
11240                for (int ia = 0; ia < NA; ia++) {
11241                    final ProcessRecord app = apps.valueAt(ia);
11242                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11243
11244                    final int NG = app.pkgList.size();
11245                    for (int ig = 0; ig < NG; ig++) {
11246                        try {
11247                            final String pkgName = app.pkgList.keyAt(ig);
11248                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11249                                    .getPackageInfo(pkgName, matchFlags, userId);
11250                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11251                                for (ProviderInfo pi : pkgInfo.providers) {
11252                                    // TODO: keep in sync with generateApplicationProvidersLocked
11253                                    final boolean processMatch = Objects.equals(pi.processName,
11254                                            app.processName) || pi.multiprocess;
11255                                    final boolean userMatch = isSingleton(pi.processName,
11256                                            pi.applicationInfo, pi.name, pi.flags)
11257                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11258                                    if (processMatch && userMatch) {
11259                                        Log.v(TAG, "Installing " + pi);
11260                                        app.thread.scheduleInstallProvider(pi);
11261                                    } else {
11262                                        Log.v(TAG, "Skipping " + pi);
11263                                    }
11264                                }
11265                            }
11266                        } catch (RemoteException ignored) {
11267                        }
11268                    }
11269                }
11270            }
11271        }
11272    }
11273
11274    /**
11275     * Allows apps to retrieve the MIME type of a URI.
11276     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11277     * users, then it does not need permission to access the ContentProvider.
11278     * Either, it needs cross-user uri grants.
11279     *
11280     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11281     *
11282     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11283     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11284     */
11285    public String getProviderMimeType(Uri uri, int userId) {
11286        enforceNotIsolatedCaller("getProviderMimeType");
11287        final String name = uri.getAuthority();
11288        int callingUid = Binder.getCallingUid();
11289        int callingPid = Binder.getCallingPid();
11290        long ident = 0;
11291        boolean clearedIdentity = false;
11292        synchronized (this) {
11293            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11294        }
11295        if (canClearIdentity(callingPid, callingUid, userId)) {
11296            clearedIdentity = true;
11297            ident = Binder.clearCallingIdentity();
11298        }
11299        ContentProviderHolder holder = null;
11300        try {
11301            holder = getContentProviderExternalUnchecked(name, null, userId);
11302            if (holder != null) {
11303                return holder.provider.getType(uri);
11304            }
11305        } catch (RemoteException e) {
11306            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11307            return null;
11308        } catch (Exception e) {
11309            Log.w(TAG, "Exception while determining type of " + uri, e);
11310            return null;
11311        } finally {
11312            // We need to clear the identity to call removeContentProviderExternalUnchecked
11313            if (!clearedIdentity) {
11314                ident = Binder.clearCallingIdentity();
11315            }
11316            try {
11317                if (holder != null) {
11318                    removeContentProviderExternalUnchecked(name, null, userId);
11319                }
11320            } finally {
11321                Binder.restoreCallingIdentity(ident);
11322            }
11323        }
11324
11325        return null;
11326    }
11327
11328    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11329        if (UserHandle.getUserId(callingUid) == userId) {
11330            return true;
11331        }
11332        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11333                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11334                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11335                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11336                return true;
11337        }
11338        return false;
11339    }
11340
11341    // =========================================================
11342    // GLOBAL MANAGEMENT
11343    // =========================================================
11344
11345    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11346            boolean isolated, int isolatedUid) {
11347        String proc = customProcess != null ? customProcess : info.processName;
11348        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11349        final int userId = UserHandle.getUserId(info.uid);
11350        int uid = info.uid;
11351        if (isolated) {
11352            if (isolatedUid == 0) {
11353                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11354                while (true) {
11355                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11356                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11357                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11358                    }
11359                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11360                    mNextIsolatedProcessUid++;
11361                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11362                        // No process for this uid, use it.
11363                        break;
11364                    }
11365                    stepsLeft--;
11366                    if (stepsLeft <= 0) {
11367                        return null;
11368                    }
11369                }
11370            } else {
11371                // Special case for startIsolatedProcess (internal only), where
11372                // the uid of the isolated process is specified by the caller.
11373                uid = isolatedUid;
11374            }
11375        }
11376        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11377        if (!mBooted && !mBooting
11378                && userId == UserHandle.USER_SYSTEM
11379                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11380            r.persistent = true;
11381        }
11382        addProcessNameLocked(r);
11383        return r;
11384    }
11385
11386    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11387            String abiOverride) {
11388        ProcessRecord app;
11389        if (!isolated) {
11390            app = getProcessRecordLocked(info.processName, info.uid, true);
11391        } else {
11392            app = null;
11393        }
11394
11395        if (app == null) {
11396            app = newProcessRecordLocked(info, null, isolated, 0);
11397            updateLruProcessLocked(app, false, null);
11398            updateOomAdjLocked();
11399        }
11400
11401        // This package really, really can not be stopped.
11402        try {
11403            AppGlobals.getPackageManager().setPackageStoppedState(
11404                    info.packageName, false, UserHandle.getUserId(app.uid));
11405        } catch (RemoteException e) {
11406        } catch (IllegalArgumentException e) {
11407            Slog.w(TAG, "Failed trying to unstop package "
11408                    + info.packageName + ": " + e);
11409        }
11410
11411        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11412            app.persistent = true;
11413            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11414        }
11415        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11416            mPersistentStartingProcesses.add(app);
11417            startProcessLocked(app, "added application", app.processName, abiOverride,
11418                    null /* entryPoint */, null /* entryPointArgs */);
11419        }
11420
11421        return app;
11422    }
11423
11424    public void unhandledBack() {
11425        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11426                "unhandledBack()");
11427
11428        synchronized(this) {
11429            final long origId = Binder.clearCallingIdentity();
11430            try {
11431                getFocusedStack().unhandledBackLocked();
11432            } finally {
11433                Binder.restoreCallingIdentity(origId);
11434            }
11435        }
11436    }
11437
11438    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11439        enforceNotIsolatedCaller("openContentUri");
11440        final int userId = UserHandle.getCallingUserId();
11441        String name = uri.getAuthority();
11442        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11443        ParcelFileDescriptor pfd = null;
11444        if (cph != null) {
11445            // We record the binder invoker's uid in thread-local storage before
11446            // going to the content provider to open the file.  Later, in the code
11447            // that handles all permissions checks, we look for this uid and use
11448            // that rather than the Activity Manager's own uid.  The effect is that
11449            // we do the check against the caller's permissions even though it looks
11450            // to the content provider like the Activity Manager itself is making
11451            // the request.
11452            Binder token = new Binder();
11453            sCallerIdentity.set(new Identity(
11454                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11455            try {
11456                pfd = cph.provider.openFile(null, uri, "r", null, token);
11457            } catch (FileNotFoundException e) {
11458                // do nothing; pfd will be returned null
11459            } finally {
11460                // Ensure that whatever happens, we clean up the identity state
11461                sCallerIdentity.remove();
11462                // Ensure we're done with the provider.
11463                removeContentProviderExternalUnchecked(name, null, userId);
11464            }
11465        } else {
11466            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11467        }
11468        return pfd;
11469    }
11470
11471    // Actually is sleeping or shutting down or whatever else in the future
11472    // is an inactive state.
11473    public boolean isSleepingOrShuttingDown() {
11474        return isSleeping() || mShuttingDown;
11475    }
11476
11477    public boolean isSleeping() {
11478        return mSleeping;
11479    }
11480
11481    void onWakefulnessChanged(int wakefulness) {
11482        synchronized(this) {
11483            mWakefulness = wakefulness;
11484            updateSleepIfNeededLocked();
11485        }
11486    }
11487
11488    void finishRunningVoiceLocked() {
11489        if (mRunningVoice != null) {
11490            mRunningVoice = null;
11491            mVoiceWakeLock.release();
11492            updateSleepIfNeededLocked();
11493        }
11494    }
11495
11496    void startTimeTrackingFocusedActivityLocked() {
11497        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11498            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11499        }
11500    }
11501
11502    void updateSleepIfNeededLocked() {
11503        if (mSleeping && !shouldSleepLocked()) {
11504            mSleeping = false;
11505            startTimeTrackingFocusedActivityLocked();
11506            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11507            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11508            updateOomAdjLocked();
11509        } else if (!mSleeping && shouldSleepLocked()) {
11510            mSleeping = true;
11511            if (mCurAppTimeTracker != null) {
11512                mCurAppTimeTracker.stop();
11513            }
11514            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11515            mStackSupervisor.goingToSleepLocked();
11516            updateOomAdjLocked();
11517
11518            // Initialize the wake times of all processes.
11519            checkExcessivePowerUsageLocked(false);
11520            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11521            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11522            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11523        }
11524    }
11525
11526    private boolean shouldSleepLocked() {
11527        // Resume applications while running a voice interactor.
11528        if (mRunningVoice != null) {
11529            return false;
11530        }
11531
11532        // TODO: Transform the lock screen state into a sleep token instead.
11533        switch (mWakefulness) {
11534            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11535            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11536            case PowerManagerInternal.WAKEFULNESS_DOZING:
11537                // Pause applications whenever the lock screen is shown or any sleep
11538                // tokens have been acquired.
11539                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11540            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11541            default:
11542                // If we're asleep then pause applications unconditionally.
11543                return true;
11544        }
11545    }
11546
11547    /** Pokes the task persister. */
11548    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11549        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11550    }
11551
11552    /** Notifies all listeners when the task stack has changed. */
11553    void notifyTaskStackChangedLocked() {
11554        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11555        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11556        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11557        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11558    }
11559
11560    /** Notifies all listeners when an Activity is pinned. */
11561    void notifyActivityPinnedLocked() {
11562        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11563        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11564    }
11565
11566    /**
11567     * Notifies all listeners when an attempt was made to start an an activity that is already
11568     * running in the pinned stack and the activity was not actually started, but the task is
11569     * either brought to the front or a new Intent is delivered to it.
11570     */
11571    void notifyPinnedActivityRestartAttemptLocked() {
11572        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11573        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11574    }
11575
11576    /** Notifies all listeners when the pinned stack animation ends. */
11577    @Override
11578    public void notifyPinnedStackAnimationEnded() {
11579        synchronized (this) {
11580            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11581            mHandler.obtainMessage(
11582                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11583        }
11584    }
11585
11586    @Override
11587    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11588        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11589    }
11590
11591    @Override
11592    public boolean shutdown(int timeout) {
11593        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11594                != PackageManager.PERMISSION_GRANTED) {
11595            throw new SecurityException("Requires permission "
11596                    + android.Manifest.permission.SHUTDOWN);
11597        }
11598
11599        boolean timedout = false;
11600
11601        synchronized(this) {
11602            mShuttingDown = true;
11603            updateEventDispatchingLocked();
11604            timedout = mStackSupervisor.shutdownLocked(timeout);
11605        }
11606
11607        mAppOpsService.shutdown();
11608        if (mUsageStatsService != null) {
11609            mUsageStatsService.prepareShutdown();
11610        }
11611        mBatteryStatsService.shutdown();
11612        synchronized (this) {
11613            mProcessStats.shutdownLocked();
11614            notifyTaskPersisterLocked(null, true);
11615        }
11616
11617        return timedout;
11618    }
11619
11620    public final void activitySlept(IBinder token) {
11621        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11622
11623        final long origId = Binder.clearCallingIdentity();
11624
11625        synchronized (this) {
11626            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11627            if (r != null) {
11628                mStackSupervisor.activitySleptLocked(r);
11629            }
11630        }
11631
11632        Binder.restoreCallingIdentity(origId);
11633    }
11634
11635    private String lockScreenShownToString() {
11636        switch (mLockScreenShown) {
11637            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11638            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11639            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11640            default: return "Unknown=" + mLockScreenShown;
11641        }
11642    }
11643
11644    void logLockScreen(String msg) {
11645        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11646                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11647                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11648                + " mSleeping=" + mSleeping);
11649    }
11650
11651    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11652        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11653        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11654        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11655            boolean wasRunningVoice = mRunningVoice != null;
11656            mRunningVoice = session;
11657            if (!wasRunningVoice) {
11658                mVoiceWakeLock.acquire();
11659                updateSleepIfNeededLocked();
11660            }
11661        }
11662    }
11663
11664    private void updateEventDispatchingLocked() {
11665        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11666    }
11667
11668    public void setLockScreenShown(boolean showing, boolean occluded) {
11669        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11670                != PackageManager.PERMISSION_GRANTED) {
11671            throw new SecurityException("Requires permission "
11672                    + android.Manifest.permission.DEVICE_POWER);
11673        }
11674
11675        synchronized(this) {
11676            long ident = Binder.clearCallingIdentity();
11677            try {
11678                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11679                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11680                if (showing && occluded) {
11681                    // The lock screen is currently showing, but is occluded by a window that can
11682                    // show on top of the lock screen. In this can we want to dismiss the docked
11683                    // stack since it will be complicated/risky to try to put the activity on top
11684                    // of the lock screen in the right fullscreen configuration.
11685                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11686                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11687                }
11688
11689                updateSleepIfNeededLocked();
11690            } finally {
11691                Binder.restoreCallingIdentity(ident);
11692            }
11693        }
11694    }
11695
11696    @Override
11697    public void notifyLockedProfile(@UserIdInt int userId) {
11698        try {
11699            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11700                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11701            }
11702        } catch (RemoteException ex) {
11703            throw new SecurityException("Fail to check is caller a privileged app", ex);
11704        }
11705
11706        synchronized (this) {
11707            if (mStackSupervisor.isUserLockedProfile(userId)) {
11708                final long ident = Binder.clearCallingIdentity();
11709                try {
11710                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11711                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11712                        // If there is no device lock, we will show the profile's credential page.
11713                        mActivityStarter.showConfirmDeviceCredential(userId);
11714                    } else {
11715                        // Showing launcher to avoid user entering credential twice.
11716                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11717                    }
11718                } finally {
11719                    Binder.restoreCallingIdentity(ident);
11720                }
11721            }
11722        }
11723    }
11724
11725    @Override
11726    public void startConfirmDeviceCredentialIntent(Intent intent) {
11727        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11728        synchronized (this) {
11729            final long ident = Binder.clearCallingIdentity();
11730            try {
11731                mActivityStarter.startConfirmCredentialIntent(intent);
11732            } finally {
11733                Binder.restoreCallingIdentity(ident);
11734            }
11735        }
11736    }
11737
11738    @Override
11739    public void stopAppSwitches() {
11740        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11741                != PackageManager.PERMISSION_GRANTED) {
11742            throw new SecurityException("viewquires permission "
11743                    + android.Manifest.permission.STOP_APP_SWITCHES);
11744        }
11745
11746        synchronized(this) {
11747            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11748                    + APP_SWITCH_DELAY_TIME;
11749            mDidAppSwitch = false;
11750            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11751            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11752            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11753        }
11754    }
11755
11756    public void resumeAppSwitches() {
11757        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11758                != PackageManager.PERMISSION_GRANTED) {
11759            throw new SecurityException("Requires permission "
11760                    + android.Manifest.permission.STOP_APP_SWITCHES);
11761        }
11762
11763        synchronized(this) {
11764            // Note that we don't execute any pending app switches... we will
11765            // let those wait until either the timeout, or the next start
11766            // activity request.
11767            mAppSwitchesAllowedTime = 0;
11768        }
11769    }
11770
11771    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11772            int callingPid, int callingUid, String name) {
11773        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11774            return true;
11775        }
11776
11777        int perm = checkComponentPermission(
11778                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11779                sourceUid, -1, true);
11780        if (perm == PackageManager.PERMISSION_GRANTED) {
11781            return true;
11782        }
11783
11784        // If the actual IPC caller is different from the logical source, then
11785        // also see if they are allowed to control app switches.
11786        if (callingUid != -1 && callingUid != sourceUid) {
11787            perm = checkComponentPermission(
11788                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11789                    callingUid, -1, true);
11790            if (perm == PackageManager.PERMISSION_GRANTED) {
11791                return true;
11792            }
11793        }
11794
11795        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11796        return false;
11797    }
11798
11799    public void setDebugApp(String packageName, boolean waitForDebugger,
11800            boolean persistent) {
11801        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11802                "setDebugApp()");
11803
11804        long ident = Binder.clearCallingIdentity();
11805        try {
11806            // Note that this is not really thread safe if there are multiple
11807            // callers into it at the same time, but that's not a situation we
11808            // care about.
11809            if (persistent) {
11810                final ContentResolver resolver = mContext.getContentResolver();
11811                Settings.Global.putString(
11812                    resolver, Settings.Global.DEBUG_APP,
11813                    packageName);
11814                Settings.Global.putInt(
11815                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11816                    waitForDebugger ? 1 : 0);
11817            }
11818
11819            synchronized (this) {
11820                if (!persistent) {
11821                    mOrigDebugApp = mDebugApp;
11822                    mOrigWaitForDebugger = mWaitForDebugger;
11823                }
11824                mDebugApp = packageName;
11825                mWaitForDebugger = waitForDebugger;
11826                mDebugTransient = !persistent;
11827                if (packageName != null) {
11828                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11829                            false, UserHandle.USER_ALL, "set debug app");
11830                }
11831            }
11832        } finally {
11833            Binder.restoreCallingIdentity(ident);
11834        }
11835    }
11836
11837    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11838        synchronized (this) {
11839            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11840            if (!isDebuggable) {
11841                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11842                    throw new SecurityException("Process not debuggable: " + app.packageName);
11843                }
11844            }
11845
11846            mTrackAllocationApp = processName;
11847        }
11848    }
11849
11850    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11851        synchronized (this) {
11852            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11853            if (!isDebuggable) {
11854                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11855                    throw new SecurityException("Process not debuggable: " + app.packageName);
11856                }
11857            }
11858            mProfileApp = processName;
11859            mProfileFile = profilerInfo.profileFile;
11860            if (mProfileFd != null) {
11861                try {
11862                    mProfileFd.close();
11863                } catch (IOException e) {
11864                }
11865                mProfileFd = null;
11866            }
11867            mProfileFd = profilerInfo.profileFd;
11868            mSamplingInterval = profilerInfo.samplingInterval;
11869            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11870            mProfileType = 0;
11871        }
11872    }
11873
11874    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11875        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11876        if (!isDebuggable) {
11877            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11878                throw new SecurityException("Process not debuggable: " + app.packageName);
11879            }
11880        }
11881        mNativeDebuggingApp = processName;
11882    }
11883
11884    @Override
11885    public void setAlwaysFinish(boolean enabled) {
11886        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11887                "setAlwaysFinish()");
11888
11889        long ident = Binder.clearCallingIdentity();
11890        try {
11891            Settings.Global.putInt(
11892                    mContext.getContentResolver(),
11893                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11894
11895            synchronized (this) {
11896                mAlwaysFinishActivities = enabled;
11897            }
11898        } finally {
11899            Binder.restoreCallingIdentity(ident);
11900        }
11901    }
11902
11903    @Override
11904    public void setLenientBackgroundCheck(boolean enabled) {
11905        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11906                "setLenientBackgroundCheck()");
11907
11908        long ident = Binder.clearCallingIdentity();
11909        try {
11910            Settings.Global.putInt(
11911                    mContext.getContentResolver(),
11912                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11913
11914            synchronized (this) {
11915                mLenientBackgroundCheck = enabled;
11916            }
11917        } finally {
11918            Binder.restoreCallingIdentity(ident);
11919        }
11920    }
11921
11922    @Override
11923    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11924        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11925                "setActivityController()");
11926        synchronized (this) {
11927            mController = controller;
11928            mControllerIsAMonkey = imAMonkey;
11929            Watchdog.getInstance().setActivityController(controller);
11930        }
11931    }
11932
11933    @Override
11934    public void setUserIsMonkey(boolean userIsMonkey) {
11935        synchronized (this) {
11936            synchronized (mPidsSelfLocked) {
11937                final int callingPid = Binder.getCallingPid();
11938                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11939                if (precessRecord == null) {
11940                    throw new SecurityException("Unknown process: " + callingPid);
11941                }
11942                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11943                    throw new SecurityException("Only an instrumentation process "
11944                            + "with a UiAutomation can call setUserIsMonkey");
11945                }
11946            }
11947            mUserIsMonkey = userIsMonkey;
11948        }
11949    }
11950
11951    @Override
11952    public boolean isUserAMonkey() {
11953        synchronized (this) {
11954            // If there is a controller also implies the user is a monkey.
11955            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11956        }
11957    }
11958
11959    public void requestBugReport(int bugreportType) {
11960        String service = null;
11961        switch (bugreportType) {
11962            case ActivityManager.BUGREPORT_OPTION_FULL:
11963                service = "bugreport";
11964                break;
11965            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11966                service = "bugreportplus";
11967                break;
11968            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11969                service = "bugreportremote";
11970                break;
11971        }
11972        if (service == null) {
11973            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11974                    + bugreportType);
11975        }
11976        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11977        SystemProperties.set("ctl.start", service);
11978    }
11979
11980    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11981        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11982    }
11983
11984    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11985        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11986            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11987        }
11988        return KEY_DISPATCHING_TIMEOUT;
11989    }
11990
11991    @Override
11992    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11993        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11994                != PackageManager.PERMISSION_GRANTED) {
11995            throw new SecurityException("Requires permission "
11996                    + android.Manifest.permission.FILTER_EVENTS);
11997        }
11998        ProcessRecord proc;
11999        long timeout;
12000        synchronized (this) {
12001            synchronized (mPidsSelfLocked) {
12002                proc = mPidsSelfLocked.get(pid);
12003            }
12004            timeout = getInputDispatchingTimeoutLocked(proc);
12005        }
12006
12007        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12008            return -1;
12009        }
12010
12011        return timeout;
12012    }
12013
12014    /**
12015     * Handle input dispatching timeouts.
12016     * Returns whether input dispatching should be aborted or not.
12017     */
12018    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12019            final ActivityRecord activity, final ActivityRecord parent,
12020            final boolean aboveSystem, String reason) {
12021        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12022                != PackageManager.PERMISSION_GRANTED) {
12023            throw new SecurityException("Requires permission "
12024                    + android.Manifest.permission.FILTER_EVENTS);
12025        }
12026
12027        final String annotation;
12028        if (reason == null) {
12029            annotation = "Input dispatching timed out";
12030        } else {
12031            annotation = "Input dispatching timed out (" + reason + ")";
12032        }
12033
12034        if (proc != null) {
12035            synchronized (this) {
12036                if (proc.debugging) {
12037                    return false;
12038                }
12039
12040                if (mDidDexOpt) {
12041                    // Give more time since we were dexopting.
12042                    mDidDexOpt = false;
12043                    return false;
12044                }
12045
12046                if (proc.instrumentationClass != null) {
12047                    Bundle info = new Bundle();
12048                    info.putString("shortMsg", "keyDispatchingTimedOut");
12049                    info.putString("longMsg", annotation);
12050                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12051                    return true;
12052                }
12053            }
12054            mHandler.post(new Runnable() {
12055                @Override
12056                public void run() {
12057                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12058                }
12059            });
12060        }
12061
12062        return true;
12063    }
12064
12065    @Override
12066    public Bundle getAssistContextExtras(int requestType) {
12067        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12068                null, null, true /* focused */, true /* newSessionId */,
12069                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12070        if (pae == null) {
12071            return null;
12072        }
12073        synchronized (pae) {
12074            while (!pae.haveResult) {
12075                try {
12076                    pae.wait();
12077                } catch (InterruptedException e) {
12078                }
12079            }
12080        }
12081        synchronized (this) {
12082            buildAssistBundleLocked(pae, pae.result);
12083            mPendingAssistExtras.remove(pae);
12084            mUiHandler.removeCallbacks(pae);
12085        }
12086        return pae.extras;
12087    }
12088
12089    @Override
12090    public boolean isAssistDataAllowedOnCurrentActivity() {
12091        int userId;
12092        synchronized (this) {
12093            userId = mUserController.getCurrentUserIdLocked();
12094            ActivityRecord activity = getFocusedStack().topActivity();
12095            if (activity == null) {
12096                return false;
12097            }
12098            userId = activity.userId;
12099        }
12100        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12101                Context.DEVICE_POLICY_SERVICE);
12102        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12103    }
12104
12105    @Override
12106    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12107        long ident = Binder.clearCallingIdentity();
12108        try {
12109            synchronized (this) {
12110                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12111                ActivityRecord top = getFocusedStack().topActivity();
12112                if (top != caller) {
12113                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12114                            + " is not current top " + top);
12115                    return false;
12116                }
12117                if (!top.nowVisible) {
12118                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12119                            + " is not visible");
12120                    return false;
12121                }
12122            }
12123            AssistUtils utils = new AssistUtils(mContext);
12124            return utils.showSessionForActiveService(args,
12125                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12126        } finally {
12127            Binder.restoreCallingIdentity(ident);
12128        }
12129    }
12130
12131    @Override
12132    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12133            Bundle receiverExtras,
12134            IBinder activityToken, boolean focused, boolean newSessionId) {
12135        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12136                activityToken, focused, newSessionId,
12137                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12138                != null;
12139    }
12140
12141    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12142            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12143            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12144        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12145                "enqueueAssistContext()");
12146        synchronized (this) {
12147            ActivityRecord activity = getFocusedStack().topActivity();
12148            if (activity == null) {
12149                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12150                return null;
12151            }
12152            if (activity.app == null || activity.app.thread == null) {
12153                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12154                return null;
12155            }
12156            if (focused) {
12157                if (activityToken != null) {
12158                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12159                    if (activity != caller) {
12160                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12161                                + " is not current top " + activity);
12162                        return null;
12163                    }
12164                }
12165            } else {
12166                activity = ActivityRecord.forTokenLocked(activityToken);
12167                if (activity == null) {
12168                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12169                            + " couldn't be found");
12170                    return null;
12171                }
12172            }
12173
12174            PendingAssistExtras pae;
12175            Bundle extras = new Bundle();
12176            if (args != null) {
12177                extras.putAll(args);
12178            }
12179            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12180            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12181            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12182                    userHandle);
12183            // Increment the sessionId if necessary
12184            if (newSessionId) {
12185                mViSessionId++;
12186            }
12187            try {
12188                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12189                        requestType, mViSessionId);
12190                mPendingAssistExtras.add(pae);
12191                mUiHandler.postDelayed(pae, timeout);
12192            } catch (RemoteException e) {
12193                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12194                return null;
12195            }
12196            return pae;
12197        }
12198    }
12199
12200    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12201        IResultReceiver receiver;
12202        synchronized (this) {
12203            mPendingAssistExtras.remove(pae);
12204            receiver = pae.receiver;
12205        }
12206        if (receiver != null) {
12207            // Caller wants result sent back to them.
12208            Bundle sendBundle = new Bundle();
12209            // At least return the receiver extras
12210            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12211                    pae.receiverExtras);
12212            try {
12213                pae.receiver.send(0, sendBundle);
12214            } catch (RemoteException e) {
12215            }
12216        }
12217    }
12218
12219    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12220        if (result != null) {
12221            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12222        }
12223        if (pae.hint != null) {
12224            pae.extras.putBoolean(pae.hint, true);
12225        }
12226    }
12227
12228    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12229            AssistContent content, Uri referrer) {
12230        PendingAssistExtras pae = (PendingAssistExtras)token;
12231        synchronized (pae) {
12232            pae.result = extras;
12233            pae.structure = structure;
12234            pae.content = content;
12235            if (referrer != null) {
12236                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12237            }
12238            pae.haveResult = true;
12239            pae.notifyAll();
12240            if (pae.intent == null && pae.receiver == null) {
12241                // Caller is just waiting for the result.
12242                return;
12243            }
12244        }
12245
12246        // We are now ready to launch the assist activity.
12247        IResultReceiver sendReceiver = null;
12248        Bundle sendBundle = null;
12249        synchronized (this) {
12250            buildAssistBundleLocked(pae, extras);
12251            boolean exists = mPendingAssistExtras.remove(pae);
12252            mUiHandler.removeCallbacks(pae);
12253            if (!exists) {
12254                // Timed out.
12255                return;
12256            }
12257            if ((sendReceiver=pae.receiver) != null) {
12258                // Caller wants result sent back to them.
12259                sendBundle = new Bundle();
12260                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12261                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12262                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12263                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12264                        pae.receiverExtras);
12265            }
12266        }
12267        if (sendReceiver != null) {
12268            try {
12269                sendReceiver.send(0, sendBundle);
12270            } catch (RemoteException e) {
12271            }
12272            return;
12273        }
12274
12275        long ident = Binder.clearCallingIdentity();
12276        try {
12277            pae.intent.replaceExtras(pae.extras);
12278            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12279                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12280                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12281            closeSystemDialogs("assist");
12282            try {
12283                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12284            } catch (ActivityNotFoundException e) {
12285                Slog.w(TAG, "No activity to handle assist action.", e);
12286            }
12287        } finally {
12288            Binder.restoreCallingIdentity(ident);
12289        }
12290    }
12291
12292    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12293            Bundle args) {
12294        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12295                true /* focused */, true /* newSessionId */,
12296                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12297    }
12298
12299    public void registerProcessObserver(IProcessObserver observer) {
12300        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12301                "registerProcessObserver()");
12302        synchronized (this) {
12303            mProcessObservers.register(observer);
12304        }
12305    }
12306
12307    @Override
12308    public void unregisterProcessObserver(IProcessObserver observer) {
12309        synchronized (this) {
12310            mProcessObservers.unregister(observer);
12311        }
12312    }
12313
12314    @Override
12315    public void registerUidObserver(IUidObserver observer, int which) {
12316        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12317                "registerUidObserver()");
12318        synchronized (this) {
12319            mUidObservers.register(observer, which);
12320        }
12321    }
12322
12323    @Override
12324    public void unregisterUidObserver(IUidObserver observer) {
12325        synchronized (this) {
12326            mUidObservers.unregister(observer);
12327        }
12328    }
12329
12330    @Override
12331    public boolean convertFromTranslucent(IBinder token) {
12332        final long origId = Binder.clearCallingIdentity();
12333        try {
12334            synchronized (this) {
12335                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12336                if (r == null) {
12337                    return false;
12338                }
12339                final boolean translucentChanged = r.changeWindowTranslucency(true);
12340                if (translucentChanged) {
12341                    r.task.stack.releaseBackgroundResources(r);
12342                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12343                }
12344                mWindowManager.setAppFullscreen(token, true);
12345                return translucentChanged;
12346            }
12347        } finally {
12348            Binder.restoreCallingIdentity(origId);
12349        }
12350    }
12351
12352    @Override
12353    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12354        final long origId = Binder.clearCallingIdentity();
12355        try {
12356            synchronized (this) {
12357                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12358                if (r == null) {
12359                    return false;
12360                }
12361                int index = r.task.mActivities.lastIndexOf(r);
12362                if (index > 0) {
12363                    ActivityRecord under = r.task.mActivities.get(index - 1);
12364                    under.returningOptions = options;
12365                }
12366                final boolean translucentChanged = r.changeWindowTranslucency(false);
12367                if (translucentChanged) {
12368                    r.task.stack.convertActivityToTranslucent(r);
12369                }
12370                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12371                mWindowManager.setAppFullscreen(token, false);
12372                return translucentChanged;
12373            }
12374        } finally {
12375            Binder.restoreCallingIdentity(origId);
12376        }
12377    }
12378
12379    @Override
12380    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12381        final long origId = Binder.clearCallingIdentity();
12382        try {
12383            synchronized (this) {
12384                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12385                if (r != null) {
12386                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12387                }
12388            }
12389            return false;
12390        } finally {
12391            Binder.restoreCallingIdentity(origId);
12392        }
12393    }
12394
12395    @Override
12396    public boolean isBackgroundVisibleBehind(IBinder token) {
12397        final long origId = Binder.clearCallingIdentity();
12398        try {
12399            synchronized (this) {
12400                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12401                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12402                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12403                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12404                return visible;
12405            }
12406        } finally {
12407            Binder.restoreCallingIdentity(origId);
12408        }
12409    }
12410
12411    @Override
12412    public ActivityOptions getActivityOptions(IBinder token) {
12413        final long origId = Binder.clearCallingIdentity();
12414        try {
12415            synchronized (this) {
12416                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12417                if (r != null) {
12418                    final ActivityOptions activityOptions = r.pendingOptions;
12419                    r.pendingOptions = null;
12420                    return activityOptions;
12421                }
12422                return null;
12423            }
12424        } finally {
12425            Binder.restoreCallingIdentity(origId);
12426        }
12427    }
12428
12429    @Override
12430    public void setImmersive(IBinder token, boolean immersive) {
12431        synchronized(this) {
12432            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12433            if (r == null) {
12434                throw new IllegalArgumentException();
12435            }
12436            r.immersive = immersive;
12437
12438            // update associated state if we're frontmost
12439            if (r == mFocusedActivity) {
12440                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12441                applyUpdateLockStateLocked(r);
12442            }
12443        }
12444    }
12445
12446    @Override
12447    public boolean isImmersive(IBinder token) {
12448        synchronized (this) {
12449            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12450            if (r == null) {
12451                throw new IllegalArgumentException();
12452            }
12453            return r.immersive;
12454        }
12455    }
12456
12457    @Override
12458    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12459        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12460            throw new UnsupportedOperationException("VR mode not supported on this device!");
12461        }
12462
12463        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12464
12465        ActivityRecord r;
12466        synchronized (this) {
12467            r = ActivityRecord.isInStackLocked(token);
12468        }
12469
12470        if (r == null) {
12471            throw new IllegalArgumentException();
12472        }
12473
12474        int err;
12475        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12476                VrManagerInternal.NO_ERROR) {
12477            return err;
12478        }
12479
12480        synchronized(this) {
12481            r.requestedVrComponent = (enabled) ? packageName : null;
12482
12483            // Update associated state if this activity is currently focused
12484            if (r == mFocusedActivity) {
12485                applyUpdateVrModeLocked(r);
12486            }
12487            return 0;
12488        }
12489    }
12490
12491    @Override
12492    public boolean isVrModePackageEnabled(ComponentName packageName) {
12493        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12494            throw new UnsupportedOperationException("VR mode not supported on this device!");
12495        }
12496
12497        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12498
12499        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12500                VrManagerInternal.NO_ERROR;
12501    }
12502
12503    public boolean isTopActivityImmersive() {
12504        enforceNotIsolatedCaller("startActivity");
12505        synchronized (this) {
12506            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12507            return (r != null) ? r.immersive : false;
12508        }
12509    }
12510
12511    @Override
12512    public boolean isTopOfTask(IBinder token) {
12513        synchronized (this) {
12514            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12515            if (r == null) {
12516                throw new IllegalArgumentException();
12517            }
12518            return r.task.getTopActivity() == r;
12519        }
12520    }
12521
12522    public final void enterSafeMode() {
12523        synchronized(this) {
12524            // It only makes sense to do this before the system is ready
12525            // and started launching other packages.
12526            if (!mSystemReady) {
12527                try {
12528                    AppGlobals.getPackageManager().enterSafeMode();
12529                } catch (RemoteException e) {
12530                }
12531            }
12532
12533            mSafeMode = true;
12534        }
12535    }
12536
12537    public final void showSafeModeOverlay() {
12538        View v = LayoutInflater.from(mContext).inflate(
12539                com.android.internal.R.layout.safe_mode, null);
12540        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12541        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12542        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12543        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12544        lp.gravity = Gravity.BOTTOM | Gravity.START;
12545        lp.format = v.getBackground().getOpacity();
12546        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12547                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12548        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12549        ((WindowManager)mContext.getSystemService(
12550                Context.WINDOW_SERVICE)).addView(v, lp);
12551    }
12552
12553    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12554        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12555            return;
12556        }
12557        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12558        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12559        synchronized (stats) {
12560            if (mBatteryStatsService.isOnBattery()) {
12561                mBatteryStatsService.enforceCallingPermission();
12562                int MY_UID = Binder.getCallingUid();
12563                final int uid;
12564                if (sender == null) {
12565                    uid = sourceUid;
12566                } else {
12567                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12568                }
12569                BatteryStatsImpl.Uid.Pkg pkg =
12570                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12571                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12572                pkg.noteWakeupAlarmLocked(tag);
12573            }
12574        }
12575    }
12576
12577    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12578        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12579            return;
12580        }
12581        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12582        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12583        synchronized (stats) {
12584            mBatteryStatsService.enforceCallingPermission();
12585            int MY_UID = Binder.getCallingUid();
12586            final int uid;
12587            if (sender == null) {
12588                uid = sourceUid;
12589            } else {
12590                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12591            }
12592            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12593        }
12594    }
12595
12596    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12597        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12598            return;
12599        }
12600        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12601        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12602        synchronized (stats) {
12603            mBatteryStatsService.enforceCallingPermission();
12604            int MY_UID = Binder.getCallingUid();
12605            final int uid;
12606            if (sender == null) {
12607                uid = sourceUid;
12608            } else {
12609                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12610            }
12611            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12612        }
12613    }
12614
12615    public boolean killPids(int[] pids, String pReason, boolean secure) {
12616        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12617            throw new SecurityException("killPids only available to the system");
12618        }
12619        String reason = (pReason == null) ? "Unknown" : pReason;
12620        // XXX Note: don't acquire main activity lock here, because the window
12621        // manager calls in with its locks held.
12622
12623        boolean killed = false;
12624        synchronized (mPidsSelfLocked) {
12625            int worstType = 0;
12626            for (int i=0; i<pids.length; i++) {
12627                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12628                if (proc != null) {
12629                    int type = proc.setAdj;
12630                    if (type > worstType) {
12631                        worstType = type;
12632                    }
12633                }
12634            }
12635
12636            // If the worst oom_adj is somewhere in the cached proc LRU range,
12637            // then constrain it so we will kill all cached procs.
12638            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12639                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12640                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12641            }
12642
12643            // If this is not a secure call, don't let it kill processes that
12644            // are important.
12645            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12646                worstType = ProcessList.SERVICE_ADJ;
12647            }
12648
12649            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12650            for (int i=0; i<pids.length; i++) {
12651                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12652                if (proc == null) {
12653                    continue;
12654                }
12655                int adj = proc.setAdj;
12656                if (adj >= worstType && !proc.killedByAm) {
12657                    proc.kill(reason, true);
12658                    killed = true;
12659                }
12660            }
12661        }
12662        return killed;
12663    }
12664
12665    @Override
12666    public void killUid(int appId, int userId, String reason) {
12667        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12668        synchronized (this) {
12669            final long identity = Binder.clearCallingIdentity();
12670            try {
12671                killPackageProcessesLocked(null, appId, userId,
12672                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12673                        reason != null ? reason : "kill uid");
12674            } finally {
12675                Binder.restoreCallingIdentity(identity);
12676            }
12677        }
12678    }
12679
12680    @Override
12681    public boolean killProcessesBelowForeground(String reason) {
12682        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12683            throw new SecurityException("killProcessesBelowForeground() only available to system");
12684        }
12685
12686        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12687    }
12688
12689    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12690        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12691            throw new SecurityException("killProcessesBelowAdj() only available to system");
12692        }
12693
12694        boolean killed = false;
12695        synchronized (mPidsSelfLocked) {
12696            final int size = mPidsSelfLocked.size();
12697            for (int i = 0; i < size; i++) {
12698                final int pid = mPidsSelfLocked.keyAt(i);
12699                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12700                if (proc == null) continue;
12701
12702                final int adj = proc.setAdj;
12703                if (adj > belowAdj && !proc.killedByAm) {
12704                    proc.kill(reason, true);
12705                    killed = true;
12706                }
12707            }
12708        }
12709        return killed;
12710    }
12711
12712    @Override
12713    public void hang(final IBinder who, boolean allowRestart) {
12714        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12715                != PackageManager.PERMISSION_GRANTED) {
12716            throw new SecurityException("Requires permission "
12717                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12718        }
12719
12720        final IBinder.DeathRecipient death = new DeathRecipient() {
12721            @Override
12722            public void binderDied() {
12723                synchronized (this) {
12724                    notifyAll();
12725                }
12726            }
12727        };
12728
12729        try {
12730            who.linkToDeath(death, 0);
12731        } catch (RemoteException e) {
12732            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12733            return;
12734        }
12735
12736        synchronized (this) {
12737            Watchdog.getInstance().setAllowRestart(allowRestart);
12738            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12739            synchronized (death) {
12740                while (who.isBinderAlive()) {
12741                    try {
12742                        death.wait();
12743                    } catch (InterruptedException e) {
12744                    }
12745                }
12746            }
12747            Watchdog.getInstance().setAllowRestart(true);
12748        }
12749    }
12750
12751    @Override
12752    public void restart() {
12753        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12754                != PackageManager.PERMISSION_GRANTED) {
12755            throw new SecurityException("Requires permission "
12756                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12757        }
12758
12759        Log.i(TAG, "Sending shutdown broadcast...");
12760
12761        BroadcastReceiver br = new BroadcastReceiver() {
12762            @Override public void onReceive(Context context, Intent intent) {
12763                // Now the broadcast is done, finish up the low-level shutdown.
12764                Log.i(TAG, "Shutting down activity manager...");
12765                shutdown(10000);
12766                Log.i(TAG, "Shutdown complete, restarting!");
12767                Process.killProcess(Process.myPid());
12768                System.exit(10);
12769            }
12770        };
12771
12772        // First send the high-level shut down broadcast.
12773        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12774        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12775        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12776        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12777        mContext.sendOrderedBroadcastAsUser(intent,
12778                UserHandle.ALL, null, br, mHandler, 0, null, null);
12779        */
12780        br.onReceive(mContext, intent);
12781    }
12782
12783    private long getLowRamTimeSinceIdle(long now) {
12784        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12785    }
12786
12787    @Override
12788    public void performIdleMaintenance() {
12789        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12790                != PackageManager.PERMISSION_GRANTED) {
12791            throw new SecurityException("Requires permission "
12792                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12793        }
12794
12795        synchronized (this) {
12796            final long now = SystemClock.uptimeMillis();
12797            final long timeSinceLastIdle = now - mLastIdleTime;
12798            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12799            mLastIdleTime = now;
12800            mLowRamTimeSinceLastIdle = 0;
12801            if (mLowRamStartTime != 0) {
12802                mLowRamStartTime = now;
12803            }
12804
12805            StringBuilder sb = new StringBuilder(128);
12806            sb.append("Idle maintenance over ");
12807            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12808            sb.append(" low RAM for ");
12809            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12810            Slog.i(TAG, sb.toString());
12811
12812            // If at least 1/3 of our time since the last idle period has been spent
12813            // with RAM low, then we want to kill processes.
12814            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12815
12816            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12817                ProcessRecord proc = mLruProcesses.get(i);
12818                if (proc.notCachedSinceIdle) {
12819                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12820                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12821                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12822                        if (doKilling && proc.initialIdlePss != 0
12823                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12824                            sb = new StringBuilder(128);
12825                            sb.append("Kill");
12826                            sb.append(proc.processName);
12827                            sb.append(" in idle maint: pss=");
12828                            sb.append(proc.lastPss);
12829                            sb.append(", swapPss=");
12830                            sb.append(proc.lastSwapPss);
12831                            sb.append(", initialPss=");
12832                            sb.append(proc.initialIdlePss);
12833                            sb.append(", period=");
12834                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12835                            sb.append(", lowRamPeriod=");
12836                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12837                            Slog.wtfQuiet(TAG, sb.toString());
12838                            proc.kill("idle maint (pss " + proc.lastPss
12839                                    + " from " + proc.initialIdlePss + ")", true);
12840                        }
12841                    }
12842                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12843                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12844                    proc.notCachedSinceIdle = true;
12845                    proc.initialIdlePss = 0;
12846                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12847                            mTestPssMode, isSleeping(), now);
12848                }
12849            }
12850
12851            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12852            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12853        }
12854    }
12855
12856    @Override
12857    public void sendIdleJobTrigger() {
12858        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12859                != PackageManager.PERMISSION_GRANTED) {
12860            throw new SecurityException("Requires permission "
12861                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12862        }
12863
12864        final long ident = Binder.clearCallingIdentity();
12865        try {
12866            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12867                    .setPackage("android")
12868                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12869            broadcastIntent(null, intent, null, null, 0, null, null, null,
12870                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12871        } finally {
12872            Binder.restoreCallingIdentity(ident);
12873        }
12874    }
12875
12876    private void retrieveSettings() {
12877        final ContentResolver resolver = mContext.getContentResolver();
12878        final boolean freeformWindowManagement =
12879                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12880                        || Settings.Global.getInt(
12881                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12882        final boolean supportsPictureInPicture =
12883                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12884
12885        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12886        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12887        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12888        final boolean alwaysFinishActivities =
12889                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12890        final boolean lenientBackgroundCheck =
12891                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12892        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12893        final boolean forceResizable = Settings.Global.getInt(
12894                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12895        final boolean supportsLeanbackOnly =
12896                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12897
12898        // Transfer any global setting for forcing RTL layout, into a System Property
12899        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12900
12901        final Configuration configuration = new Configuration();
12902        Settings.System.getConfiguration(resolver, configuration);
12903        if (forceRtl) {
12904            // This will take care of setting the correct layout direction flags
12905            configuration.setLayoutDirection(configuration.locale);
12906        }
12907
12908        synchronized (this) {
12909            mDebugApp = mOrigDebugApp = debugApp;
12910            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12911            mAlwaysFinishActivities = alwaysFinishActivities;
12912            mLenientBackgroundCheck = lenientBackgroundCheck;
12913            mSupportsLeanbackOnly = supportsLeanbackOnly;
12914            mForceResizableActivities = forceResizable;
12915            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12916            if (supportsMultiWindow || forceResizable) {
12917                mSupportsMultiWindow = true;
12918                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12919                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12920            } else {
12921                mSupportsMultiWindow = false;
12922                mSupportsFreeformWindowManagement = false;
12923                mSupportsPictureInPicture = false;
12924            }
12925            // This happens before any activities are started, so we can
12926            // change mConfiguration in-place.
12927            updateConfigurationLocked(configuration, null, true);
12928            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12929                    "Initial config: " + mConfiguration);
12930
12931            // Load resources only after the current configuration has been set.
12932            final Resources res = mContext.getResources();
12933            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12934            mThumbnailWidth = res.getDimensionPixelSize(
12935                    com.android.internal.R.dimen.thumbnail_width);
12936            mThumbnailHeight = res.getDimensionPixelSize(
12937                    com.android.internal.R.dimen.thumbnail_height);
12938            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12939                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12940            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12941                    com.android.internal.R.string.config_appsNotReportingCrashes));
12942            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12943                mFullscreenThumbnailScale = (float) res
12944                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12945                    (float) mConfiguration.screenWidthDp;
12946            } else {
12947                mFullscreenThumbnailScale = res.getFraction(
12948                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12949            }
12950        }
12951    }
12952
12953    public boolean testIsSystemReady() {
12954        // no need to synchronize(this) just to read & return the value
12955        return mSystemReady;
12956    }
12957
12958    public void systemReady(final Runnable goingCallback) {
12959        synchronized(this) {
12960            if (mSystemReady) {
12961                // If we're done calling all the receivers, run the next "boot phase" passed in
12962                // by the SystemServer
12963                if (goingCallback != null) {
12964                    goingCallback.run();
12965                }
12966                return;
12967            }
12968
12969            mLocalDeviceIdleController
12970                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12971
12972            // Make sure we have the current profile info, since it is needed for security checks.
12973            mUserController.onSystemReady();
12974            mRecentTasks.onSystemReadyLocked();
12975            mAppOpsService.systemReady();
12976            mSystemReady = true;
12977        }
12978
12979        ArrayList<ProcessRecord> procsToKill = null;
12980        synchronized(mPidsSelfLocked) {
12981            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12982                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12983                if (!isAllowedWhileBooting(proc.info)){
12984                    if (procsToKill == null) {
12985                        procsToKill = new ArrayList<ProcessRecord>();
12986                    }
12987                    procsToKill.add(proc);
12988                }
12989            }
12990        }
12991
12992        synchronized(this) {
12993            if (procsToKill != null) {
12994                for (int i=procsToKill.size()-1; i>=0; i--) {
12995                    ProcessRecord proc = procsToKill.get(i);
12996                    Slog.i(TAG, "Removing system update proc: " + proc);
12997                    removeProcessLocked(proc, true, false, "system update done");
12998                }
12999            }
13000
13001            // Now that we have cleaned up any update processes, we
13002            // are ready to start launching real processes and know that
13003            // we won't trample on them any more.
13004            mProcessesReady = true;
13005        }
13006
13007        Slog.i(TAG, "System now ready");
13008        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13009            SystemClock.uptimeMillis());
13010
13011        synchronized(this) {
13012            // Make sure we have no pre-ready processes sitting around.
13013
13014            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13015                ResolveInfo ri = mContext.getPackageManager()
13016                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13017                                STOCK_PM_FLAGS);
13018                CharSequence errorMsg = null;
13019                if (ri != null) {
13020                    ActivityInfo ai = ri.activityInfo;
13021                    ApplicationInfo app = ai.applicationInfo;
13022                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13023                        mTopAction = Intent.ACTION_FACTORY_TEST;
13024                        mTopData = null;
13025                        mTopComponent = new ComponentName(app.packageName,
13026                                ai.name);
13027                    } else {
13028                        errorMsg = mContext.getResources().getText(
13029                                com.android.internal.R.string.factorytest_not_system);
13030                    }
13031                } else {
13032                    errorMsg = mContext.getResources().getText(
13033                            com.android.internal.R.string.factorytest_no_action);
13034                }
13035                if (errorMsg != null) {
13036                    mTopAction = null;
13037                    mTopData = null;
13038                    mTopComponent = null;
13039                    Message msg = Message.obtain();
13040                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13041                    msg.getData().putCharSequence("msg", errorMsg);
13042                    mUiHandler.sendMessage(msg);
13043                }
13044            }
13045        }
13046
13047        retrieveSettings();
13048        final int currentUserId;
13049        synchronized (this) {
13050            currentUserId = mUserController.getCurrentUserIdLocked();
13051            readGrantedUriPermissionsLocked();
13052        }
13053
13054        if (goingCallback != null) goingCallback.run();
13055
13056        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13057                Integer.toString(currentUserId), currentUserId);
13058        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13059                Integer.toString(currentUserId), currentUserId);
13060        mSystemServiceManager.startUser(currentUserId);
13061
13062        synchronized (this) {
13063            // Only start up encryption-aware persistent apps; once user is
13064            // unlocked we'll come back around and start unaware apps
13065            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13066
13067            // Start up initial activity.
13068            mBooting = true;
13069            // Enable home activity for system user, so that the system can always boot
13070            if (UserManager.isSplitSystemUser()) {
13071                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13072                try {
13073                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13074                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13075                            UserHandle.USER_SYSTEM);
13076                } catch (RemoteException e) {
13077                    throw e.rethrowAsRuntimeException();
13078                }
13079            }
13080            startHomeActivityLocked(currentUserId, "systemReady");
13081
13082            try {
13083                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13084                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13085                            + " data partition or your device will be unstable.");
13086                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13087                }
13088            } catch (RemoteException e) {
13089            }
13090
13091            if (!Build.isBuildConsistent()) {
13092                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13093                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13094            }
13095
13096            long ident = Binder.clearCallingIdentity();
13097            try {
13098                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13099                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13100                        | Intent.FLAG_RECEIVER_FOREGROUND);
13101                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13102                broadcastIntentLocked(null, null, intent,
13103                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13104                        null, false, false, MY_PID, Process.SYSTEM_UID,
13105                        currentUserId);
13106                intent = new Intent(Intent.ACTION_USER_STARTING);
13107                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13108                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13109                broadcastIntentLocked(null, null, intent,
13110                        null, new IIntentReceiver.Stub() {
13111                            @Override
13112                            public void performReceive(Intent intent, int resultCode, String data,
13113                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13114                                    throws RemoteException {
13115                            }
13116                        }, 0, null, null,
13117                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13118                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13119            } catch (Throwable t) {
13120                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13121            } finally {
13122                Binder.restoreCallingIdentity(ident);
13123            }
13124            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13125            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13126        }
13127    }
13128
13129    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13130        synchronized (this) {
13131            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13132        }
13133    }
13134
13135    void skipCurrentReceiverLocked(ProcessRecord app) {
13136        for (BroadcastQueue queue : mBroadcastQueues) {
13137            queue.skipCurrentReceiverLocked(app);
13138        }
13139    }
13140
13141    /**
13142     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13143     * The application process will exit immediately after this call returns.
13144     * @param app object of the crashing app, null for the system server
13145     * @param crashInfo describing the exception
13146     */
13147    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13148        ProcessRecord r = findAppProcess(app, "Crash");
13149        final String processName = app == null ? "system_server"
13150                : (r == null ? "unknown" : r.processName);
13151
13152        handleApplicationCrashInner("crash", r, processName, crashInfo);
13153    }
13154
13155    /* Native crash reporting uses this inner version because it needs to be somewhat
13156     * decoupled from the AM-managed cleanup lifecycle
13157     */
13158    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13159            ApplicationErrorReport.CrashInfo crashInfo) {
13160        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13161                UserHandle.getUserId(Binder.getCallingUid()), processName,
13162                r == null ? -1 : r.info.flags,
13163                crashInfo.exceptionClassName,
13164                crashInfo.exceptionMessage,
13165                crashInfo.throwFileName,
13166                crashInfo.throwLineNumber);
13167
13168        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13169
13170        mAppErrors.crashApplication(r, crashInfo);
13171    }
13172
13173    public void handleApplicationStrictModeViolation(
13174            IBinder app,
13175            int violationMask,
13176            StrictMode.ViolationInfo info) {
13177        ProcessRecord r = findAppProcess(app, "StrictMode");
13178        if (r == null) {
13179            return;
13180        }
13181
13182        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13183            Integer stackFingerprint = info.hashCode();
13184            boolean logIt = true;
13185            synchronized (mAlreadyLoggedViolatedStacks) {
13186                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13187                    logIt = false;
13188                    // TODO: sub-sample into EventLog for these, with
13189                    // the info.durationMillis?  Then we'd get
13190                    // the relative pain numbers, without logging all
13191                    // the stack traces repeatedly.  We'd want to do
13192                    // likewise in the client code, which also does
13193                    // dup suppression, before the Binder call.
13194                } else {
13195                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13196                        mAlreadyLoggedViolatedStacks.clear();
13197                    }
13198                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13199                }
13200            }
13201            if (logIt) {
13202                logStrictModeViolationToDropBox(r, info);
13203            }
13204        }
13205
13206        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13207            AppErrorResult result = new AppErrorResult();
13208            synchronized (this) {
13209                final long origId = Binder.clearCallingIdentity();
13210
13211                Message msg = Message.obtain();
13212                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13213                HashMap<String, Object> data = new HashMap<String, Object>();
13214                data.put("result", result);
13215                data.put("app", r);
13216                data.put("violationMask", violationMask);
13217                data.put("info", info);
13218                msg.obj = data;
13219                mUiHandler.sendMessage(msg);
13220
13221                Binder.restoreCallingIdentity(origId);
13222            }
13223            int res = result.get();
13224            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13225        }
13226    }
13227
13228    // Depending on the policy in effect, there could be a bunch of
13229    // these in quick succession so we try to batch these together to
13230    // minimize disk writes, number of dropbox entries, and maximize
13231    // compression, by having more fewer, larger records.
13232    private void logStrictModeViolationToDropBox(
13233            ProcessRecord process,
13234            StrictMode.ViolationInfo info) {
13235        if (info == null) {
13236            return;
13237        }
13238        final boolean isSystemApp = process == null ||
13239                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13240                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13241        final String processName = process == null ? "unknown" : process.processName;
13242        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13243        final DropBoxManager dbox = (DropBoxManager)
13244                mContext.getSystemService(Context.DROPBOX_SERVICE);
13245
13246        // Exit early if the dropbox isn't configured to accept this report type.
13247        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13248
13249        boolean bufferWasEmpty;
13250        boolean needsFlush;
13251        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13252        synchronized (sb) {
13253            bufferWasEmpty = sb.length() == 0;
13254            appendDropBoxProcessHeaders(process, processName, sb);
13255            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13256            sb.append("System-App: ").append(isSystemApp).append("\n");
13257            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13258            if (info.violationNumThisLoop != 0) {
13259                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13260            }
13261            if (info.numAnimationsRunning != 0) {
13262                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13263            }
13264            if (info.broadcastIntentAction != null) {
13265                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13266            }
13267            if (info.durationMillis != -1) {
13268                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13269            }
13270            if (info.numInstances != -1) {
13271                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13272            }
13273            if (info.tags != null) {
13274                for (String tag : info.tags) {
13275                    sb.append("Span-Tag: ").append(tag).append("\n");
13276                }
13277            }
13278            sb.append("\n");
13279            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13280                sb.append(info.crashInfo.stackTrace);
13281                sb.append("\n");
13282            }
13283            if (info.message != null) {
13284                sb.append(info.message);
13285                sb.append("\n");
13286            }
13287
13288            // Only buffer up to ~64k.  Various logging bits truncate
13289            // things at 128k.
13290            needsFlush = (sb.length() > 64 * 1024);
13291        }
13292
13293        // Flush immediately if the buffer's grown too large, or this
13294        // is a non-system app.  Non-system apps are isolated with a
13295        // different tag & policy and not batched.
13296        //
13297        // Batching is useful during internal testing with
13298        // StrictMode settings turned up high.  Without batching,
13299        // thousands of separate files could be created on boot.
13300        if (!isSystemApp || needsFlush) {
13301            new Thread("Error dump: " + dropboxTag) {
13302                @Override
13303                public void run() {
13304                    String report;
13305                    synchronized (sb) {
13306                        report = sb.toString();
13307                        sb.delete(0, sb.length());
13308                        sb.trimToSize();
13309                    }
13310                    if (report.length() != 0) {
13311                        dbox.addText(dropboxTag, report);
13312                    }
13313                }
13314            }.start();
13315            return;
13316        }
13317
13318        // System app batching:
13319        if (!bufferWasEmpty) {
13320            // An existing dropbox-writing thread is outstanding, so
13321            // we don't need to start it up.  The existing thread will
13322            // catch the buffer appends we just did.
13323            return;
13324        }
13325
13326        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13327        // (After this point, we shouldn't access AMS internal data structures.)
13328        new Thread("Error dump: " + dropboxTag) {
13329            @Override
13330            public void run() {
13331                // 5 second sleep to let stacks arrive and be batched together
13332                try {
13333                    Thread.sleep(5000);  // 5 seconds
13334                } catch (InterruptedException e) {}
13335
13336                String errorReport;
13337                synchronized (mStrictModeBuffer) {
13338                    errorReport = mStrictModeBuffer.toString();
13339                    if (errorReport.length() == 0) {
13340                        return;
13341                    }
13342                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13343                    mStrictModeBuffer.trimToSize();
13344                }
13345                dbox.addText(dropboxTag, errorReport);
13346            }
13347        }.start();
13348    }
13349
13350    /**
13351     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13352     * @param app object of the crashing app, null for the system server
13353     * @param tag reported by the caller
13354     * @param system whether this wtf is coming from the system
13355     * @param crashInfo describing the context of the error
13356     * @return true if the process should exit immediately (WTF is fatal)
13357     */
13358    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13359            final ApplicationErrorReport.CrashInfo crashInfo) {
13360        final int callingUid = Binder.getCallingUid();
13361        final int callingPid = Binder.getCallingPid();
13362
13363        if (system) {
13364            // If this is coming from the system, we could very well have low-level
13365            // system locks held, so we want to do this all asynchronously.  And we
13366            // never want this to become fatal, so there is that too.
13367            mHandler.post(new Runnable() {
13368                @Override public void run() {
13369                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13370                }
13371            });
13372            return false;
13373        }
13374
13375        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13376                crashInfo);
13377
13378        if (r != null && r.pid != Process.myPid() &&
13379                Settings.Global.getInt(mContext.getContentResolver(),
13380                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13381            mAppErrors.crashApplication(r, crashInfo);
13382            return true;
13383        } else {
13384            return false;
13385        }
13386    }
13387
13388    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13389            final ApplicationErrorReport.CrashInfo crashInfo) {
13390        final ProcessRecord r = findAppProcess(app, "WTF");
13391        final String processName = app == null ? "system_server"
13392                : (r == null ? "unknown" : r.processName);
13393
13394        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13395                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13396
13397        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13398
13399        return r;
13400    }
13401
13402    /**
13403     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13404     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13405     */
13406    private ProcessRecord findAppProcess(IBinder app, String reason) {
13407        if (app == null) {
13408            return null;
13409        }
13410
13411        synchronized (this) {
13412            final int NP = mProcessNames.getMap().size();
13413            for (int ip=0; ip<NP; ip++) {
13414                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13415                final int NA = apps.size();
13416                for (int ia=0; ia<NA; ia++) {
13417                    ProcessRecord p = apps.valueAt(ia);
13418                    if (p.thread != null && p.thread.asBinder() == app) {
13419                        return p;
13420                    }
13421                }
13422            }
13423
13424            Slog.w(TAG, "Can't find mystery application for " + reason
13425                    + " from pid=" + Binder.getCallingPid()
13426                    + " uid=" + Binder.getCallingUid() + ": " + app);
13427            return null;
13428        }
13429    }
13430
13431    /**
13432     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13433     * to append various headers to the dropbox log text.
13434     */
13435    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13436            StringBuilder sb) {
13437        // Watchdog thread ends up invoking this function (with
13438        // a null ProcessRecord) to add the stack file to dropbox.
13439        // Do not acquire a lock on this (am) in such cases, as it
13440        // could cause a potential deadlock, if and when watchdog
13441        // is invoked due to unavailability of lock on am and it
13442        // would prevent watchdog from killing system_server.
13443        if (process == null) {
13444            sb.append("Process: ").append(processName).append("\n");
13445            return;
13446        }
13447        // Note: ProcessRecord 'process' is guarded by the service
13448        // instance.  (notably process.pkgList, which could otherwise change
13449        // concurrently during execution of this method)
13450        synchronized (this) {
13451            sb.append("Process: ").append(processName).append("\n");
13452            int flags = process.info.flags;
13453            IPackageManager pm = AppGlobals.getPackageManager();
13454            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13455            for (int ip=0; ip<process.pkgList.size(); ip++) {
13456                String pkg = process.pkgList.keyAt(ip);
13457                sb.append("Package: ").append(pkg);
13458                try {
13459                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13460                    if (pi != null) {
13461                        sb.append(" v").append(pi.versionCode);
13462                        if (pi.versionName != null) {
13463                            sb.append(" (").append(pi.versionName).append(")");
13464                        }
13465                    }
13466                } catch (RemoteException e) {
13467                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13468                }
13469                sb.append("\n");
13470            }
13471        }
13472    }
13473
13474    private static String processClass(ProcessRecord process) {
13475        if (process == null || process.pid == MY_PID) {
13476            return "system_server";
13477        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13478            return "system_app";
13479        } else {
13480            return "data_app";
13481        }
13482    }
13483
13484    private volatile long mWtfClusterStart;
13485    private volatile int mWtfClusterCount;
13486
13487    /**
13488     * Write a description of an error (crash, WTF, ANR) to the drop box.
13489     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13490     * @param process which caused the error, null means the system server
13491     * @param activity which triggered the error, null if unknown
13492     * @param parent activity related to the error, null if unknown
13493     * @param subject line related to the error, null if absent
13494     * @param report in long form describing the error, null if absent
13495     * @param dataFile text file to include in the report, null if none
13496     * @param crashInfo giving an application stack trace, null if absent
13497     */
13498    public void addErrorToDropBox(String eventType,
13499            ProcessRecord process, String processName, ActivityRecord activity,
13500            ActivityRecord parent, String subject,
13501            final String report, final File dataFile,
13502            final ApplicationErrorReport.CrashInfo crashInfo) {
13503        // NOTE -- this must never acquire the ActivityManagerService lock,
13504        // otherwise the watchdog may be prevented from resetting the system.
13505
13506        final String dropboxTag = processClass(process) + "_" + eventType;
13507        final DropBoxManager dbox = (DropBoxManager)
13508                mContext.getSystemService(Context.DROPBOX_SERVICE);
13509
13510        // Exit early if the dropbox isn't configured to accept this report type.
13511        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13512
13513        // Rate-limit how often we're willing to do the heavy lifting below to
13514        // collect and record logs; currently 5 logs per 10 second period.
13515        final long now = SystemClock.elapsedRealtime();
13516        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13517            mWtfClusterStart = now;
13518            mWtfClusterCount = 1;
13519        } else {
13520            if (mWtfClusterCount++ >= 5) return;
13521        }
13522
13523        final StringBuilder sb = new StringBuilder(1024);
13524        appendDropBoxProcessHeaders(process, processName, sb);
13525        if (process != null) {
13526            sb.append("Foreground: ")
13527                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13528                    .append("\n");
13529        }
13530        if (activity != null) {
13531            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13532        }
13533        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13534            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13535        }
13536        if (parent != null && parent != activity) {
13537            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13538        }
13539        if (subject != null) {
13540            sb.append("Subject: ").append(subject).append("\n");
13541        }
13542        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13543        if (Debug.isDebuggerConnected()) {
13544            sb.append("Debugger: Connected\n");
13545        }
13546        sb.append("\n");
13547
13548        // Do the rest in a worker thread to avoid blocking the caller on I/O
13549        // (After this point, we shouldn't access AMS internal data structures.)
13550        Thread worker = new Thread("Error dump: " + dropboxTag) {
13551            @Override
13552            public void run() {
13553                if (report != null) {
13554                    sb.append(report);
13555                }
13556
13557                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13558                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13559                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13560                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13561
13562                if (dataFile != null && maxDataFileSize > 0) {
13563                    try {
13564                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13565                                    "\n\n[[TRUNCATED]]"));
13566                    } catch (IOException e) {
13567                        Slog.e(TAG, "Error reading " + dataFile, e);
13568                    }
13569                }
13570                if (crashInfo != null && crashInfo.stackTrace != null) {
13571                    sb.append(crashInfo.stackTrace);
13572                }
13573
13574                if (lines > 0) {
13575                    sb.append("\n");
13576
13577                    // Merge several logcat streams, and take the last N lines
13578                    InputStreamReader input = null;
13579                    try {
13580                        java.lang.Process logcat = new ProcessBuilder(
13581                                "/system/bin/timeout", "-k", "15s", "10s",
13582                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13583                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13584                                        .redirectErrorStream(true).start();
13585
13586                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13587                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13588                        input = new InputStreamReader(logcat.getInputStream());
13589
13590                        int num;
13591                        char[] buf = new char[8192];
13592                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13593                    } catch (IOException e) {
13594                        Slog.e(TAG, "Error running logcat", e);
13595                    } finally {
13596                        if (input != null) try { input.close(); } catch (IOException e) {}
13597                    }
13598                }
13599
13600                dbox.addText(dropboxTag, sb.toString());
13601            }
13602        };
13603
13604        if (process == null) {
13605            // If process is null, we are being called from some internal code
13606            // and may be about to die -- run this synchronously.
13607            worker.run();
13608        } else {
13609            worker.start();
13610        }
13611    }
13612
13613    @Override
13614    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13615        enforceNotIsolatedCaller("getProcessesInErrorState");
13616        // assume our apps are happy - lazy create the list
13617        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13618
13619        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13620                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13621        int userId = UserHandle.getUserId(Binder.getCallingUid());
13622
13623        synchronized (this) {
13624
13625            // iterate across all processes
13626            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13627                ProcessRecord app = mLruProcesses.get(i);
13628                if (!allUsers && app.userId != userId) {
13629                    continue;
13630                }
13631                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13632                    // This one's in trouble, so we'll generate a report for it
13633                    // crashes are higher priority (in case there's a crash *and* an anr)
13634                    ActivityManager.ProcessErrorStateInfo report = null;
13635                    if (app.crashing) {
13636                        report = app.crashingReport;
13637                    } else if (app.notResponding) {
13638                        report = app.notRespondingReport;
13639                    }
13640
13641                    if (report != null) {
13642                        if (errList == null) {
13643                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13644                        }
13645                        errList.add(report);
13646                    } else {
13647                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13648                                " crashing = " + app.crashing +
13649                                " notResponding = " + app.notResponding);
13650                    }
13651                }
13652            }
13653        }
13654
13655        return errList;
13656    }
13657
13658    static int procStateToImportance(int procState, int memAdj,
13659            ActivityManager.RunningAppProcessInfo currApp) {
13660        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13661        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13662            currApp.lru = memAdj;
13663        } else {
13664            currApp.lru = 0;
13665        }
13666        return imp;
13667    }
13668
13669    private void fillInProcMemInfo(ProcessRecord app,
13670            ActivityManager.RunningAppProcessInfo outInfo) {
13671        outInfo.pid = app.pid;
13672        outInfo.uid = app.info.uid;
13673        if (mHeavyWeightProcess == app) {
13674            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13675        }
13676        if (app.persistent) {
13677            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13678        }
13679        if (app.activities.size() > 0) {
13680            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13681        }
13682        outInfo.lastTrimLevel = app.trimMemoryLevel;
13683        int adj = app.curAdj;
13684        int procState = app.curProcState;
13685        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13686        outInfo.importanceReasonCode = app.adjTypeCode;
13687        outInfo.processState = app.curProcState;
13688    }
13689
13690    @Override
13691    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13692        enforceNotIsolatedCaller("getRunningAppProcesses");
13693
13694        final int callingUid = Binder.getCallingUid();
13695
13696        // Lazy instantiation of list
13697        List<ActivityManager.RunningAppProcessInfo> runList = null;
13698        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13699                callingUid) == PackageManager.PERMISSION_GRANTED;
13700        final int userId = UserHandle.getUserId(callingUid);
13701        final boolean allUids = isGetTasksAllowed(
13702                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13703
13704        synchronized (this) {
13705            // Iterate across all processes
13706            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13707                ProcessRecord app = mLruProcesses.get(i);
13708                if ((!allUsers && app.userId != userId)
13709                        || (!allUids && app.uid != callingUid)) {
13710                    continue;
13711                }
13712                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13713                    // Generate process state info for running application
13714                    ActivityManager.RunningAppProcessInfo currApp =
13715                        new ActivityManager.RunningAppProcessInfo(app.processName,
13716                                app.pid, app.getPackageList());
13717                    fillInProcMemInfo(app, currApp);
13718                    if (app.adjSource instanceof ProcessRecord) {
13719                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13720                        currApp.importanceReasonImportance =
13721                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13722                                        app.adjSourceProcState);
13723                    } else if (app.adjSource instanceof ActivityRecord) {
13724                        ActivityRecord r = (ActivityRecord)app.adjSource;
13725                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13726                    }
13727                    if (app.adjTarget instanceof ComponentName) {
13728                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13729                    }
13730                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13731                    //        + " lru=" + currApp.lru);
13732                    if (runList == null) {
13733                        runList = new ArrayList<>();
13734                    }
13735                    runList.add(currApp);
13736                }
13737            }
13738        }
13739        return runList;
13740    }
13741
13742    @Override
13743    public List<ApplicationInfo> getRunningExternalApplications() {
13744        enforceNotIsolatedCaller("getRunningExternalApplications");
13745        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13746        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13747        if (runningApps != null && runningApps.size() > 0) {
13748            Set<String> extList = new HashSet<String>();
13749            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13750                if (app.pkgList != null) {
13751                    for (String pkg : app.pkgList) {
13752                        extList.add(pkg);
13753                    }
13754                }
13755            }
13756            IPackageManager pm = AppGlobals.getPackageManager();
13757            for (String pkg : extList) {
13758                try {
13759                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13760                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13761                        retList.add(info);
13762                    }
13763                } catch (RemoteException e) {
13764                }
13765            }
13766        }
13767        return retList;
13768    }
13769
13770    @Override
13771    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13772        enforceNotIsolatedCaller("getMyMemoryState");
13773        synchronized (this) {
13774            ProcessRecord proc;
13775            synchronized (mPidsSelfLocked) {
13776                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13777            }
13778            fillInProcMemInfo(proc, outInfo);
13779        }
13780    }
13781
13782    @Override
13783    public int getMemoryTrimLevel() {
13784        enforceNotIsolatedCaller("getMyMemoryState");
13785        synchronized (this) {
13786            return mLastMemoryLevel;
13787        }
13788    }
13789
13790    @Override
13791    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13792            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13793        (new ActivityManagerShellCommand(this, false)).exec(
13794                this, in, out, err, args, resultReceiver);
13795    }
13796
13797    @Override
13798    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13799        if (checkCallingPermission(android.Manifest.permission.DUMP)
13800                != PackageManager.PERMISSION_GRANTED) {
13801            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13802                    + Binder.getCallingPid()
13803                    + ", uid=" + Binder.getCallingUid()
13804                    + " without permission "
13805                    + android.Manifest.permission.DUMP);
13806            return;
13807        }
13808
13809        boolean dumpAll = false;
13810        boolean dumpClient = false;
13811        boolean dumpCheckin = false;
13812        boolean dumpCheckinFormat = false;
13813        String dumpPackage = null;
13814
13815        int opti = 0;
13816        while (opti < args.length) {
13817            String opt = args[opti];
13818            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13819                break;
13820            }
13821            opti++;
13822            if ("-a".equals(opt)) {
13823                dumpAll = true;
13824            } else if ("-c".equals(opt)) {
13825                dumpClient = true;
13826            } else if ("-p".equals(opt)) {
13827                if (opti < args.length) {
13828                    dumpPackage = args[opti];
13829                    opti++;
13830                } else {
13831                    pw.println("Error: -p option requires package argument");
13832                    return;
13833                }
13834                dumpClient = true;
13835            } else if ("--checkin".equals(opt)) {
13836                dumpCheckin = dumpCheckinFormat = true;
13837            } else if ("-C".equals(opt)) {
13838                dumpCheckinFormat = true;
13839            } else if ("-h".equals(opt)) {
13840                ActivityManagerShellCommand.dumpHelp(pw, true);
13841                return;
13842            } else {
13843                pw.println("Unknown argument: " + opt + "; use -h for help");
13844            }
13845        }
13846
13847        long origId = Binder.clearCallingIdentity();
13848        boolean more = false;
13849        // Is the caller requesting to dump a particular piece of data?
13850        if (opti < args.length) {
13851            String cmd = args[opti];
13852            opti++;
13853            if ("activities".equals(cmd) || "a".equals(cmd)) {
13854                synchronized (this) {
13855                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13856                }
13857            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13858                synchronized (this) {
13859                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13860                }
13861            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13862                String[] newArgs;
13863                String name;
13864                if (opti >= args.length) {
13865                    name = null;
13866                    newArgs = EMPTY_STRING_ARRAY;
13867                } else {
13868                    dumpPackage = args[opti];
13869                    opti++;
13870                    newArgs = new String[args.length - opti];
13871                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13872                            args.length - opti);
13873                }
13874                synchronized (this) {
13875                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13876                }
13877            } else if ("broadcast-stats".equals(cmd)) {
13878                String[] newArgs;
13879                String name;
13880                if (opti >= args.length) {
13881                    name = null;
13882                    newArgs = EMPTY_STRING_ARRAY;
13883                } else {
13884                    dumpPackage = args[opti];
13885                    opti++;
13886                    newArgs = new String[args.length - opti];
13887                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13888                            args.length - opti);
13889                }
13890                synchronized (this) {
13891                    dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13892                }
13893            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13894                String[] newArgs;
13895                String name;
13896                if (opti >= args.length) {
13897                    name = null;
13898                    newArgs = EMPTY_STRING_ARRAY;
13899                } else {
13900                    dumpPackage = args[opti];
13901                    opti++;
13902                    newArgs = new String[args.length - opti];
13903                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13904                            args.length - opti);
13905                }
13906                synchronized (this) {
13907                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13908                }
13909            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13910                String[] newArgs;
13911                String name;
13912                if (opti >= args.length) {
13913                    name = null;
13914                    newArgs = EMPTY_STRING_ARRAY;
13915                } else {
13916                    dumpPackage = args[opti];
13917                    opti++;
13918                    newArgs = new String[args.length - opti];
13919                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13920                            args.length - opti);
13921                }
13922                synchronized (this) {
13923                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13924                }
13925            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13926                synchronized (this) {
13927                    dumpOomLocked(fd, pw, args, opti, true);
13928                }
13929            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13930                synchronized (this) {
13931                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13932                }
13933            } else if ("provider".equals(cmd)) {
13934                String[] newArgs;
13935                String name;
13936                if (opti >= args.length) {
13937                    name = null;
13938                    newArgs = EMPTY_STRING_ARRAY;
13939                } else {
13940                    name = args[opti];
13941                    opti++;
13942                    newArgs = new String[args.length - opti];
13943                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13944                }
13945                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13946                    pw.println("No providers match: " + name);
13947                    pw.println("Use -h for help.");
13948                }
13949            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13950                synchronized (this) {
13951                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13952                }
13953            } else if ("service".equals(cmd)) {
13954                String[] newArgs;
13955                String name;
13956                if (opti >= args.length) {
13957                    name = null;
13958                    newArgs = EMPTY_STRING_ARRAY;
13959                } else {
13960                    name = args[opti];
13961                    opti++;
13962                    newArgs = new String[args.length - opti];
13963                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13964                            args.length - opti);
13965                }
13966                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13967                    pw.println("No services match: " + name);
13968                    pw.println("Use -h for help.");
13969                }
13970            } else if ("package".equals(cmd)) {
13971                String[] newArgs;
13972                if (opti >= args.length) {
13973                    pw.println("package: no package name specified");
13974                    pw.println("Use -h for help.");
13975                } else {
13976                    dumpPackage = args[opti];
13977                    opti++;
13978                    newArgs = new String[args.length - opti];
13979                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13980                            args.length - opti);
13981                    args = newArgs;
13982                    opti = 0;
13983                    more = true;
13984                }
13985            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13986                synchronized (this) {
13987                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13988                }
13989            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13990                if (dumpClient) {
13991                    ActiveServices.ServiceDumper dumper;
13992                    synchronized (this) {
13993                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13994                                dumpPackage);
13995                    }
13996                    dumper.dumpWithClient();
13997                } else {
13998                    synchronized (this) {
13999                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14000                                dumpPackage).dumpLocked();
14001                    }
14002                }
14003            } else if ("locks".equals(cmd)) {
14004                LockGuard.dump(fd, pw, args);
14005            } else {
14006                // Dumping a single activity?
14007                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14008                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14009                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14010                    if (res < 0) {
14011                        pw.println("Bad activity command, or no activities match: " + cmd);
14012                        pw.println("Use -h for help.");
14013                    }
14014                }
14015            }
14016            if (!more) {
14017                Binder.restoreCallingIdentity(origId);
14018                return;
14019            }
14020        }
14021
14022        // No piece of data specified, dump everything.
14023        if (dumpCheckinFormat) {
14024            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14025        } else if (dumpClient) {
14026            ActiveServices.ServiceDumper sdumper;
14027            synchronized (this) {
14028                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14029                pw.println();
14030                if (dumpAll) {
14031                    pw.println("-------------------------------------------------------------------------------");
14032                }
14033                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14034                pw.println();
14035                if (dumpAll) {
14036                    pw.println("-------------------------------------------------------------------------------");
14037                }
14038                if (dumpAll || dumpPackage != null) {
14039                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14040                    pw.println();
14041                    if (dumpAll) {
14042                        pw.println("-------------------------------------------------------------------------------");
14043                    }
14044                }
14045                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14046                pw.println();
14047                if (dumpAll) {
14048                    pw.println("-------------------------------------------------------------------------------");
14049                }
14050                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14051                pw.println();
14052                if (dumpAll) {
14053                    pw.println("-------------------------------------------------------------------------------");
14054                }
14055                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14056                        dumpPackage);
14057            }
14058            sdumper.dumpWithClient();
14059            pw.println();
14060            synchronized (this) {
14061                if (dumpAll) {
14062                    pw.println("-------------------------------------------------------------------------------");
14063                }
14064                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14065                pw.println();
14066                if (dumpAll) {
14067                    pw.println("-------------------------------------------------------------------------------");
14068                }
14069                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14070                if (mAssociations.size() > 0) {
14071                    pw.println();
14072                    if (dumpAll) {
14073                        pw.println("-------------------------------------------------------------------------------");
14074                    }
14075                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14076                }
14077                pw.println();
14078                if (dumpAll) {
14079                    pw.println("-------------------------------------------------------------------------------");
14080                }
14081                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14082            }
14083
14084        } else {
14085            synchronized (this) {
14086                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14087                pw.println();
14088                if (dumpAll) {
14089                    pw.println("-------------------------------------------------------------------------------");
14090                }
14091                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14092                pw.println();
14093                if (dumpAll) {
14094                    pw.println("-------------------------------------------------------------------------------");
14095                }
14096                if (dumpAll || dumpPackage != null) {
14097                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14098                    pw.println();
14099                    if (dumpAll) {
14100                        pw.println("-------------------------------------------------------------------------------");
14101                    }
14102                }
14103                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14104                pw.println();
14105                if (dumpAll) {
14106                    pw.println("-------------------------------------------------------------------------------");
14107                }
14108                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14109                pw.println();
14110                if (dumpAll) {
14111                    pw.println("-------------------------------------------------------------------------------");
14112                }
14113                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14114                        .dumpLocked();
14115                pw.println();
14116                if (dumpAll) {
14117                    pw.println("-------------------------------------------------------------------------------");
14118                }
14119                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14120                pw.println();
14121                if (dumpAll) {
14122                    pw.println("-------------------------------------------------------------------------------");
14123                }
14124                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14125                if (mAssociations.size() > 0) {
14126                    pw.println();
14127                    if (dumpAll) {
14128                        pw.println("-------------------------------------------------------------------------------");
14129                    }
14130                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14131                }
14132                pw.println();
14133                if (dumpAll) {
14134                    pw.println("-------------------------------------------------------------------------------");
14135                }
14136                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14137            }
14138        }
14139        Binder.restoreCallingIdentity(origId);
14140    }
14141
14142    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14143            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14144        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14145
14146        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14147                dumpPackage);
14148        boolean needSep = printedAnything;
14149
14150        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14151                dumpPackage, needSep, "  mFocusedActivity: ");
14152        if (printed) {
14153            printedAnything = true;
14154            needSep = false;
14155        }
14156
14157        if (dumpPackage == null) {
14158            if (needSep) {
14159                pw.println();
14160            }
14161            needSep = true;
14162            printedAnything = true;
14163            mStackSupervisor.dump(pw, "  ");
14164        }
14165
14166        if (!printedAnything) {
14167            pw.println("  (nothing)");
14168        }
14169    }
14170
14171    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14172            int opti, boolean dumpAll, String dumpPackage) {
14173        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14174
14175        boolean printedAnything = false;
14176
14177        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14178            boolean printedHeader = false;
14179
14180            final int N = mRecentTasks.size();
14181            for (int i=0; i<N; i++) {
14182                TaskRecord tr = mRecentTasks.get(i);
14183                if (dumpPackage != null) {
14184                    if (tr.realActivity == null ||
14185                            !dumpPackage.equals(tr.realActivity)) {
14186                        continue;
14187                    }
14188                }
14189                if (!printedHeader) {
14190                    pw.println("  Recent tasks:");
14191                    printedHeader = true;
14192                    printedAnything = true;
14193                }
14194                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14195                        pw.println(tr);
14196                if (dumpAll) {
14197                    mRecentTasks.get(i).dump(pw, "    ");
14198                }
14199            }
14200        }
14201
14202        if (!printedAnything) {
14203            pw.println("  (nothing)");
14204        }
14205    }
14206
14207    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14208            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14209        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14210
14211        int dumpUid = 0;
14212        if (dumpPackage != null) {
14213            IPackageManager pm = AppGlobals.getPackageManager();
14214            try {
14215                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14216            } catch (RemoteException e) {
14217            }
14218        }
14219
14220        boolean printedAnything = false;
14221
14222        final long now = SystemClock.uptimeMillis();
14223
14224        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14225            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14226                    = mAssociations.valueAt(i1);
14227            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14228                SparseArray<ArrayMap<String, Association>> sourceUids
14229                        = targetComponents.valueAt(i2);
14230                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14231                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14232                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14233                        Association ass = sourceProcesses.valueAt(i4);
14234                        if (dumpPackage != null) {
14235                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14236                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14237                                continue;
14238                            }
14239                        }
14240                        printedAnything = true;
14241                        pw.print("  ");
14242                        pw.print(ass.mTargetProcess);
14243                        pw.print("/");
14244                        UserHandle.formatUid(pw, ass.mTargetUid);
14245                        pw.print(" <- ");
14246                        pw.print(ass.mSourceProcess);
14247                        pw.print("/");
14248                        UserHandle.formatUid(pw, ass.mSourceUid);
14249                        pw.println();
14250                        pw.print("    via ");
14251                        pw.print(ass.mTargetComponent.flattenToShortString());
14252                        pw.println();
14253                        pw.print("    ");
14254                        long dur = ass.mTime;
14255                        if (ass.mNesting > 0) {
14256                            dur += now - ass.mStartTime;
14257                        }
14258                        TimeUtils.formatDuration(dur, pw);
14259                        pw.print(" (");
14260                        pw.print(ass.mCount);
14261                        pw.print(" times)");
14262                        pw.print("  ");
14263                        for (int i=0; i<ass.mStateTimes.length; i++) {
14264                            long amt = ass.mStateTimes[i];
14265                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14266                                amt += now - ass.mLastStateUptime;
14267                            }
14268                            if (amt != 0) {
14269                                pw.print(" ");
14270                                pw.print(ProcessList.makeProcStateString(
14271                                            i + ActivityManager.MIN_PROCESS_STATE));
14272                                pw.print("=");
14273                                TimeUtils.formatDuration(amt, pw);
14274                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14275                                    pw.print("*");
14276                                }
14277                            }
14278                        }
14279                        pw.println();
14280                        if (ass.mNesting > 0) {
14281                            pw.print("    Currently active: ");
14282                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14283                            pw.println();
14284                        }
14285                    }
14286                }
14287            }
14288
14289        }
14290
14291        if (!printedAnything) {
14292            pw.println("  (nothing)");
14293        }
14294    }
14295
14296    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14297            String header, boolean needSep) {
14298        boolean printed = false;
14299        int whichAppId = -1;
14300        if (dumpPackage != null) {
14301            try {
14302                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14303                        dumpPackage, 0);
14304                whichAppId = UserHandle.getAppId(info.uid);
14305            } catch (NameNotFoundException e) {
14306                e.printStackTrace();
14307            }
14308        }
14309        for (int i=0; i<uids.size(); i++) {
14310            UidRecord uidRec = uids.valueAt(i);
14311            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14312                continue;
14313            }
14314            if (!printed) {
14315                printed = true;
14316                if (needSep) {
14317                    pw.println();
14318                }
14319                pw.print("  ");
14320                pw.println(header);
14321                needSep = true;
14322            }
14323            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14324            pw.print(": "); pw.println(uidRec);
14325        }
14326        return printed;
14327    }
14328
14329    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14330            int opti, boolean dumpAll, String dumpPackage) {
14331        boolean needSep = false;
14332        boolean printedAnything = false;
14333        int numPers = 0;
14334
14335        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14336
14337        if (dumpAll) {
14338            final int NP = mProcessNames.getMap().size();
14339            for (int ip=0; ip<NP; ip++) {
14340                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14341                final int NA = procs.size();
14342                for (int ia=0; ia<NA; ia++) {
14343                    ProcessRecord r = procs.valueAt(ia);
14344                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14345                        continue;
14346                    }
14347                    if (!needSep) {
14348                        pw.println("  All known processes:");
14349                        needSep = true;
14350                        printedAnything = true;
14351                    }
14352                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14353                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14354                        pw.print(" "); pw.println(r);
14355                    r.dump(pw, "    ");
14356                    if (r.persistent) {
14357                        numPers++;
14358                    }
14359                }
14360            }
14361        }
14362
14363        if (mIsolatedProcesses.size() > 0) {
14364            boolean printed = false;
14365            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14366                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14367                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14368                    continue;
14369                }
14370                if (!printed) {
14371                    if (needSep) {
14372                        pw.println();
14373                    }
14374                    pw.println("  Isolated process list (sorted by uid):");
14375                    printedAnything = true;
14376                    printed = true;
14377                    needSep = true;
14378                }
14379                pw.println(String.format("%sIsolated #%2d: %s",
14380                        "    ", i, r.toString()));
14381            }
14382        }
14383
14384        if (mActiveUids.size() > 0) {
14385            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14386                printedAnything = needSep = true;
14387            }
14388        }
14389        if (mValidateUids.size() > 0) {
14390            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14391                printedAnything = needSep = true;
14392            }
14393        }
14394
14395        if (mLruProcesses.size() > 0) {
14396            if (needSep) {
14397                pw.println();
14398            }
14399            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14400                    pw.print(" total, non-act at ");
14401                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14402                    pw.print(", non-svc at ");
14403                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14404                    pw.println("):");
14405            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14406            needSep = true;
14407            printedAnything = true;
14408        }
14409
14410        if (dumpAll || dumpPackage != null) {
14411            synchronized (mPidsSelfLocked) {
14412                boolean printed = false;
14413                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14414                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14415                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14416                        continue;
14417                    }
14418                    if (!printed) {
14419                        if (needSep) pw.println();
14420                        needSep = true;
14421                        pw.println("  PID mappings:");
14422                        printed = true;
14423                        printedAnything = true;
14424                    }
14425                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14426                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14427                }
14428            }
14429        }
14430
14431        if (mForegroundProcesses.size() > 0) {
14432            synchronized (mPidsSelfLocked) {
14433                boolean printed = false;
14434                for (int i=0; i<mForegroundProcesses.size(); i++) {
14435                    ProcessRecord r = mPidsSelfLocked.get(
14436                            mForegroundProcesses.valueAt(i).pid);
14437                    if (dumpPackage != null && (r == null
14438                            || !r.pkgList.containsKey(dumpPackage))) {
14439                        continue;
14440                    }
14441                    if (!printed) {
14442                        if (needSep) pw.println();
14443                        needSep = true;
14444                        pw.println("  Foreground Processes:");
14445                        printed = true;
14446                        printedAnything = true;
14447                    }
14448                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14449                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14450                }
14451            }
14452        }
14453
14454        if (mPersistentStartingProcesses.size() > 0) {
14455            if (needSep) pw.println();
14456            needSep = true;
14457            printedAnything = true;
14458            pw.println("  Persisent processes that are starting:");
14459            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14460                    "Starting Norm", "Restarting PERS", dumpPackage);
14461        }
14462
14463        if (mRemovedProcesses.size() > 0) {
14464            if (needSep) pw.println();
14465            needSep = true;
14466            printedAnything = true;
14467            pw.println("  Processes that are being removed:");
14468            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14469                    "Removed Norm", "Removed PERS", dumpPackage);
14470        }
14471
14472        if (mProcessesOnHold.size() > 0) {
14473            if (needSep) pw.println();
14474            needSep = true;
14475            printedAnything = true;
14476            pw.println("  Processes that are on old until the system is ready:");
14477            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14478                    "OnHold Norm", "OnHold PERS", dumpPackage);
14479        }
14480
14481        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14482
14483        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14484        if (needSep) {
14485            printedAnything = true;
14486        }
14487
14488        if (dumpPackage == null) {
14489            pw.println();
14490            needSep = false;
14491            mUserController.dump(pw, dumpAll);
14492        }
14493        if (mHomeProcess != null && (dumpPackage == null
14494                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14495            if (needSep) {
14496                pw.println();
14497                needSep = false;
14498            }
14499            pw.println("  mHomeProcess: " + mHomeProcess);
14500        }
14501        if (mPreviousProcess != null && (dumpPackage == null
14502                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14503            if (needSep) {
14504                pw.println();
14505                needSep = false;
14506            }
14507            pw.println("  mPreviousProcess: " + mPreviousProcess);
14508        }
14509        if (dumpAll) {
14510            StringBuilder sb = new StringBuilder(128);
14511            sb.append("  mPreviousProcessVisibleTime: ");
14512            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14513            pw.println(sb);
14514        }
14515        if (mHeavyWeightProcess != null && (dumpPackage == null
14516                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14517            if (needSep) {
14518                pw.println();
14519                needSep = false;
14520            }
14521            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14522        }
14523        if (dumpPackage == null) {
14524            pw.println("  mConfiguration: " + mConfiguration);
14525        }
14526        if (dumpAll) {
14527            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14528            if (mCompatModePackages.getPackages().size() > 0) {
14529                boolean printed = false;
14530                for (Map.Entry<String, Integer> entry
14531                        : mCompatModePackages.getPackages().entrySet()) {
14532                    String pkg = entry.getKey();
14533                    int mode = entry.getValue();
14534                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14535                        continue;
14536                    }
14537                    if (!printed) {
14538                        pw.println("  mScreenCompatPackages:");
14539                        printed = true;
14540                    }
14541                    pw.print("    "); pw.print(pkg); pw.print(": ");
14542                            pw.print(mode); pw.println();
14543                }
14544            }
14545        }
14546        if (dumpPackage == null) {
14547            pw.println("  mWakefulness="
14548                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14549            pw.println("  mSleepTokens=" + mSleepTokens);
14550            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14551                    + lockScreenShownToString());
14552            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14553            if (mRunningVoice != null) {
14554                pw.println("  mRunningVoice=" + mRunningVoice);
14555                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14556            }
14557        }
14558        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14559                || mOrigWaitForDebugger) {
14560            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14561                    || dumpPackage.equals(mOrigDebugApp)) {
14562                if (needSep) {
14563                    pw.println();
14564                    needSep = false;
14565                }
14566                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14567                        + " mDebugTransient=" + mDebugTransient
14568                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14569            }
14570        }
14571        if (mCurAppTimeTracker != null) {
14572            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14573        }
14574        if (mMemWatchProcesses.getMap().size() > 0) {
14575            pw.println("  Mem watch processes:");
14576            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14577                    = mMemWatchProcesses.getMap();
14578            for (int i=0; i<procs.size(); i++) {
14579                final String proc = procs.keyAt(i);
14580                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14581                for (int j=0; j<uids.size(); j++) {
14582                    if (needSep) {
14583                        pw.println();
14584                        needSep = false;
14585                    }
14586                    StringBuilder sb = new StringBuilder();
14587                    sb.append("    ").append(proc).append('/');
14588                    UserHandle.formatUid(sb, uids.keyAt(j));
14589                    Pair<Long, String> val = uids.valueAt(j);
14590                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14591                    if (val.second != null) {
14592                        sb.append(", report to ").append(val.second);
14593                    }
14594                    pw.println(sb.toString());
14595                }
14596            }
14597            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14598            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14599            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14600                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14601        }
14602        if (mTrackAllocationApp != null) {
14603            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14604                if (needSep) {
14605                    pw.println();
14606                    needSep = false;
14607                }
14608                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14609            }
14610        }
14611        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14612                || mProfileFd != null) {
14613            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14614                if (needSep) {
14615                    pw.println();
14616                    needSep = false;
14617                }
14618                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14619                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14620                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14621                        + mAutoStopProfiler);
14622                pw.println("  mProfileType=" + mProfileType);
14623            }
14624        }
14625        if (mNativeDebuggingApp != null) {
14626            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14627                if (needSep) {
14628                    pw.println();
14629                    needSep = false;
14630                }
14631                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14632            }
14633        }
14634        if (dumpPackage == null) {
14635            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14636                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14637                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14638            }
14639            if (mController != null) {
14640                pw.println("  mController=" + mController
14641                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14642            }
14643            if (dumpAll) {
14644                pw.println("  Total persistent processes: " + numPers);
14645                pw.println("  mProcessesReady=" + mProcessesReady
14646                        + " mSystemReady=" + mSystemReady
14647                        + " mBooted=" + mBooted
14648                        + " mFactoryTest=" + mFactoryTest);
14649                pw.println("  mBooting=" + mBooting
14650                        + " mCallFinishBooting=" + mCallFinishBooting
14651                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14652                pw.print("  mLastPowerCheckRealtime=");
14653                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14654                        pw.println("");
14655                pw.print("  mLastPowerCheckUptime=");
14656                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14657                        pw.println("");
14658                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14659                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14660                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14661                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14662                        + " (" + mLruProcesses.size() + " total)"
14663                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14664                        + " mNumServiceProcs=" + mNumServiceProcs
14665                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14666                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14667                        + " mLastMemoryLevel=" + mLastMemoryLevel
14668                        + " mLastNumProcesses=" + mLastNumProcesses);
14669                long now = SystemClock.uptimeMillis();
14670                pw.print("  mLastIdleTime=");
14671                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14672                        pw.print(" mLowRamSinceLastIdle=");
14673                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14674                        pw.println();
14675            }
14676        }
14677
14678        if (!printedAnything) {
14679            pw.println("  (nothing)");
14680        }
14681    }
14682
14683    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14684            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14685        if (mProcessesToGc.size() > 0) {
14686            boolean printed = false;
14687            long now = SystemClock.uptimeMillis();
14688            for (int i=0; i<mProcessesToGc.size(); i++) {
14689                ProcessRecord proc = mProcessesToGc.get(i);
14690                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14691                    continue;
14692                }
14693                if (!printed) {
14694                    if (needSep) pw.println();
14695                    needSep = true;
14696                    pw.println("  Processes that are waiting to GC:");
14697                    printed = true;
14698                }
14699                pw.print("    Process "); pw.println(proc);
14700                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14701                        pw.print(", last gced=");
14702                        pw.print(now-proc.lastRequestedGc);
14703                        pw.print(" ms ago, last lowMem=");
14704                        pw.print(now-proc.lastLowMemory);
14705                        pw.println(" ms ago");
14706
14707            }
14708        }
14709        return needSep;
14710    }
14711
14712    void printOomLevel(PrintWriter pw, String name, int adj) {
14713        pw.print("    ");
14714        if (adj >= 0) {
14715            pw.print(' ');
14716            if (adj < 10) pw.print(' ');
14717        } else {
14718            if (adj > -10) pw.print(' ');
14719        }
14720        pw.print(adj);
14721        pw.print(": ");
14722        pw.print(name);
14723        pw.print(" (");
14724        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14725        pw.println(")");
14726    }
14727
14728    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14729            int opti, boolean dumpAll) {
14730        boolean needSep = false;
14731
14732        if (mLruProcesses.size() > 0) {
14733            if (needSep) pw.println();
14734            needSep = true;
14735            pw.println("  OOM levels:");
14736            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14737            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14738            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14739            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14740            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14741            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14742            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14743            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14744            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14745            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14746            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14747            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14748            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14749            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14750
14751            if (needSep) pw.println();
14752            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14753                    pw.print(" total, non-act at ");
14754                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14755                    pw.print(", non-svc at ");
14756                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14757                    pw.println("):");
14758            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14759            needSep = true;
14760        }
14761
14762        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14763
14764        pw.println();
14765        pw.println("  mHomeProcess: " + mHomeProcess);
14766        pw.println("  mPreviousProcess: " + mPreviousProcess);
14767        if (mHeavyWeightProcess != null) {
14768            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14769        }
14770
14771        return true;
14772    }
14773
14774    /**
14775     * There are three ways to call this:
14776     *  - no provider specified: dump all the providers
14777     *  - a flattened component name that matched an existing provider was specified as the
14778     *    first arg: dump that one provider
14779     *  - the first arg isn't the flattened component name of an existing provider:
14780     *    dump all providers whose component contains the first arg as a substring
14781     */
14782    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14783            int opti, boolean dumpAll) {
14784        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14785    }
14786
14787    static class ItemMatcher {
14788        ArrayList<ComponentName> components;
14789        ArrayList<String> strings;
14790        ArrayList<Integer> objects;
14791        boolean all;
14792
14793        ItemMatcher() {
14794            all = true;
14795        }
14796
14797        void build(String name) {
14798            ComponentName componentName = ComponentName.unflattenFromString(name);
14799            if (componentName != null) {
14800                if (components == null) {
14801                    components = new ArrayList<ComponentName>();
14802                }
14803                components.add(componentName);
14804                all = false;
14805            } else {
14806                int objectId = 0;
14807                // Not a '/' separated full component name; maybe an object ID?
14808                try {
14809                    objectId = Integer.parseInt(name, 16);
14810                    if (objects == null) {
14811                        objects = new ArrayList<Integer>();
14812                    }
14813                    objects.add(objectId);
14814                    all = false;
14815                } catch (RuntimeException e) {
14816                    // Not an integer; just do string match.
14817                    if (strings == null) {
14818                        strings = new ArrayList<String>();
14819                    }
14820                    strings.add(name);
14821                    all = false;
14822                }
14823            }
14824        }
14825
14826        int build(String[] args, int opti) {
14827            for (; opti<args.length; opti++) {
14828                String name = args[opti];
14829                if ("--".equals(name)) {
14830                    return opti+1;
14831                }
14832                build(name);
14833            }
14834            return opti;
14835        }
14836
14837        boolean match(Object object, ComponentName comp) {
14838            if (all) {
14839                return true;
14840            }
14841            if (components != null) {
14842                for (int i=0; i<components.size(); i++) {
14843                    if (components.get(i).equals(comp)) {
14844                        return true;
14845                    }
14846                }
14847            }
14848            if (objects != null) {
14849                for (int i=0; i<objects.size(); i++) {
14850                    if (System.identityHashCode(object) == objects.get(i)) {
14851                        return true;
14852                    }
14853                }
14854            }
14855            if (strings != null) {
14856                String flat = comp.flattenToString();
14857                for (int i=0; i<strings.size(); i++) {
14858                    if (flat.contains(strings.get(i))) {
14859                        return true;
14860                    }
14861                }
14862            }
14863            return false;
14864        }
14865    }
14866
14867    /**
14868     * There are three things that cmd can be:
14869     *  - a flattened component name that matches an existing activity
14870     *  - the cmd arg isn't the flattened component name of an existing activity:
14871     *    dump all activity whose component contains the cmd as a substring
14872     *  - A hex number of the ActivityRecord object instance.
14873     */
14874    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14875            int opti, boolean dumpAll) {
14876        ArrayList<ActivityRecord> activities;
14877
14878        synchronized (this) {
14879            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14880        }
14881
14882        if (activities.size() <= 0) {
14883            return false;
14884        }
14885
14886        String[] newArgs = new String[args.length - opti];
14887        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14888
14889        TaskRecord lastTask = null;
14890        boolean needSep = false;
14891        for (int i=activities.size()-1; i>=0; i--) {
14892            ActivityRecord r = activities.get(i);
14893            if (needSep) {
14894                pw.println();
14895            }
14896            needSep = true;
14897            synchronized (this) {
14898                if (lastTask != r.task) {
14899                    lastTask = r.task;
14900                    pw.print("TASK "); pw.print(lastTask.affinity);
14901                            pw.print(" id="); pw.println(lastTask.taskId);
14902                    if (dumpAll) {
14903                        lastTask.dump(pw, "  ");
14904                    }
14905                }
14906            }
14907            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14908        }
14909        return true;
14910    }
14911
14912    /**
14913     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14914     * there is a thread associated with the activity.
14915     */
14916    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14917            final ActivityRecord r, String[] args, boolean dumpAll) {
14918        String innerPrefix = prefix + "  ";
14919        synchronized (this) {
14920            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14921                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14922                    pw.print(" pid=");
14923                    if (r.app != null) pw.println(r.app.pid);
14924                    else pw.println("(not running)");
14925            if (dumpAll) {
14926                r.dump(pw, innerPrefix);
14927            }
14928        }
14929        if (r.app != null && r.app.thread != null) {
14930            // flush anything that is already in the PrintWriter since the thread is going
14931            // to write to the file descriptor directly
14932            pw.flush();
14933            try {
14934                TransferPipe tp = new TransferPipe();
14935                try {
14936                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14937                            r.appToken, innerPrefix, args);
14938                    tp.go(fd);
14939                } finally {
14940                    tp.kill();
14941                }
14942            } catch (IOException e) {
14943                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14944            } catch (RemoteException e) {
14945                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14946            }
14947        }
14948    }
14949
14950    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14951            int opti, boolean dumpAll, String dumpPackage) {
14952        boolean needSep = false;
14953        boolean onlyHistory = false;
14954        boolean printedAnything = false;
14955
14956        if ("history".equals(dumpPackage)) {
14957            if (opti < args.length && "-s".equals(args[opti])) {
14958                dumpAll = false;
14959            }
14960            onlyHistory = true;
14961            dumpPackage = null;
14962        }
14963
14964        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14965        if (!onlyHistory && dumpAll) {
14966            if (mRegisteredReceivers.size() > 0) {
14967                boolean printed = false;
14968                Iterator it = mRegisteredReceivers.values().iterator();
14969                while (it.hasNext()) {
14970                    ReceiverList r = (ReceiverList)it.next();
14971                    if (dumpPackage != null && (r.app == null ||
14972                            !dumpPackage.equals(r.app.info.packageName))) {
14973                        continue;
14974                    }
14975                    if (!printed) {
14976                        pw.println("  Registered Receivers:");
14977                        needSep = true;
14978                        printed = true;
14979                        printedAnything = true;
14980                    }
14981                    pw.print("  * "); pw.println(r);
14982                    r.dump(pw, "    ");
14983                }
14984            }
14985
14986            if (mReceiverResolver.dump(pw, needSep ?
14987                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14988                    "    ", dumpPackage, false, false)) {
14989                needSep = true;
14990                printedAnything = true;
14991            }
14992        }
14993
14994        for (BroadcastQueue q : mBroadcastQueues) {
14995            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14996            printedAnything |= needSep;
14997        }
14998
14999        needSep = true;
15000
15001        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15002            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15003                if (needSep) {
15004                    pw.println();
15005                }
15006                needSep = true;
15007                printedAnything = true;
15008                pw.print("  Sticky broadcasts for user ");
15009                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15010                StringBuilder sb = new StringBuilder(128);
15011                for (Map.Entry<String, ArrayList<Intent>> ent
15012                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15013                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15014                    if (dumpAll) {
15015                        pw.println(":");
15016                        ArrayList<Intent> intents = ent.getValue();
15017                        final int N = intents.size();
15018                        for (int i=0; i<N; i++) {
15019                            sb.setLength(0);
15020                            sb.append("    Intent: ");
15021                            intents.get(i).toShortString(sb, false, true, false, false);
15022                            pw.println(sb.toString());
15023                            Bundle bundle = intents.get(i).getExtras();
15024                            if (bundle != null) {
15025                                pw.print("      ");
15026                                pw.println(bundle.toString());
15027                            }
15028                        }
15029                    } else {
15030                        pw.println("");
15031                    }
15032                }
15033            }
15034        }
15035
15036        if (!onlyHistory && dumpAll) {
15037            pw.println();
15038            for (BroadcastQueue queue : mBroadcastQueues) {
15039                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15040                        + queue.mBroadcastsScheduled);
15041            }
15042            pw.println("  mHandler:");
15043            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15044            needSep = true;
15045            printedAnything = true;
15046        }
15047
15048        if (!printedAnything) {
15049            pw.println("  (nothing)");
15050        }
15051    }
15052
15053    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15054            int opti, boolean dumpAll, String dumpPackage) {
15055        if (mCurBroadcastStats == null) {
15056            return;
15057        }
15058
15059        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15060        final long now = SystemClock.elapsedRealtime();
15061        if (mLastBroadcastStats != null) {
15062            pw.print("  Last stats (from ");
15063            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15064            pw.print(" to ");
15065            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15066            pw.print(", ");
15067            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15068                    - mLastBroadcastStats.mStartUptime, pw);
15069            pw.println(" uptime):");
15070            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15071                pw.println("    (nothing)");
15072            }
15073            pw.println();
15074        }
15075        pw.print("  Current stats (from ");
15076        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15077        pw.print(" to now, ");
15078        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15079                - mCurBroadcastStats.mStartUptime, pw);
15080        pw.println(" uptime):");
15081        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15082            pw.println("    (nothing)");
15083        }
15084    }
15085
15086    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15087            int opti, boolean fullCheckin, String dumpPackage) {
15088        if (mCurBroadcastStats == null) {
15089            return;
15090        }
15091
15092        if (mLastBroadcastStats != null) {
15093            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15094            if (fullCheckin) {
15095                mLastBroadcastStats = null;
15096                return;
15097            }
15098        }
15099        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15100        if (fullCheckin) {
15101            mCurBroadcastStats = null;
15102        }
15103    }
15104
15105    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15106            int opti, boolean dumpAll, String dumpPackage) {
15107        boolean needSep;
15108        boolean printedAnything = false;
15109
15110        ItemMatcher matcher = new ItemMatcher();
15111        matcher.build(args, opti);
15112
15113        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15114
15115        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15116        printedAnything |= needSep;
15117
15118        if (mLaunchingProviders.size() > 0) {
15119            boolean printed = false;
15120            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15121                ContentProviderRecord r = mLaunchingProviders.get(i);
15122                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15123                    continue;
15124                }
15125                if (!printed) {
15126                    if (needSep) pw.println();
15127                    needSep = true;
15128                    pw.println("  Launching content providers:");
15129                    printed = true;
15130                    printedAnything = true;
15131                }
15132                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15133                        pw.println(r);
15134            }
15135        }
15136
15137        if (!printedAnything) {
15138            pw.println("  (nothing)");
15139        }
15140    }
15141
15142    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15143            int opti, boolean dumpAll, String dumpPackage) {
15144        boolean needSep = false;
15145        boolean printedAnything = false;
15146
15147        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15148
15149        if (mGrantedUriPermissions.size() > 0) {
15150            boolean printed = false;
15151            int dumpUid = -2;
15152            if (dumpPackage != null) {
15153                try {
15154                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15155                            MATCH_UNINSTALLED_PACKAGES, 0);
15156                } catch (NameNotFoundException e) {
15157                    dumpUid = -1;
15158                }
15159            }
15160            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15161                int uid = mGrantedUriPermissions.keyAt(i);
15162                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15163                    continue;
15164                }
15165                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15166                if (!printed) {
15167                    if (needSep) pw.println();
15168                    needSep = true;
15169                    pw.println("  Granted Uri Permissions:");
15170                    printed = true;
15171                    printedAnything = true;
15172                }
15173                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15174                for (UriPermission perm : perms.values()) {
15175                    pw.print("    "); pw.println(perm);
15176                    if (dumpAll) {
15177                        perm.dump(pw, "      ");
15178                    }
15179                }
15180            }
15181        }
15182
15183        if (!printedAnything) {
15184            pw.println("  (nothing)");
15185        }
15186    }
15187
15188    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15189            int opti, boolean dumpAll, String dumpPackage) {
15190        boolean printed = false;
15191
15192        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15193
15194        if (mIntentSenderRecords.size() > 0) {
15195            Iterator<WeakReference<PendingIntentRecord>> it
15196                    = mIntentSenderRecords.values().iterator();
15197            while (it.hasNext()) {
15198                WeakReference<PendingIntentRecord> ref = it.next();
15199                PendingIntentRecord rec = ref != null ? ref.get(): null;
15200                if (dumpPackage != null && (rec == null
15201                        || !dumpPackage.equals(rec.key.packageName))) {
15202                    continue;
15203                }
15204                printed = true;
15205                if (rec != null) {
15206                    pw.print("  * "); pw.println(rec);
15207                    if (dumpAll) {
15208                        rec.dump(pw, "    ");
15209                    }
15210                } else {
15211                    pw.print("  * "); pw.println(ref);
15212                }
15213            }
15214        }
15215
15216        if (!printed) {
15217            pw.println("  (nothing)");
15218        }
15219    }
15220
15221    private static final int dumpProcessList(PrintWriter pw,
15222            ActivityManagerService service, List list,
15223            String prefix, String normalLabel, String persistentLabel,
15224            String dumpPackage) {
15225        int numPers = 0;
15226        final int N = list.size()-1;
15227        for (int i=N; i>=0; i--) {
15228            ProcessRecord r = (ProcessRecord)list.get(i);
15229            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15230                continue;
15231            }
15232            pw.println(String.format("%s%s #%2d: %s",
15233                    prefix, (r.persistent ? persistentLabel : normalLabel),
15234                    i, r.toString()));
15235            if (r.persistent) {
15236                numPers++;
15237            }
15238        }
15239        return numPers;
15240    }
15241
15242    private static final boolean dumpProcessOomList(PrintWriter pw,
15243            ActivityManagerService service, List<ProcessRecord> origList,
15244            String prefix, String normalLabel, String persistentLabel,
15245            boolean inclDetails, String dumpPackage) {
15246
15247        ArrayList<Pair<ProcessRecord, Integer>> list
15248                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15249        for (int i=0; i<origList.size(); i++) {
15250            ProcessRecord r = origList.get(i);
15251            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15252                continue;
15253            }
15254            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15255        }
15256
15257        if (list.size() <= 0) {
15258            return false;
15259        }
15260
15261        Comparator<Pair<ProcessRecord, Integer>> comparator
15262                = new Comparator<Pair<ProcessRecord, Integer>>() {
15263            @Override
15264            public int compare(Pair<ProcessRecord, Integer> object1,
15265                    Pair<ProcessRecord, Integer> object2) {
15266                if (object1.first.setAdj != object2.first.setAdj) {
15267                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15268                }
15269                if (object1.first.setProcState != object2.first.setProcState) {
15270                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15271                }
15272                if (object1.second.intValue() != object2.second.intValue()) {
15273                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15274                }
15275                return 0;
15276            }
15277        };
15278
15279        Collections.sort(list, comparator);
15280
15281        final long curRealtime = SystemClock.elapsedRealtime();
15282        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15283        final long curUptime = SystemClock.uptimeMillis();
15284        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15285
15286        for (int i=list.size()-1; i>=0; i--) {
15287            ProcessRecord r = list.get(i).first;
15288            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15289            char schedGroup;
15290            switch (r.setSchedGroup) {
15291                case ProcessList.SCHED_GROUP_BACKGROUND:
15292                    schedGroup = 'B';
15293                    break;
15294                case ProcessList.SCHED_GROUP_DEFAULT:
15295                    schedGroup = 'F';
15296                    break;
15297                case ProcessList.SCHED_GROUP_TOP_APP:
15298                    schedGroup = 'T';
15299                    break;
15300                default:
15301                    schedGroup = '?';
15302                    break;
15303            }
15304            char foreground;
15305            if (r.foregroundActivities) {
15306                foreground = 'A';
15307            } else if (r.foregroundServices) {
15308                foreground = 'S';
15309            } else {
15310                foreground = ' ';
15311            }
15312            String procState = ProcessList.makeProcStateString(r.curProcState);
15313            pw.print(prefix);
15314            pw.print(r.persistent ? persistentLabel : normalLabel);
15315            pw.print(" #");
15316            int num = (origList.size()-1)-list.get(i).second;
15317            if (num < 10) pw.print(' ');
15318            pw.print(num);
15319            pw.print(": ");
15320            pw.print(oomAdj);
15321            pw.print(' ');
15322            pw.print(schedGroup);
15323            pw.print('/');
15324            pw.print(foreground);
15325            pw.print('/');
15326            pw.print(procState);
15327            pw.print(" trm:");
15328            if (r.trimMemoryLevel < 10) pw.print(' ');
15329            pw.print(r.trimMemoryLevel);
15330            pw.print(' ');
15331            pw.print(r.toShortString());
15332            pw.print(" (");
15333            pw.print(r.adjType);
15334            pw.println(')');
15335            if (r.adjSource != null || r.adjTarget != null) {
15336                pw.print(prefix);
15337                pw.print("    ");
15338                if (r.adjTarget instanceof ComponentName) {
15339                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15340                } else if (r.adjTarget != null) {
15341                    pw.print(r.adjTarget.toString());
15342                } else {
15343                    pw.print("{null}");
15344                }
15345                pw.print("<=");
15346                if (r.adjSource instanceof ProcessRecord) {
15347                    pw.print("Proc{");
15348                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15349                    pw.println("}");
15350                } else if (r.adjSource != null) {
15351                    pw.println(r.adjSource.toString());
15352                } else {
15353                    pw.println("{null}");
15354                }
15355            }
15356            if (inclDetails) {
15357                pw.print(prefix);
15358                pw.print("    ");
15359                pw.print("oom: max="); pw.print(r.maxAdj);
15360                pw.print(" curRaw="); pw.print(r.curRawAdj);
15361                pw.print(" setRaw="); pw.print(r.setRawAdj);
15362                pw.print(" cur="); pw.print(r.curAdj);
15363                pw.print(" set="); pw.println(r.setAdj);
15364                pw.print(prefix);
15365                pw.print("    ");
15366                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15367                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15368                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15369                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15370                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15371                pw.println();
15372                pw.print(prefix);
15373                pw.print("    ");
15374                pw.print("cached="); pw.print(r.cached);
15375                pw.print(" empty="); pw.print(r.empty);
15376                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15377
15378                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15379                    if (r.lastWakeTime != 0) {
15380                        long wtime;
15381                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15382                        synchronized (stats) {
15383                            wtime = stats.getProcessWakeTime(r.info.uid,
15384                                    r.pid, curRealtime);
15385                        }
15386                        long timeUsed = wtime - r.lastWakeTime;
15387                        pw.print(prefix);
15388                        pw.print("    ");
15389                        pw.print("keep awake over ");
15390                        TimeUtils.formatDuration(realtimeSince, pw);
15391                        pw.print(" used ");
15392                        TimeUtils.formatDuration(timeUsed, pw);
15393                        pw.print(" (");
15394                        pw.print((timeUsed*100)/realtimeSince);
15395                        pw.println("%)");
15396                    }
15397                    if (r.lastCpuTime != 0) {
15398                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15399                        pw.print(prefix);
15400                        pw.print("    ");
15401                        pw.print("run cpu over ");
15402                        TimeUtils.formatDuration(uptimeSince, pw);
15403                        pw.print(" used ");
15404                        TimeUtils.formatDuration(timeUsed, pw);
15405                        pw.print(" (");
15406                        pw.print((timeUsed*100)/uptimeSince);
15407                        pw.println("%)");
15408                    }
15409                }
15410            }
15411        }
15412        return true;
15413    }
15414
15415    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15416            String[] args) {
15417        ArrayList<ProcessRecord> procs;
15418        synchronized (this) {
15419            if (args != null && args.length > start
15420                    && args[start].charAt(0) != '-') {
15421                procs = new ArrayList<ProcessRecord>();
15422                int pid = -1;
15423                try {
15424                    pid = Integer.parseInt(args[start]);
15425                } catch (NumberFormatException e) {
15426                }
15427                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15428                    ProcessRecord proc = mLruProcesses.get(i);
15429                    if (proc.pid == pid) {
15430                        procs.add(proc);
15431                    } else if (allPkgs && proc.pkgList != null
15432                            && proc.pkgList.containsKey(args[start])) {
15433                        procs.add(proc);
15434                    } else if (proc.processName.equals(args[start])) {
15435                        procs.add(proc);
15436                    }
15437                }
15438                if (procs.size() <= 0) {
15439                    return null;
15440                }
15441            } else {
15442                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15443            }
15444        }
15445        return procs;
15446    }
15447
15448    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15449            PrintWriter pw, String[] args) {
15450        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15451        if (procs == null) {
15452            pw.println("No process found for: " + args[0]);
15453            return;
15454        }
15455
15456        long uptime = SystemClock.uptimeMillis();
15457        long realtime = SystemClock.elapsedRealtime();
15458        pw.println("Applications Graphics Acceleration Info:");
15459        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15460
15461        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15462            ProcessRecord r = procs.get(i);
15463            if (r.thread != null) {
15464                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15465                pw.flush();
15466                try {
15467                    TransferPipe tp = new TransferPipe();
15468                    try {
15469                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15470                        tp.go(fd);
15471                    } finally {
15472                        tp.kill();
15473                    }
15474                } catch (IOException e) {
15475                    pw.println("Failure while dumping the app: " + r);
15476                    pw.flush();
15477                } catch (RemoteException e) {
15478                    pw.println("Got a RemoteException while dumping the app " + r);
15479                    pw.flush();
15480                }
15481            }
15482        }
15483    }
15484
15485    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15486        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15487        if (procs == null) {
15488            pw.println("No process found for: " + args[0]);
15489            return;
15490        }
15491
15492        pw.println("Applications Database Info:");
15493
15494        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15495            ProcessRecord r = procs.get(i);
15496            if (r.thread != null) {
15497                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15498                pw.flush();
15499                try {
15500                    TransferPipe tp = new TransferPipe();
15501                    try {
15502                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15503                        tp.go(fd);
15504                    } finally {
15505                        tp.kill();
15506                    }
15507                } catch (IOException e) {
15508                    pw.println("Failure while dumping the app: " + r);
15509                    pw.flush();
15510                } catch (RemoteException e) {
15511                    pw.println("Got a RemoteException while dumping the app " + r);
15512                    pw.flush();
15513                }
15514            }
15515        }
15516    }
15517
15518    final static class MemItem {
15519        final boolean isProc;
15520        final String label;
15521        final String shortLabel;
15522        final long pss;
15523        final long swapPss;
15524        final int id;
15525        final boolean hasActivities;
15526        ArrayList<MemItem> subitems;
15527
15528        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15529                boolean _hasActivities) {
15530            isProc = true;
15531            label = _label;
15532            shortLabel = _shortLabel;
15533            pss = _pss;
15534            swapPss = _swapPss;
15535            id = _id;
15536            hasActivities = _hasActivities;
15537        }
15538
15539        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15540            isProc = false;
15541            label = _label;
15542            shortLabel = _shortLabel;
15543            pss = _pss;
15544            swapPss = _swapPss;
15545            id = _id;
15546            hasActivities = false;
15547        }
15548    }
15549
15550    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15551            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15552        if (sort && !isCompact) {
15553            Collections.sort(items, new Comparator<MemItem>() {
15554                @Override
15555                public int compare(MemItem lhs, MemItem rhs) {
15556                    if (lhs.pss < rhs.pss) {
15557                        return 1;
15558                    } else if (lhs.pss > rhs.pss) {
15559                        return -1;
15560                    }
15561                    return 0;
15562                }
15563            });
15564        }
15565
15566        for (int i=0; i<items.size(); i++) {
15567            MemItem mi = items.get(i);
15568            if (!isCompact) {
15569                if (dumpSwapPss) {
15570                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15571                            mi.label, stringifyKBSize(mi.swapPss));
15572                } else {
15573                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15574                }
15575            } else if (mi.isProc) {
15576                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15577                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15578                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15579                pw.println(mi.hasActivities ? ",a" : ",e");
15580            } else {
15581                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15582                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15583            }
15584            if (mi.subitems != null) {
15585                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15586                        true, isCompact, dumpSwapPss);
15587            }
15588        }
15589    }
15590
15591    // These are in KB.
15592    static final long[] DUMP_MEM_BUCKETS = new long[] {
15593        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15594        120*1024, 160*1024, 200*1024,
15595        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15596        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15597    };
15598
15599    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15600            boolean stackLike) {
15601        int start = label.lastIndexOf('.');
15602        if (start >= 0) start++;
15603        else start = 0;
15604        int end = label.length();
15605        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15606            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15607                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15608                out.append(bucket);
15609                out.append(stackLike ? "MB." : "MB ");
15610                out.append(label, start, end);
15611                return;
15612            }
15613        }
15614        out.append(memKB/1024);
15615        out.append(stackLike ? "MB." : "MB ");
15616        out.append(label, start, end);
15617    }
15618
15619    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15620            ProcessList.NATIVE_ADJ,
15621            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15622            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15623            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15624            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15625            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15626            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15627    };
15628    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15629            "Native",
15630            "System", "Persistent", "Persistent Service", "Foreground",
15631            "Visible", "Perceptible",
15632            "Heavy Weight", "Backup",
15633            "A Services", "Home",
15634            "Previous", "B Services", "Cached"
15635    };
15636    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15637            "native",
15638            "sys", "pers", "persvc", "fore",
15639            "vis", "percept",
15640            "heavy", "backup",
15641            "servicea", "home",
15642            "prev", "serviceb", "cached"
15643    };
15644
15645    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15646            long realtime, boolean isCheckinRequest, boolean isCompact) {
15647        if (isCompact) {
15648            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15649        }
15650        if (isCheckinRequest || isCompact) {
15651            // short checkin version
15652            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15653        } else {
15654            pw.println("Applications Memory Usage (in Kilobytes):");
15655            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15656        }
15657    }
15658
15659    private static final int KSM_SHARED = 0;
15660    private static final int KSM_SHARING = 1;
15661    private static final int KSM_UNSHARED = 2;
15662    private static final int KSM_VOLATILE = 3;
15663
15664    private final long[] getKsmInfo() {
15665        long[] longOut = new long[4];
15666        final int[] SINGLE_LONG_FORMAT = new int[] {
15667            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15668        };
15669        long[] longTmp = new long[1];
15670        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15671                SINGLE_LONG_FORMAT, null, longTmp, null);
15672        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15673        longTmp[0] = 0;
15674        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15675                SINGLE_LONG_FORMAT, null, longTmp, null);
15676        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15677        longTmp[0] = 0;
15678        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15679                SINGLE_LONG_FORMAT, null, longTmp, null);
15680        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15681        longTmp[0] = 0;
15682        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15683                SINGLE_LONG_FORMAT, null, longTmp, null);
15684        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15685        return longOut;
15686    }
15687
15688    private static String stringifySize(long size, int order) {
15689        Locale locale = Locale.US;
15690        switch (order) {
15691            case 1:
15692                return String.format(locale, "%,13d", size);
15693            case 1024:
15694                return String.format(locale, "%,9dK", size / 1024);
15695            case 1024 * 1024:
15696                return String.format(locale, "%,5dM", size / 1024 / 1024);
15697            case 1024 * 1024 * 1024:
15698                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15699            default:
15700                throw new IllegalArgumentException("Invalid size order");
15701        }
15702    }
15703
15704    private static String stringifyKBSize(long size) {
15705        return stringifySize(size * 1024, 1024);
15706    }
15707
15708    // Update this version number in case you change the 'compact' format
15709    private static final int MEMINFO_COMPACT_VERSION = 1;
15710
15711    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15712            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15713        boolean dumpDetails = false;
15714        boolean dumpFullDetails = false;
15715        boolean dumpDalvik = false;
15716        boolean dumpSummaryOnly = false;
15717        boolean dumpUnreachable = false;
15718        boolean oomOnly = false;
15719        boolean isCompact = false;
15720        boolean localOnly = false;
15721        boolean packages = false;
15722        boolean isCheckinRequest = false;
15723        boolean dumpSwapPss = false;
15724
15725        int opti = 0;
15726        while (opti < args.length) {
15727            String opt = args[opti];
15728            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15729                break;
15730            }
15731            opti++;
15732            if ("-a".equals(opt)) {
15733                dumpDetails = true;
15734                dumpFullDetails = true;
15735                dumpDalvik = true;
15736                dumpSwapPss = true;
15737            } else if ("-d".equals(opt)) {
15738                dumpDalvik = true;
15739            } else if ("-c".equals(opt)) {
15740                isCompact = true;
15741            } else if ("-s".equals(opt)) {
15742                dumpDetails = true;
15743                dumpSummaryOnly = true;
15744            } else if ("-S".equals(opt)) {
15745                dumpSwapPss = true;
15746            } else if ("--unreachable".equals(opt)) {
15747                dumpUnreachable = true;
15748            } else if ("--oom".equals(opt)) {
15749                oomOnly = true;
15750            } else if ("--local".equals(opt)) {
15751                localOnly = true;
15752            } else if ("--package".equals(opt)) {
15753                packages = true;
15754            } else if ("--checkin".equals(opt)) {
15755                isCheckinRequest = true;
15756
15757            } else if ("-h".equals(opt)) {
15758                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15759                pw.println("  -a: include all available information for each process.");
15760                pw.println("  -d: include dalvik details.");
15761                pw.println("  -c: dump in a compact machine-parseable representation.");
15762                pw.println("  -s: dump only summary of application memory usage.");
15763                pw.println("  -S: dump also SwapPss.");
15764                pw.println("  --oom: only show processes organized by oom adj.");
15765                pw.println("  --local: only collect details locally, don't call process.");
15766                pw.println("  --package: interpret process arg as package, dumping all");
15767                pw.println("             processes that have loaded that package.");
15768                pw.println("  --checkin: dump data for a checkin");
15769                pw.println("If [process] is specified it can be the name or ");
15770                pw.println("pid of a specific process to dump.");
15771                return;
15772            } else {
15773                pw.println("Unknown argument: " + opt + "; use -h for help");
15774            }
15775        }
15776
15777        long uptime = SystemClock.uptimeMillis();
15778        long realtime = SystemClock.elapsedRealtime();
15779        final long[] tmpLong = new long[1];
15780
15781        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15782        if (procs == null) {
15783            // No Java processes.  Maybe they want to print a native process.
15784            if (args != null && args.length > opti
15785                    && args[opti].charAt(0) != '-') {
15786                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15787                        = new ArrayList<ProcessCpuTracker.Stats>();
15788                updateCpuStatsNow();
15789                int findPid = -1;
15790                try {
15791                    findPid = Integer.parseInt(args[opti]);
15792                } catch (NumberFormatException e) {
15793                }
15794                synchronized (mProcessCpuTracker) {
15795                    final int N = mProcessCpuTracker.countStats();
15796                    for (int i=0; i<N; i++) {
15797                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15798                        if (st.pid == findPid || (st.baseName != null
15799                                && st.baseName.equals(args[opti]))) {
15800                            nativeProcs.add(st);
15801                        }
15802                    }
15803                }
15804                if (nativeProcs.size() > 0) {
15805                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15806                            isCompact);
15807                    Debug.MemoryInfo mi = null;
15808                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15809                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15810                        final int pid = r.pid;
15811                        if (!isCheckinRequest && dumpDetails) {
15812                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15813                        }
15814                        if (mi == null) {
15815                            mi = new Debug.MemoryInfo();
15816                        }
15817                        if (dumpDetails || (!brief && !oomOnly)) {
15818                            Debug.getMemoryInfo(pid, mi);
15819                        } else {
15820                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15821                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15822                        }
15823                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15824                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15825                        if (isCheckinRequest) {
15826                            pw.println();
15827                        }
15828                    }
15829                    return;
15830                }
15831            }
15832            pw.println("No process found for: " + args[opti]);
15833            return;
15834        }
15835
15836        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15837            dumpDetails = true;
15838        }
15839
15840        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15841
15842        String[] innerArgs = new String[args.length-opti];
15843        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15844
15845        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15846        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15847        long nativePss = 0;
15848        long nativeSwapPss = 0;
15849        long dalvikPss = 0;
15850        long dalvikSwapPss = 0;
15851        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15852                EmptyArray.LONG;
15853        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15854                EmptyArray.LONG;
15855        long otherPss = 0;
15856        long otherSwapPss = 0;
15857        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15858        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15859
15860        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15861        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15862        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15863                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15864
15865        long totalPss = 0;
15866        long totalSwapPss = 0;
15867        long cachedPss = 0;
15868        long cachedSwapPss = 0;
15869        boolean hasSwapPss = false;
15870
15871        Debug.MemoryInfo mi = null;
15872        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15873            final ProcessRecord r = procs.get(i);
15874            final IApplicationThread thread;
15875            final int pid;
15876            final int oomAdj;
15877            final boolean hasActivities;
15878            synchronized (this) {
15879                thread = r.thread;
15880                pid = r.pid;
15881                oomAdj = r.getSetAdjWithServices();
15882                hasActivities = r.activities.size() > 0;
15883            }
15884            if (thread != null) {
15885                if (!isCheckinRequest && dumpDetails) {
15886                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15887                }
15888                if (mi == null) {
15889                    mi = new Debug.MemoryInfo();
15890                }
15891                if (dumpDetails || (!brief && !oomOnly)) {
15892                    Debug.getMemoryInfo(pid, mi);
15893                    hasSwapPss = mi.hasSwappedOutPss;
15894                } else {
15895                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15896                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15897                }
15898                if (dumpDetails) {
15899                    if (localOnly) {
15900                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15901                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15902                        if (isCheckinRequest) {
15903                            pw.println();
15904                        }
15905                    } else {
15906                        try {
15907                            pw.flush();
15908                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15909                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15910                        } catch (RemoteException e) {
15911                            if (!isCheckinRequest) {
15912                                pw.println("Got RemoteException!");
15913                                pw.flush();
15914                            }
15915                        }
15916                    }
15917                }
15918
15919                final long myTotalPss = mi.getTotalPss();
15920                final long myTotalUss = mi.getTotalUss();
15921                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15922
15923                synchronized (this) {
15924                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15925                        // Record this for posterity if the process has been stable.
15926                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15927                    }
15928                }
15929
15930                if (!isCheckinRequest && mi != null) {
15931                    totalPss += myTotalPss;
15932                    totalSwapPss += myTotalSwapPss;
15933                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15934                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15935                            myTotalSwapPss, pid, hasActivities);
15936                    procMems.add(pssItem);
15937                    procMemsMap.put(pid, pssItem);
15938
15939                    nativePss += mi.nativePss;
15940                    nativeSwapPss += mi.nativeSwappedOutPss;
15941                    dalvikPss += mi.dalvikPss;
15942                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15943                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15944                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15945                        dalvikSubitemSwapPss[j] +=
15946                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15947                    }
15948                    otherPss += mi.otherPss;
15949                    otherSwapPss += mi.otherSwappedOutPss;
15950                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15951                        long mem = mi.getOtherPss(j);
15952                        miscPss[j] += mem;
15953                        otherPss -= mem;
15954                        mem = mi.getOtherSwappedOutPss(j);
15955                        miscSwapPss[j] += mem;
15956                        otherSwapPss -= mem;
15957                    }
15958
15959                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15960                        cachedPss += myTotalPss;
15961                        cachedSwapPss += myTotalSwapPss;
15962                    }
15963
15964                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15965                        if (oomIndex == (oomPss.length - 1)
15966                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15967                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15968                            oomPss[oomIndex] += myTotalPss;
15969                            oomSwapPss[oomIndex] += myTotalSwapPss;
15970                            if (oomProcs[oomIndex] == null) {
15971                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15972                            }
15973                            oomProcs[oomIndex].add(pssItem);
15974                            break;
15975                        }
15976                    }
15977                }
15978            }
15979        }
15980
15981        long nativeProcTotalPss = 0;
15982
15983        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15984            // If we are showing aggregations, also look for native processes to
15985            // include so that our aggregations are more accurate.
15986            updateCpuStatsNow();
15987            mi = null;
15988            synchronized (mProcessCpuTracker) {
15989                final int N = mProcessCpuTracker.countStats();
15990                for (int i=0; i<N; i++) {
15991                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15992                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15993                        if (mi == null) {
15994                            mi = new Debug.MemoryInfo();
15995                        }
15996                        if (!brief && !oomOnly) {
15997                            Debug.getMemoryInfo(st.pid, mi);
15998                        } else {
15999                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16000                            mi.nativePrivateDirty = (int)tmpLong[0];
16001                        }
16002
16003                        final long myTotalPss = mi.getTotalPss();
16004                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16005                        totalPss += myTotalPss;
16006                        nativeProcTotalPss += myTotalPss;
16007
16008                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16009                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16010                        procMems.add(pssItem);
16011
16012                        nativePss += mi.nativePss;
16013                        nativeSwapPss += mi.nativeSwappedOutPss;
16014                        dalvikPss += mi.dalvikPss;
16015                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16016                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16017                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16018                            dalvikSubitemSwapPss[j] +=
16019                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16020                        }
16021                        otherPss += mi.otherPss;
16022                        otherSwapPss += mi.otherSwappedOutPss;
16023                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16024                            long mem = mi.getOtherPss(j);
16025                            miscPss[j] += mem;
16026                            otherPss -= mem;
16027                            mem = mi.getOtherSwappedOutPss(j);
16028                            miscSwapPss[j] += mem;
16029                            otherSwapPss -= mem;
16030                        }
16031                        oomPss[0] += myTotalPss;
16032                        oomSwapPss[0] += myTotalSwapPss;
16033                        if (oomProcs[0] == null) {
16034                            oomProcs[0] = new ArrayList<MemItem>();
16035                        }
16036                        oomProcs[0].add(pssItem);
16037                    }
16038                }
16039            }
16040
16041            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16042
16043            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16044            final MemItem dalvikItem =
16045                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16046            if (dalvikSubitemPss.length > 0) {
16047                dalvikItem.subitems = new ArrayList<MemItem>();
16048                for (int j=0; j<dalvikSubitemPss.length; j++) {
16049                    final String name = Debug.MemoryInfo.getOtherLabel(
16050                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16051                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16052                                    dalvikSubitemSwapPss[j], j));
16053                }
16054            }
16055            catMems.add(dalvikItem);
16056            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16057            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16058                String label = Debug.MemoryInfo.getOtherLabel(j);
16059                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16060            }
16061
16062            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16063            for (int j=0; j<oomPss.length; j++) {
16064                if (oomPss[j] != 0) {
16065                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16066                            : DUMP_MEM_OOM_LABEL[j];
16067                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16068                            DUMP_MEM_OOM_ADJ[j]);
16069                    item.subitems = oomProcs[j];
16070                    oomMems.add(item);
16071                }
16072            }
16073
16074            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16075            if (!brief && !oomOnly && !isCompact) {
16076                pw.println();
16077                pw.println("Total PSS by process:");
16078                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16079                pw.println();
16080            }
16081            if (!isCompact) {
16082                pw.println("Total PSS by OOM adjustment:");
16083            }
16084            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16085            if (!brief && !oomOnly) {
16086                PrintWriter out = categoryPw != null ? categoryPw : pw;
16087                if (!isCompact) {
16088                    out.println();
16089                    out.println("Total PSS by category:");
16090                }
16091                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16092            }
16093            if (!isCompact) {
16094                pw.println();
16095            }
16096            MemInfoReader memInfo = new MemInfoReader();
16097            memInfo.readMemInfo();
16098            if (nativeProcTotalPss > 0) {
16099                synchronized (this) {
16100                    final long cachedKb = memInfo.getCachedSizeKb();
16101                    final long freeKb = memInfo.getFreeSizeKb();
16102                    final long zramKb = memInfo.getZramTotalSizeKb();
16103                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16104                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16105                            kernelKb*1024, nativeProcTotalPss*1024);
16106                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16107                            nativeProcTotalPss);
16108                }
16109            }
16110            if (!brief) {
16111                if (!isCompact) {
16112                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16113                    pw.print(" (status ");
16114                    switch (mLastMemoryLevel) {
16115                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16116                            pw.println("normal)");
16117                            break;
16118                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16119                            pw.println("moderate)");
16120                            break;
16121                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16122                            pw.println("low)");
16123                            break;
16124                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16125                            pw.println("critical)");
16126                            break;
16127                        default:
16128                            pw.print(mLastMemoryLevel);
16129                            pw.println(")");
16130                            break;
16131                    }
16132                    pw.print(" Free RAM: ");
16133                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16134                            + memInfo.getFreeSizeKb()));
16135                    pw.print(" (");
16136                    pw.print(stringifyKBSize(cachedPss));
16137                    pw.print(" cached pss + ");
16138                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16139                    pw.print(" cached kernel + ");
16140                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16141                    pw.println(" free)");
16142                } else {
16143                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16144                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16145                            + memInfo.getFreeSizeKb()); pw.print(",");
16146                    pw.println(totalPss - cachedPss);
16147                }
16148            }
16149            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16150                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16151                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16152            if (!isCompact) {
16153                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16154                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16155                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16156                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16157                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16158            } else {
16159                pw.print("lostram,"); pw.println(lostRAM);
16160            }
16161            if (!brief) {
16162                if (memInfo.getZramTotalSizeKb() != 0) {
16163                    if (!isCompact) {
16164                        pw.print("     ZRAM: ");
16165                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16166                                pw.print(" physical used for ");
16167                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16168                                        - memInfo.getSwapFreeSizeKb()));
16169                                pw.print(" in swap (");
16170                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16171                                pw.println(" total swap)");
16172                    } else {
16173                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16174                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16175                                pw.println(memInfo.getSwapFreeSizeKb());
16176                    }
16177                }
16178                final long[] ksm = getKsmInfo();
16179                if (!isCompact) {
16180                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16181                            || ksm[KSM_VOLATILE] != 0) {
16182                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16183                                pw.print(" saved from shared ");
16184                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16185                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16186                                pw.print(" unshared; ");
16187                                pw.print(stringifyKBSize(
16188                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16189                    }
16190                    pw.print("   Tuning: ");
16191                    pw.print(ActivityManager.staticGetMemoryClass());
16192                    pw.print(" (large ");
16193                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16194                    pw.print("), oom ");
16195                    pw.print(stringifySize(
16196                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16197                    pw.print(", restore limit ");
16198                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16199                    if (ActivityManager.isLowRamDeviceStatic()) {
16200                        pw.print(" (low-ram)");
16201                    }
16202                    if (ActivityManager.isHighEndGfx()) {
16203                        pw.print(" (high-end-gfx)");
16204                    }
16205                    pw.println();
16206                } else {
16207                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16208                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16209                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16210                    pw.print("tuning,");
16211                    pw.print(ActivityManager.staticGetMemoryClass());
16212                    pw.print(',');
16213                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16214                    pw.print(',');
16215                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16216                    if (ActivityManager.isLowRamDeviceStatic()) {
16217                        pw.print(",low-ram");
16218                    }
16219                    if (ActivityManager.isHighEndGfx()) {
16220                        pw.print(",high-end-gfx");
16221                    }
16222                    pw.println();
16223                }
16224            }
16225        }
16226    }
16227
16228    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16229            long memtrack, String name) {
16230        sb.append("  ");
16231        sb.append(ProcessList.makeOomAdjString(oomAdj));
16232        sb.append(' ');
16233        sb.append(ProcessList.makeProcStateString(procState));
16234        sb.append(' ');
16235        ProcessList.appendRamKb(sb, pss);
16236        sb.append(": ");
16237        sb.append(name);
16238        if (memtrack > 0) {
16239            sb.append(" (");
16240            sb.append(stringifyKBSize(memtrack));
16241            sb.append(" memtrack)");
16242        }
16243    }
16244
16245    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16246        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16247        sb.append(" (pid ");
16248        sb.append(mi.pid);
16249        sb.append(") ");
16250        sb.append(mi.adjType);
16251        sb.append('\n');
16252        if (mi.adjReason != null) {
16253            sb.append("                      ");
16254            sb.append(mi.adjReason);
16255            sb.append('\n');
16256        }
16257    }
16258
16259    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16260        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16261        for (int i=0, N=memInfos.size(); i<N; i++) {
16262            ProcessMemInfo mi = memInfos.get(i);
16263            infoMap.put(mi.pid, mi);
16264        }
16265        updateCpuStatsNow();
16266        long[] memtrackTmp = new long[1];
16267        synchronized (mProcessCpuTracker) {
16268            final int N = mProcessCpuTracker.countStats();
16269            for (int i=0; i<N; i++) {
16270                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16271                if (st.vsize > 0) {
16272                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16273                    if (pss > 0) {
16274                        if (infoMap.indexOfKey(st.pid) < 0) {
16275                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16276                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16277                            mi.pss = pss;
16278                            mi.memtrack = memtrackTmp[0];
16279                            memInfos.add(mi);
16280                        }
16281                    }
16282                }
16283            }
16284        }
16285
16286        long totalPss = 0;
16287        long totalMemtrack = 0;
16288        for (int i=0, N=memInfos.size(); i<N; i++) {
16289            ProcessMemInfo mi = memInfos.get(i);
16290            if (mi.pss == 0) {
16291                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16292                mi.memtrack = memtrackTmp[0];
16293            }
16294            totalPss += mi.pss;
16295            totalMemtrack += mi.memtrack;
16296        }
16297        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16298            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16299                if (lhs.oomAdj != rhs.oomAdj) {
16300                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16301                }
16302                if (lhs.pss != rhs.pss) {
16303                    return lhs.pss < rhs.pss ? 1 : -1;
16304                }
16305                return 0;
16306            }
16307        });
16308
16309        StringBuilder tag = new StringBuilder(128);
16310        StringBuilder stack = new StringBuilder(128);
16311        tag.append("Low on memory -- ");
16312        appendMemBucket(tag, totalPss, "total", false);
16313        appendMemBucket(stack, totalPss, "total", true);
16314
16315        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16316        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16317        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16318
16319        boolean firstLine = true;
16320        int lastOomAdj = Integer.MIN_VALUE;
16321        long extraNativeRam = 0;
16322        long extraNativeMemtrack = 0;
16323        long cachedPss = 0;
16324        for (int i=0, N=memInfos.size(); i<N; i++) {
16325            ProcessMemInfo mi = memInfos.get(i);
16326
16327            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16328                cachedPss += mi.pss;
16329            }
16330
16331            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16332                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16333                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16334                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16335                if (lastOomAdj != mi.oomAdj) {
16336                    lastOomAdj = mi.oomAdj;
16337                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16338                        tag.append(" / ");
16339                    }
16340                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16341                        if (firstLine) {
16342                            stack.append(":");
16343                            firstLine = false;
16344                        }
16345                        stack.append("\n\t at ");
16346                    } else {
16347                        stack.append("$");
16348                    }
16349                } else {
16350                    tag.append(" ");
16351                    stack.append("$");
16352                }
16353                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16354                    appendMemBucket(tag, mi.pss, mi.name, false);
16355                }
16356                appendMemBucket(stack, mi.pss, mi.name, true);
16357                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16358                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16359                    stack.append("(");
16360                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16361                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16362                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16363                            stack.append(":");
16364                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16365                        }
16366                    }
16367                    stack.append(")");
16368                }
16369            }
16370
16371            appendMemInfo(fullNativeBuilder, mi);
16372            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16373                // The short form only has native processes that are >= 512K.
16374                if (mi.pss >= 512) {
16375                    appendMemInfo(shortNativeBuilder, mi);
16376                } else {
16377                    extraNativeRam += mi.pss;
16378                    extraNativeMemtrack += mi.memtrack;
16379                }
16380            } else {
16381                // Short form has all other details, but if we have collected RAM
16382                // from smaller native processes let's dump a summary of that.
16383                if (extraNativeRam > 0) {
16384                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16385                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16386                    shortNativeBuilder.append('\n');
16387                    extraNativeRam = 0;
16388                }
16389                appendMemInfo(fullJavaBuilder, mi);
16390            }
16391        }
16392
16393        fullJavaBuilder.append("           ");
16394        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16395        fullJavaBuilder.append(": TOTAL");
16396        if (totalMemtrack > 0) {
16397            fullJavaBuilder.append(" (");
16398            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16399            fullJavaBuilder.append(" memtrack)");
16400        } else {
16401        }
16402        fullJavaBuilder.append("\n");
16403
16404        MemInfoReader memInfo = new MemInfoReader();
16405        memInfo.readMemInfo();
16406        final long[] infos = memInfo.getRawInfo();
16407
16408        StringBuilder memInfoBuilder = new StringBuilder(1024);
16409        Debug.getMemInfo(infos);
16410        memInfoBuilder.append("  MemInfo: ");
16411        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16412        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16413        memInfoBuilder.append(stringifyKBSize(
16414                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16415        memInfoBuilder.append(stringifyKBSize(
16416                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16417        memInfoBuilder.append(stringifyKBSize(
16418                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16419        memInfoBuilder.append("           ");
16420        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16421        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16422        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16423        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16424        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16425            memInfoBuilder.append("  ZRAM: ");
16426            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16427            memInfoBuilder.append(" RAM, ");
16428            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16429            memInfoBuilder.append(" swap total, ");
16430            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16431            memInfoBuilder.append(" swap free\n");
16432        }
16433        final long[] ksm = getKsmInfo();
16434        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16435                || ksm[KSM_VOLATILE] != 0) {
16436            memInfoBuilder.append("  KSM: ");
16437            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16438            memInfoBuilder.append(" saved from shared ");
16439            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16440            memInfoBuilder.append("\n       ");
16441            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16442            memInfoBuilder.append(" unshared; ");
16443            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16444            memInfoBuilder.append(" volatile\n");
16445        }
16446        memInfoBuilder.append("  Free RAM: ");
16447        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16448                + memInfo.getFreeSizeKb()));
16449        memInfoBuilder.append("\n");
16450        memInfoBuilder.append("  Used RAM: ");
16451        memInfoBuilder.append(stringifyKBSize(
16452                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16453        memInfoBuilder.append("\n");
16454        memInfoBuilder.append("  Lost RAM: ");
16455        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16456                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16457                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16458        memInfoBuilder.append("\n");
16459        Slog.i(TAG, "Low on memory:");
16460        Slog.i(TAG, shortNativeBuilder.toString());
16461        Slog.i(TAG, fullJavaBuilder.toString());
16462        Slog.i(TAG, memInfoBuilder.toString());
16463
16464        StringBuilder dropBuilder = new StringBuilder(1024);
16465        /*
16466        StringWriter oomSw = new StringWriter();
16467        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16468        StringWriter catSw = new StringWriter();
16469        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16470        String[] emptyArgs = new String[] { };
16471        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16472        oomPw.flush();
16473        String oomString = oomSw.toString();
16474        */
16475        dropBuilder.append("Low on memory:");
16476        dropBuilder.append(stack);
16477        dropBuilder.append('\n');
16478        dropBuilder.append(fullNativeBuilder);
16479        dropBuilder.append(fullJavaBuilder);
16480        dropBuilder.append('\n');
16481        dropBuilder.append(memInfoBuilder);
16482        dropBuilder.append('\n');
16483        /*
16484        dropBuilder.append(oomString);
16485        dropBuilder.append('\n');
16486        */
16487        StringWriter catSw = new StringWriter();
16488        synchronized (ActivityManagerService.this) {
16489            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16490            String[] emptyArgs = new String[] { };
16491            catPw.println();
16492            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16493            catPw.println();
16494            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16495                    false, null).dumpLocked();
16496            catPw.println();
16497            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16498            catPw.flush();
16499        }
16500        dropBuilder.append(catSw.toString());
16501        addErrorToDropBox("lowmem", null, "system_server", null,
16502                null, tag.toString(), dropBuilder.toString(), null, null);
16503        //Slog.i(TAG, "Sent to dropbox:");
16504        //Slog.i(TAG, dropBuilder.toString());
16505        synchronized (ActivityManagerService.this) {
16506            long now = SystemClock.uptimeMillis();
16507            if (mLastMemUsageReportTime < now) {
16508                mLastMemUsageReportTime = now;
16509            }
16510        }
16511    }
16512
16513    /**
16514     * Searches array of arguments for the specified string
16515     * @param args array of argument strings
16516     * @param value value to search for
16517     * @return true if the value is contained in the array
16518     */
16519    private static boolean scanArgs(String[] args, String value) {
16520        if (args != null) {
16521            for (String arg : args) {
16522                if (value.equals(arg)) {
16523                    return true;
16524                }
16525            }
16526        }
16527        return false;
16528    }
16529
16530    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16531            ContentProviderRecord cpr, boolean always) {
16532        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16533
16534        if (!inLaunching || always) {
16535            synchronized (cpr) {
16536                cpr.launchingApp = null;
16537                cpr.notifyAll();
16538            }
16539            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16540            String names[] = cpr.info.authority.split(";");
16541            for (int j = 0; j < names.length; j++) {
16542                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16543            }
16544        }
16545
16546        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16547            ContentProviderConnection conn = cpr.connections.get(i);
16548            if (conn.waiting) {
16549                // If this connection is waiting for the provider, then we don't
16550                // need to mess with its process unless we are always removing
16551                // or for some reason the provider is not currently launching.
16552                if (inLaunching && !always) {
16553                    continue;
16554                }
16555            }
16556            ProcessRecord capp = conn.client;
16557            conn.dead = true;
16558            if (conn.stableCount > 0) {
16559                if (!capp.persistent && capp.thread != null
16560                        && capp.pid != 0
16561                        && capp.pid != MY_PID) {
16562                    capp.kill("depends on provider "
16563                            + cpr.name.flattenToShortString()
16564                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16565                }
16566            } else if (capp.thread != null && conn.provider.provider != null) {
16567                try {
16568                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16569                } catch (RemoteException e) {
16570                }
16571                // In the protocol here, we don't expect the client to correctly
16572                // clean up this connection, we'll just remove it.
16573                cpr.connections.remove(i);
16574                if (conn.client.conProviders.remove(conn)) {
16575                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16576                }
16577            }
16578        }
16579
16580        if (inLaunching && always) {
16581            mLaunchingProviders.remove(cpr);
16582        }
16583        return inLaunching;
16584    }
16585
16586    /**
16587     * Main code for cleaning up a process when it has gone away.  This is
16588     * called both as a result of the process dying, or directly when stopping
16589     * a process when running in single process mode.
16590     *
16591     * @return Returns true if the given process has been restarted, so the
16592     * app that was passed in must remain on the process lists.
16593     */
16594    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16595            boolean restarting, boolean allowRestart, int index) {
16596        if (index >= 0) {
16597            removeLruProcessLocked(app);
16598            ProcessList.remove(app.pid);
16599        }
16600
16601        mProcessesToGc.remove(app);
16602        mPendingPssProcesses.remove(app);
16603
16604        // Dismiss any open dialogs.
16605        if (app.crashDialog != null && !app.forceCrashReport) {
16606            app.crashDialog.dismiss();
16607            app.crashDialog = null;
16608        }
16609        if (app.anrDialog != null) {
16610            app.anrDialog.dismiss();
16611            app.anrDialog = null;
16612        }
16613        if (app.waitDialog != null) {
16614            app.waitDialog.dismiss();
16615            app.waitDialog = null;
16616        }
16617
16618        app.crashing = false;
16619        app.notResponding = false;
16620
16621        app.resetPackageList(mProcessStats);
16622        app.unlinkDeathRecipient();
16623        app.makeInactive(mProcessStats);
16624        app.waitingToKill = null;
16625        app.forcingToForeground = null;
16626        updateProcessForegroundLocked(app, false, false);
16627        app.foregroundActivities = false;
16628        app.hasShownUi = false;
16629        app.treatLikeActivity = false;
16630        app.hasAboveClient = false;
16631        app.hasClientActivities = false;
16632
16633        mServices.killServicesLocked(app, allowRestart);
16634
16635        boolean restart = false;
16636
16637        // Remove published content providers.
16638        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16639            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16640            final boolean always = app.bad || !allowRestart;
16641            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16642            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16643                // We left the provider in the launching list, need to
16644                // restart it.
16645                restart = true;
16646            }
16647
16648            cpr.provider = null;
16649            cpr.proc = null;
16650        }
16651        app.pubProviders.clear();
16652
16653        // Take care of any launching providers waiting for this process.
16654        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16655            restart = true;
16656        }
16657
16658        // Unregister from connected content providers.
16659        if (!app.conProviders.isEmpty()) {
16660            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16661                ContentProviderConnection conn = app.conProviders.get(i);
16662                conn.provider.connections.remove(conn);
16663                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16664                        conn.provider.name);
16665            }
16666            app.conProviders.clear();
16667        }
16668
16669        // At this point there may be remaining entries in mLaunchingProviders
16670        // where we were the only one waiting, so they are no longer of use.
16671        // Look for these and clean up if found.
16672        // XXX Commented out for now.  Trying to figure out a way to reproduce
16673        // the actual situation to identify what is actually going on.
16674        if (false) {
16675            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16676                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16677                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16678                    synchronized (cpr) {
16679                        cpr.launchingApp = null;
16680                        cpr.notifyAll();
16681                    }
16682                }
16683            }
16684        }
16685
16686        skipCurrentReceiverLocked(app);
16687
16688        // Unregister any receivers.
16689        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16690            removeReceiverLocked(app.receivers.valueAt(i));
16691        }
16692        app.receivers.clear();
16693
16694        // If the app is undergoing backup, tell the backup manager about it
16695        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16696            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16697                    + mBackupTarget.appInfo + " died during backup");
16698            try {
16699                IBackupManager bm = IBackupManager.Stub.asInterface(
16700                        ServiceManager.getService(Context.BACKUP_SERVICE));
16701                bm.agentDisconnected(app.info.packageName);
16702            } catch (RemoteException e) {
16703                // can't happen; backup manager is local
16704            }
16705        }
16706
16707        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16708            ProcessChangeItem item = mPendingProcessChanges.get(i);
16709            if (item.pid == app.pid) {
16710                mPendingProcessChanges.remove(i);
16711                mAvailProcessChanges.add(item);
16712            }
16713        }
16714        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16715                null).sendToTarget();
16716
16717        // If the caller is restarting this app, then leave it in its
16718        // current lists and let the caller take care of it.
16719        if (restarting) {
16720            return false;
16721        }
16722
16723        if (!app.persistent || app.isolated) {
16724            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16725                    "Removing non-persistent process during cleanup: " + app);
16726            removeProcessNameLocked(app.processName, app.uid);
16727            if (mHeavyWeightProcess == app) {
16728                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16729                        mHeavyWeightProcess.userId, 0));
16730                mHeavyWeightProcess = null;
16731            }
16732        } else if (!app.removed) {
16733            // This app is persistent, so we need to keep its record around.
16734            // If it is not already on the pending app list, add it there
16735            // and start a new process for it.
16736            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16737                mPersistentStartingProcesses.add(app);
16738                restart = true;
16739            }
16740        }
16741        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16742                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16743        mProcessesOnHold.remove(app);
16744
16745        if (app == mHomeProcess) {
16746            mHomeProcess = null;
16747        }
16748        if (app == mPreviousProcess) {
16749            mPreviousProcess = null;
16750        }
16751
16752        if (restart && !app.isolated) {
16753            // We have components that still need to be running in the
16754            // process, so re-launch it.
16755            if (index < 0) {
16756                ProcessList.remove(app.pid);
16757            }
16758            addProcessNameLocked(app);
16759            startProcessLocked(app, "restart", app.processName);
16760            return true;
16761        } else if (app.pid > 0 && app.pid != MY_PID) {
16762            // Goodbye!
16763            boolean removed;
16764            synchronized (mPidsSelfLocked) {
16765                mPidsSelfLocked.remove(app.pid);
16766                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16767            }
16768            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16769            if (app.isolated) {
16770                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16771            }
16772            app.setPid(0);
16773        }
16774        return false;
16775    }
16776
16777    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16778        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16779            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16780            if (cpr.launchingApp == app) {
16781                return true;
16782            }
16783        }
16784        return false;
16785    }
16786
16787    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16788        // Look through the content providers we are waiting to have launched,
16789        // and if any run in this process then either schedule a restart of
16790        // the process or kill the client waiting for it if this process has
16791        // gone bad.
16792        boolean restart = false;
16793        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16794            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16795            if (cpr.launchingApp == app) {
16796                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16797                    restart = true;
16798                } else {
16799                    removeDyingProviderLocked(app, cpr, true);
16800                }
16801            }
16802        }
16803        return restart;
16804    }
16805
16806    // =========================================================
16807    // SERVICES
16808    // =========================================================
16809
16810    @Override
16811    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16812            int flags) {
16813        enforceNotIsolatedCaller("getServices");
16814        synchronized (this) {
16815            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16816        }
16817    }
16818
16819    @Override
16820    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16821        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16822        synchronized (this) {
16823            return mServices.getRunningServiceControlPanelLocked(name);
16824        }
16825    }
16826
16827    @Override
16828    public ComponentName startService(IApplicationThread caller, Intent service,
16829            String resolvedType, String callingPackage, int userId)
16830            throws TransactionTooLargeException {
16831        enforceNotIsolatedCaller("startService");
16832        // Refuse possible leaked file descriptors
16833        if (service != null && service.hasFileDescriptors() == true) {
16834            throw new IllegalArgumentException("File descriptors passed in Intent");
16835        }
16836
16837        if (callingPackage == null) {
16838            throw new IllegalArgumentException("callingPackage cannot be null");
16839        }
16840
16841        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16842                "startService: " + service + " type=" + resolvedType);
16843        synchronized(this) {
16844            final int callingPid = Binder.getCallingPid();
16845            final int callingUid = Binder.getCallingUid();
16846            final long origId = Binder.clearCallingIdentity();
16847            ComponentName res = mServices.startServiceLocked(caller, service,
16848                    resolvedType, callingPid, callingUid, callingPackage, userId);
16849            Binder.restoreCallingIdentity(origId);
16850            return res;
16851        }
16852    }
16853
16854    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16855            String callingPackage, int userId)
16856            throws TransactionTooLargeException {
16857        synchronized(this) {
16858            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16859                    "startServiceInPackage: " + service + " type=" + resolvedType);
16860            final long origId = Binder.clearCallingIdentity();
16861            ComponentName res = mServices.startServiceLocked(null, service,
16862                    resolvedType, -1, uid, callingPackage, userId);
16863            Binder.restoreCallingIdentity(origId);
16864            return res;
16865        }
16866    }
16867
16868    @Override
16869    public int stopService(IApplicationThread caller, Intent service,
16870            String resolvedType, int userId) {
16871        enforceNotIsolatedCaller("stopService");
16872        // Refuse possible leaked file descriptors
16873        if (service != null && service.hasFileDescriptors() == true) {
16874            throw new IllegalArgumentException("File descriptors passed in Intent");
16875        }
16876
16877        synchronized(this) {
16878            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16879        }
16880    }
16881
16882    @Override
16883    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16884        enforceNotIsolatedCaller("peekService");
16885        // Refuse possible leaked file descriptors
16886        if (service != null && service.hasFileDescriptors() == true) {
16887            throw new IllegalArgumentException("File descriptors passed in Intent");
16888        }
16889
16890        if (callingPackage == null) {
16891            throw new IllegalArgumentException("callingPackage cannot be null");
16892        }
16893
16894        synchronized(this) {
16895            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16896        }
16897    }
16898
16899    @Override
16900    public boolean stopServiceToken(ComponentName className, IBinder token,
16901            int startId) {
16902        synchronized(this) {
16903            return mServices.stopServiceTokenLocked(className, token, startId);
16904        }
16905    }
16906
16907    @Override
16908    public void setServiceForeground(ComponentName className, IBinder token,
16909            int id, Notification notification, int flags) {
16910        synchronized(this) {
16911            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16912        }
16913    }
16914
16915    @Override
16916    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16917            boolean requireFull, String name, String callerPackage) {
16918        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16919                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16920    }
16921
16922    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16923            String className, int flags) {
16924        boolean result = false;
16925        // For apps that don't have pre-defined UIDs, check for permission
16926        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16927            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16928                if (ActivityManager.checkUidPermission(
16929                        INTERACT_ACROSS_USERS,
16930                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16931                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16932                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16933                            + " requests FLAG_SINGLE_USER, but app does not hold "
16934                            + INTERACT_ACROSS_USERS;
16935                    Slog.w(TAG, msg);
16936                    throw new SecurityException(msg);
16937                }
16938                // Permission passed
16939                result = true;
16940            }
16941        } else if ("system".equals(componentProcessName)) {
16942            result = true;
16943        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16944            // Phone app and persistent apps are allowed to export singleuser providers.
16945            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16946                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16947        }
16948        if (DEBUG_MU) Slog.v(TAG_MU,
16949                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16950                + Integer.toHexString(flags) + ") = " + result);
16951        return result;
16952    }
16953
16954    /**
16955     * Checks to see if the caller is in the same app as the singleton
16956     * component, or the component is in a special app. It allows special apps
16957     * to export singleton components but prevents exporting singleton
16958     * components for regular apps.
16959     */
16960    boolean isValidSingletonCall(int callingUid, int componentUid) {
16961        int componentAppId = UserHandle.getAppId(componentUid);
16962        return UserHandle.isSameApp(callingUid, componentUid)
16963                || componentAppId == Process.SYSTEM_UID
16964                || componentAppId == Process.PHONE_UID
16965                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16966                        == PackageManager.PERMISSION_GRANTED;
16967    }
16968
16969    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16970            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16971            int userId) throws TransactionTooLargeException {
16972        enforceNotIsolatedCaller("bindService");
16973
16974        // Refuse possible leaked file descriptors
16975        if (service != null && service.hasFileDescriptors() == true) {
16976            throw new IllegalArgumentException("File descriptors passed in Intent");
16977        }
16978
16979        if (callingPackage == null) {
16980            throw new IllegalArgumentException("callingPackage cannot be null");
16981        }
16982
16983        synchronized(this) {
16984            return mServices.bindServiceLocked(caller, token, service,
16985                    resolvedType, connection, flags, callingPackage, userId);
16986        }
16987    }
16988
16989    public boolean unbindService(IServiceConnection connection) {
16990        synchronized (this) {
16991            return mServices.unbindServiceLocked(connection);
16992        }
16993    }
16994
16995    public void publishService(IBinder token, Intent intent, IBinder service) {
16996        // Refuse possible leaked file descriptors
16997        if (intent != null && intent.hasFileDescriptors() == true) {
16998            throw new IllegalArgumentException("File descriptors passed in Intent");
16999        }
17000
17001        synchronized(this) {
17002            if (!(token instanceof ServiceRecord)) {
17003                throw new IllegalArgumentException("Invalid service token");
17004            }
17005            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17006        }
17007    }
17008
17009    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17010        // Refuse possible leaked file descriptors
17011        if (intent != null && intent.hasFileDescriptors() == true) {
17012            throw new IllegalArgumentException("File descriptors passed in Intent");
17013        }
17014
17015        synchronized(this) {
17016            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17017        }
17018    }
17019
17020    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17021        synchronized(this) {
17022            if (!(token instanceof ServiceRecord)) {
17023                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17024                throw new IllegalArgumentException("Invalid service token");
17025            }
17026            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17027        }
17028    }
17029
17030    // =========================================================
17031    // BACKUP AND RESTORE
17032    // =========================================================
17033
17034    // Cause the target app to be launched if necessary and its backup agent
17035    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17036    // activity manager to announce its creation.
17037    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
17038        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
17039                "bindBackupAgent: app=" + app + " mode=" + backupMode);
17040        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17041
17042        synchronized(this) {
17043            // !!! TODO: currently no check here that we're already bound
17044            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17045            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17046            synchronized (stats) {
17047                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17048            }
17049
17050            // Backup agent is now in use, its package can't be stopped.
17051            try {
17052                AppGlobals.getPackageManager().setPackageStoppedState(
17053                        app.packageName, false, UserHandle.getUserId(app.uid));
17054            } catch (RemoteException e) {
17055            } catch (IllegalArgumentException e) {
17056                Slog.w(TAG, "Failed trying to unstop package "
17057                        + app.packageName + ": " + e);
17058            }
17059
17060            BackupRecord r = new BackupRecord(ss, app, backupMode);
17061            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17062                    ? new ComponentName(app.packageName, app.backupAgentName)
17063                    : new ComponentName("android", "FullBackupAgent");
17064            // startProcessLocked() returns existing proc's record if it's already running
17065            ProcessRecord proc = startProcessLocked(app.processName, app,
17066                    false, 0, "backup", hostingName, false, false, false);
17067            if (proc == null) {
17068                Slog.e(TAG, "Unable to start backup agent process " + r);
17069                return false;
17070            }
17071
17072            // If the app is a regular app (uid >= 10000) and not the system server or phone
17073            // process, etc, then mark it as being in full backup so that certain calls to the
17074            // process can be blocked. This is not reset to false anywhere because we kill the
17075            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17076            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17077                proc.inFullBackup = true;
17078            }
17079            r.app = proc;
17080            mBackupTarget = r;
17081            mBackupAppName = app.packageName;
17082
17083            // Try not to kill the process during backup
17084            updateOomAdjLocked(proc);
17085
17086            // If the process is already attached, schedule the creation of the backup agent now.
17087            // If it is not yet live, this will be done when it attaches to the framework.
17088            if (proc.thread != null) {
17089                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17090                try {
17091                    proc.thread.scheduleCreateBackupAgent(app,
17092                            compatibilityInfoForPackageLocked(app), backupMode);
17093                } catch (RemoteException e) {
17094                    // Will time out on the backup manager side
17095                }
17096            } else {
17097                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17098            }
17099            // Invariants: at this point, the target app process exists and the application
17100            // is either already running or in the process of coming up.  mBackupTarget and
17101            // mBackupAppName describe the app, so that when it binds back to the AM we
17102            // know that it's scheduled for a backup-agent operation.
17103        }
17104
17105        return true;
17106    }
17107
17108    @Override
17109    public void clearPendingBackup() {
17110        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17111        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17112
17113        synchronized (this) {
17114            mBackupTarget = null;
17115            mBackupAppName = null;
17116        }
17117    }
17118
17119    // A backup agent has just come up
17120    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17121        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17122                + " = " + agent);
17123
17124        synchronized(this) {
17125            if (!agentPackageName.equals(mBackupAppName)) {
17126                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17127                return;
17128            }
17129        }
17130
17131        long oldIdent = Binder.clearCallingIdentity();
17132        try {
17133            IBackupManager bm = IBackupManager.Stub.asInterface(
17134                    ServiceManager.getService(Context.BACKUP_SERVICE));
17135            bm.agentConnected(agentPackageName, agent);
17136        } catch (RemoteException e) {
17137            // can't happen; the backup manager service is local
17138        } catch (Exception e) {
17139            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17140            e.printStackTrace();
17141        } finally {
17142            Binder.restoreCallingIdentity(oldIdent);
17143        }
17144    }
17145
17146    // done with this agent
17147    public void unbindBackupAgent(ApplicationInfo appInfo) {
17148        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17149        if (appInfo == null) {
17150            Slog.w(TAG, "unbind backup agent for null app");
17151            return;
17152        }
17153
17154        synchronized(this) {
17155            try {
17156                if (mBackupAppName == null) {
17157                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17158                    return;
17159                }
17160
17161                if (!mBackupAppName.equals(appInfo.packageName)) {
17162                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17163                    return;
17164                }
17165
17166                // Not backing this app up any more; reset its OOM adjustment
17167                final ProcessRecord proc = mBackupTarget.app;
17168                updateOomAdjLocked(proc);
17169
17170                // If the app crashed during backup, 'thread' will be null here
17171                if (proc.thread != null) {
17172                    try {
17173                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17174                                compatibilityInfoForPackageLocked(appInfo));
17175                    } catch (Exception e) {
17176                        Slog.e(TAG, "Exception when unbinding backup agent:");
17177                        e.printStackTrace();
17178                    }
17179                }
17180            } finally {
17181                mBackupTarget = null;
17182                mBackupAppName = null;
17183            }
17184        }
17185    }
17186    // =========================================================
17187    // BROADCASTS
17188    // =========================================================
17189
17190    boolean isPendingBroadcastProcessLocked(int pid) {
17191        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17192                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17193    }
17194
17195    void skipPendingBroadcastLocked(int pid) {
17196            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17197            for (BroadcastQueue queue : mBroadcastQueues) {
17198                queue.skipPendingBroadcastLocked(pid);
17199            }
17200    }
17201
17202    // The app just attached; send any pending broadcasts that it should receive
17203    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17204        boolean didSomething = false;
17205        for (BroadcastQueue queue : mBroadcastQueues) {
17206            didSomething |= queue.sendPendingBroadcastsLocked(app);
17207        }
17208        return didSomething;
17209    }
17210
17211    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17212            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17213        enforceNotIsolatedCaller("registerReceiver");
17214        ArrayList<Intent> stickyIntents = null;
17215        ProcessRecord callerApp = null;
17216        int callingUid;
17217        int callingPid;
17218        synchronized(this) {
17219            if (caller != null) {
17220                callerApp = getRecordForAppLocked(caller);
17221                if (callerApp == null) {
17222                    throw new SecurityException(
17223                            "Unable to find app for caller " + caller
17224                            + " (pid=" + Binder.getCallingPid()
17225                            + ") when registering receiver " + receiver);
17226                }
17227                if (callerApp.info.uid != Process.SYSTEM_UID &&
17228                        !callerApp.pkgList.containsKey(callerPackage) &&
17229                        !"android".equals(callerPackage)) {
17230                    throw new SecurityException("Given caller package " + callerPackage
17231                            + " is not running in process " + callerApp);
17232                }
17233                callingUid = callerApp.info.uid;
17234                callingPid = callerApp.pid;
17235            } else {
17236                callerPackage = null;
17237                callingUid = Binder.getCallingUid();
17238                callingPid = Binder.getCallingPid();
17239            }
17240
17241            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17242                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17243
17244            Iterator<String> actions = filter.actionsIterator();
17245            if (actions == null) {
17246                ArrayList<String> noAction = new ArrayList<String>(1);
17247                noAction.add(null);
17248                actions = noAction.iterator();
17249            }
17250
17251            // Collect stickies of users
17252            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17253            while (actions.hasNext()) {
17254                String action = actions.next();
17255                for (int id : userIds) {
17256                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17257                    if (stickies != null) {
17258                        ArrayList<Intent> intents = stickies.get(action);
17259                        if (intents != null) {
17260                            if (stickyIntents == null) {
17261                                stickyIntents = new ArrayList<Intent>();
17262                            }
17263                            stickyIntents.addAll(intents);
17264                        }
17265                    }
17266                }
17267            }
17268        }
17269
17270        ArrayList<Intent> allSticky = null;
17271        if (stickyIntents != null) {
17272            final ContentResolver resolver = mContext.getContentResolver();
17273            // Look for any matching sticky broadcasts...
17274            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17275                Intent intent = stickyIntents.get(i);
17276                // If intent has scheme "content", it will need to acccess
17277                // provider that needs to lock mProviderMap in ActivityThread
17278                // and also it may need to wait application response, so we
17279                // cannot lock ActivityManagerService here.
17280                if (filter.match(resolver, intent, true, TAG) >= 0) {
17281                    if (allSticky == null) {
17282                        allSticky = new ArrayList<Intent>();
17283                    }
17284                    allSticky.add(intent);
17285                }
17286            }
17287        }
17288
17289        // The first sticky in the list is returned directly back to the client.
17290        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17291        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17292        if (receiver == null) {
17293            return sticky;
17294        }
17295
17296        synchronized (this) {
17297            if (callerApp != null && (callerApp.thread == null
17298                    || callerApp.thread.asBinder() != caller.asBinder())) {
17299                // Original caller already died
17300                return null;
17301            }
17302            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17303            if (rl == null) {
17304                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17305                        userId, receiver);
17306                if (rl.app != null) {
17307                    rl.app.receivers.add(rl);
17308                } else {
17309                    try {
17310                        receiver.asBinder().linkToDeath(rl, 0);
17311                    } catch (RemoteException e) {
17312                        return sticky;
17313                    }
17314                    rl.linkedToDeath = true;
17315                }
17316                mRegisteredReceivers.put(receiver.asBinder(), rl);
17317            } else if (rl.uid != callingUid) {
17318                throw new IllegalArgumentException(
17319                        "Receiver requested to register for uid " + callingUid
17320                        + " was previously registered for uid " + rl.uid);
17321            } else if (rl.pid != callingPid) {
17322                throw new IllegalArgumentException(
17323                        "Receiver requested to register for pid " + callingPid
17324                        + " was previously registered for pid " + rl.pid);
17325            } else if (rl.userId != userId) {
17326                throw new IllegalArgumentException(
17327                        "Receiver requested to register for user " + userId
17328                        + " was previously registered for user " + rl.userId);
17329            }
17330            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17331                    permission, callingUid, userId);
17332            rl.add(bf);
17333            if (!bf.debugCheck()) {
17334                Slog.w(TAG, "==> For Dynamic broadcast");
17335            }
17336            mReceiverResolver.addFilter(bf);
17337
17338            // Enqueue broadcasts for all existing stickies that match
17339            // this filter.
17340            if (allSticky != null) {
17341                ArrayList receivers = new ArrayList();
17342                receivers.add(bf);
17343
17344                final int stickyCount = allSticky.size();
17345                for (int i = 0; i < stickyCount; i++) {
17346                    Intent intent = allSticky.get(i);
17347                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17348                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17349                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17350                            null, 0, null, null, false, true, true, -1);
17351                    queue.enqueueParallelBroadcastLocked(r);
17352                    queue.scheduleBroadcastsLocked();
17353                }
17354            }
17355
17356            return sticky;
17357        }
17358    }
17359
17360    public void unregisterReceiver(IIntentReceiver receiver) {
17361        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17362
17363        final long origId = Binder.clearCallingIdentity();
17364        try {
17365            boolean doTrim = false;
17366
17367            synchronized(this) {
17368                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17369                if (rl != null) {
17370                    final BroadcastRecord r = rl.curBroadcast;
17371                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17372                        final boolean doNext = r.queue.finishReceiverLocked(
17373                                r, r.resultCode, r.resultData, r.resultExtras,
17374                                r.resultAbort, false);
17375                        if (doNext) {
17376                            doTrim = true;
17377                            r.queue.processNextBroadcast(false);
17378                        }
17379                    }
17380
17381                    if (rl.app != null) {
17382                        rl.app.receivers.remove(rl);
17383                    }
17384                    removeReceiverLocked(rl);
17385                    if (rl.linkedToDeath) {
17386                        rl.linkedToDeath = false;
17387                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17388                    }
17389                }
17390            }
17391
17392            // If we actually concluded any broadcasts, we might now be able
17393            // to trim the recipients' apps from our working set
17394            if (doTrim) {
17395                trimApplications();
17396                return;
17397            }
17398
17399        } finally {
17400            Binder.restoreCallingIdentity(origId);
17401        }
17402    }
17403
17404    void removeReceiverLocked(ReceiverList rl) {
17405        mRegisteredReceivers.remove(rl.receiver.asBinder());
17406        for (int i = rl.size() - 1; i >= 0; i--) {
17407            mReceiverResolver.removeFilter(rl.get(i));
17408        }
17409    }
17410
17411    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17412        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17413            ProcessRecord r = mLruProcesses.get(i);
17414            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17415                try {
17416                    r.thread.dispatchPackageBroadcast(cmd, packages);
17417                } catch (RemoteException ex) {
17418                }
17419            }
17420        }
17421    }
17422
17423    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17424            int callingUid, int[] users) {
17425        // TODO: come back and remove this assumption to triage all broadcasts
17426        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17427
17428        List<ResolveInfo> receivers = null;
17429        try {
17430            HashSet<ComponentName> singleUserReceivers = null;
17431            boolean scannedFirstReceivers = false;
17432            for (int user : users) {
17433                // Skip users that have Shell restrictions, with exception of always permitted
17434                // Shell broadcasts
17435                if (callingUid == Process.SHELL_UID
17436                        && mUserController.hasUserRestriction(
17437                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17438                        && !isPermittedShellBroadcast(intent)) {
17439                    continue;
17440                }
17441                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17442                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17443                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17444                    // If this is not the system user, we need to check for
17445                    // any receivers that should be filtered out.
17446                    for (int i=0; i<newReceivers.size(); i++) {
17447                        ResolveInfo ri = newReceivers.get(i);
17448                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17449                            newReceivers.remove(i);
17450                            i--;
17451                        }
17452                    }
17453                }
17454                if (newReceivers != null && newReceivers.size() == 0) {
17455                    newReceivers = null;
17456                }
17457                if (receivers == null) {
17458                    receivers = newReceivers;
17459                } else if (newReceivers != null) {
17460                    // We need to concatenate the additional receivers
17461                    // found with what we have do far.  This would be easy,
17462                    // but we also need to de-dup any receivers that are
17463                    // singleUser.
17464                    if (!scannedFirstReceivers) {
17465                        // Collect any single user receivers we had already retrieved.
17466                        scannedFirstReceivers = true;
17467                        for (int i=0; i<receivers.size(); i++) {
17468                            ResolveInfo ri = receivers.get(i);
17469                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17470                                ComponentName cn = new ComponentName(
17471                                        ri.activityInfo.packageName, ri.activityInfo.name);
17472                                if (singleUserReceivers == null) {
17473                                    singleUserReceivers = new HashSet<ComponentName>();
17474                                }
17475                                singleUserReceivers.add(cn);
17476                            }
17477                        }
17478                    }
17479                    // Add the new results to the existing results, tracking
17480                    // and de-dupping single user receivers.
17481                    for (int i=0; i<newReceivers.size(); i++) {
17482                        ResolveInfo ri = newReceivers.get(i);
17483                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17484                            ComponentName cn = new ComponentName(
17485                                    ri.activityInfo.packageName, ri.activityInfo.name);
17486                            if (singleUserReceivers == null) {
17487                                singleUserReceivers = new HashSet<ComponentName>();
17488                            }
17489                            if (!singleUserReceivers.contains(cn)) {
17490                                singleUserReceivers.add(cn);
17491                                receivers.add(ri);
17492                            }
17493                        } else {
17494                            receivers.add(ri);
17495                        }
17496                    }
17497                }
17498            }
17499        } catch (RemoteException ex) {
17500            // pm is in same process, this will never happen.
17501        }
17502        return receivers;
17503    }
17504
17505    private boolean isPermittedShellBroadcast(Intent intent) {
17506        // remote bugreport should always be allowed to be taken
17507        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17508    }
17509
17510    final int broadcastIntentLocked(ProcessRecord callerApp,
17511            String callerPackage, Intent intent, String resolvedType,
17512            IIntentReceiver resultTo, int resultCode, String resultData,
17513            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17514            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17515        intent = new Intent(intent);
17516
17517        // By default broadcasts do not go to stopped apps.
17518        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17519
17520        // If we have not finished booting, don't allow this to launch new processes.
17521        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17522            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17523        }
17524
17525        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17526                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17527                + " ordered=" + ordered + " userid=" + userId);
17528        if ((resultTo != null) && !ordered) {
17529            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17530        }
17531
17532        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17533                ALLOW_NON_FULL, "broadcast", callerPackage);
17534
17535        // Make sure that the user who is receiving this broadcast is running.
17536        // If not, we will just skip it. Make an exception for shutdown broadcasts
17537        // and upgrade steps.
17538
17539        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17540            if ((callingUid != Process.SYSTEM_UID
17541                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17542                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17543                Slog.w(TAG, "Skipping broadcast of " + intent
17544                        + ": user " + userId + " is stopped");
17545                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17546            }
17547        }
17548
17549        BroadcastOptions brOptions = null;
17550        if (bOptions != null) {
17551            brOptions = new BroadcastOptions(bOptions);
17552            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17553                // See if the caller is allowed to do this.  Note we are checking against
17554                // the actual real caller (not whoever provided the operation as say a
17555                // PendingIntent), because that who is actually supplied the arguments.
17556                if (checkComponentPermission(
17557                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17558                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17559                        != PackageManager.PERMISSION_GRANTED) {
17560                    String msg = "Permission Denial: " + intent.getAction()
17561                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17562                            + ", uid=" + callingUid + ")"
17563                            + " requires "
17564                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17565                    Slog.w(TAG, msg);
17566                    throw new SecurityException(msg);
17567                }
17568            }
17569        }
17570
17571        // Verify that protected broadcasts are only being sent by system code,
17572        // and that system code is only sending protected broadcasts.
17573        final String action = intent.getAction();
17574        final boolean isProtectedBroadcast;
17575        try {
17576            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17577        } catch (RemoteException e) {
17578            Slog.w(TAG, "Remote exception", e);
17579            return ActivityManager.BROADCAST_SUCCESS;
17580        }
17581
17582        final boolean isCallerSystem;
17583        switch (UserHandle.getAppId(callingUid)) {
17584            case Process.ROOT_UID:
17585            case Process.SYSTEM_UID:
17586            case Process.PHONE_UID:
17587            case Process.BLUETOOTH_UID:
17588            case Process.NFC_UID:
17589                isCallerSystem = true;
17590                break;
17591            default:
17592                isCallerSystem = (callerApp != null) && callerApp.persistent;
17593                break;
17594        }
17595
17596        if (isCallerSystem) {
17597            if (isProtectedBroadcast
17598                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17599                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17600                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17601                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17602                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17603                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17604                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17605                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17606                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17607                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17608                // Broadcast is either protected, or it's a public action that
17609                // we've relaxed, so it's fine for system internals to send.
17610            } else {
17611                // The vast majority of broadcasts sent from system internals
17612                // should be protected to avoid security holes, so yell loudly
17613                // to ensure we examine these cases.
17614                if (callerApp != null) {
17615                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17616                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17617                            new Throwable());
17618                } else {
17619                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17620                            + " from system uid " + UserHandle.formatUid(callingUid)
17621                            + " pkg " + callerPackage,
17622                            new Throwable());
17623                }
17624            }
17625
17626        } else {
17627            if (isProtectedBroadcast) {
17628                String msg = "Permission Denial: not allowed to send broadcast "
17629                        + action + " from pid="
17630                        + callingPid + ", uid=" + callingUid;
17631                Slog.w(TAG, msg);
17632                throw new SecurityException(msg);
17633
17634            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17635                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17636                // Special case for compatibility: we don't want apps to send this,
17637                // but historically it has not been protected and apps may be using it
17638                // to poke their own app widget.  So, instead of making it protected,
17639                // just limit it to the caller.
17640                if (callerPackage == null) {
17641                    String msg = "Permission Denial: not allowed to send broadcast "
17642                            + action + " from unknown caller.";
17643                    Slog.w(TAG, msg);
17644                    throw new SecurityException(msg);
17645                } else if (intent.getComponent() != null) {
17646                    // They are good enough to send to an explicit component...  verify
17647                    // it is being sent to the calling app.
17648                    if (!intent.getComponent().getPackageName().equals(
17649                            callerPackage)) {
17650                        String msg = "Permission Denial: not allowed to send broadcast "
17651                                + action + " to "
17652                                + intent.getComponent().getPackageName() + " from "
17653                                + callerPackage;
17654                        Slog.w(TAG, msg);
17655                        throw new SecurityException(msg);
17656                    }
17657                } else {
17658                    // Limit broadcast to their own package.
17659                    intent.setPackage(callerPackage);
17660                }
17661            }
17662        }
17663
17664        if (action != null) {
17665            switch (action) {
17666                case Intent.ACTION_UID_REMOVED:
17667                case Intent.ACTION_PACKAGE_REMOVED:
17668                case Intent.ACTION_PACKAGE_CHANGED:
17669                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17670                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17671                case Intent.ACTION_PACKAGES_SUSPENDED:
17672                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17673                    // Handle special intents: if this broadcast is from the package
17674                    // manager about a package being removed, we need to remove all of
17675                    // its activities from the history stack.
17676                    if (checkComponentPermission(
17677                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17678                            callingPid, callingUid, -1, true)
17679                            != PackageManager.PERMISSION_GRANTED) {
17680                        String msg = "Permission Denial: " + intent.getAction()
17681                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17682                                + ", uid=" + callingUid + ")"
17683                                + " requires "
17684                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17685                        Slog.w(TAG, msg);
17686                        throw new SecurityException(msg);
17687                    }
17688                    switch (action) {
17689                        case Intent.ACTION_UID_REMOVED:
17690                            final Bundle intentExtras = intent.getExtras();
17691                            final int uid = intentExtras != null
17692                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17693                            if (uid >= 0) {
17694                                mBatteryStatsService.removeUid(uid);
17695                                mAppOpsService.uidRemoved(uid);
17696                            }
17697                            break;
17698                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17699                            // If resources are unavailable just force stop all those packages
17700                            // and flush the attribute cache as well.
17701                            String list[] =
17702                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17703                            if (list != null && list.length > 0) {
17704                                for (int i = 0; i < list.length; i++) {
17705                                    forceStopPackageLocked(list[i], -1, false, true, true,
17706                                            false, false, userId, "storage unmount");
17707                                }
17708                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17709                                sendPackageBroadcastLocked(
17710                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17711                                        userId);
17712                            }
17713                            break;
17714                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17715                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17716                            break;
17717                        case Intent.ACTION_PACKAGE_REMOVED:
17718                        case Intent.ACTION_PACKAGE_CHANGED:
17719                            Uri data = intent.getData();
17720                            String ssp;
17721                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17722                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17723                                final boolean replacing =
17724                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17725                                final boolean killProcess =
17726                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17727                                final boolean fullUninstall = removed && !replacing;
17728                                if (removed) {
17729                                    if (killProcess) {
17730                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17731                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17732                                                false, true, true, false, fullUninstall, userId,
17733                                                removed ? "pkg removed" : "pkg changed");
17734                                    }
17735                                    final int cmd = killProcess
17736                                            ? IApplicationThread.PACKAGE_REMOVED
17737                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17738                                    sendPackageBroadcastLocked(cmd,
17739                                            new String[] {ssp}, userId);
17740                                    if (fullUninstall) {
17741                                        mAppOpsService.packageRemoved(
17742                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17743
17744                                        // Remove all permissions granted from/to this package
17745                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17746
17747                                        removeTasksByPackageNameLocked(ssp, userId);
17748                                        mBatteryStatsService.notePackageUninstalled(ssp);
17749                                    }
17750                                } else {
17751                                    if (killProcess) {
17752                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17753                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17754                                                userId, ProcessList.INVALID_ADJ,
17755                                                false, true, true, false, "change " + ssp);
17756                                    }
17757                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17758                                            intent.getStringArrayExtra(
17759                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17760                                }
17761                            }
17762                            break;
17763                        case Intent.ACTION_PACKAGES_SUSPENDED:
17764                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17765                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17766                                    intent.getAction());
17767                            final String[] packageNames = intent.getStringArrayExtra(
17768                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17769                            final int userHandle = intent.getIntExtra(
17770                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17771
17772                            synchronized(ActivityManagerService.this) {
17773                                mRecentTasks.onPackagesSuspendedChanged(
17774                                        packageNames, suspended, userHandle);
17775                            }
17776                            break;
17777                    }
17778                    break;
17779                case Intent.ACTION_PACKAGE_REPLACED:
17780                {
17781                    final Uri data = intent.getData();
17782                    final String ssp;
17783                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17784                        final ApplicationInfo aInfo =
17785                                getPackageManagerInternalLocked().getApplicationInfo(
17786                                        ssp,
17787                                        userId);
17788                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17789                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17790                                new String[] {ssp}, userId);
17791                    }
17792                    break;
17793                }
17794                case Intent.ACTION_PACKAGE_ADDED:
17795                {
17796                    // Special case for adding a package: by default turn on compatibility mode.
17797                    Uri data = intent.getData();
17798                    String ssp;
17799                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17800                        final boolean replacing =
17801                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17802                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17803
17804                        try {
17805                            ApplicationInfo ai = AppGlobals.getPackageManager().
17806                                    getApplicationInfo(ssp, 0, 0);
17807                            mBatteryStatsService.notePackageInstalled(ssp,
17808                                    ai != null ? ai.versionCode : 0);
17809                        } catch (RemoteException e) {
17810                        }
17811                    }
17812                    break;
17813                }
17814                case Intent.ACTION_TIMEZONE_CHANGED:
17815                    // If this is the time zone changed action, queue up a message that will reset
17816                    // the timezone of all currently running processes. This message will get
17817                    // queued up before the broadcast happens.
17818                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17819                    break;
17820                case Intent.ACTION_TIME_CHANGED:
17821                    // If the user set the time, let all running processes know.
17822                    final int is24Hour =
17823                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17824                                    : 0;
17825                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17826                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17827                    synchronized (stats) {
17828                        stats.noteCurrentTimeChangedLocked();
17829                    }
17830                    break;
17831                case Intent.ACTION_CLEAR_DNS_CACHE:
17832                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17833                    break;
17834                case Proxy.PROXY_CHANGE_ACTION:
17835                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17836                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17837                    break;
17838                case android.hardware.Camera.ACTION_NEW_PICTURE:
17839                case android.hardware.Camera.ACTION_NEW_VIDEO:
17840                    // These broadcasts are no longer allowed by the system, since they can
17841                    // cause significant thrashing at a crictical point (using the camera).
17842                    // Apps should use JobScehduler to monitor for media provider changes.
17843                    Slog.w(TAG, action + " no longer allowed; dropping from "
17844                            + UserHandle.formatUid(callingUid));
17845                    // Lie; we don't want to crash the app.
17846                    return ActivityManager.BROADCAST_SUCCESS;
17847            }
17848        }
17849
17850        // Add to the sticky list if requested.
17851        if (sticky) {
17852            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17853                    callingPid, callingUid)
17854                    != PackageManager.PERMISSION_GRANTED) {
17855                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17856                        + callingPid + ", uid=" + callingUid
17857                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17858                Slog.w(TAG, msg);
17859                throw new SecurityException(msg);
17860            }
17861            if (requiredPermissions != null && requiredPermissions.length > 0) {
17862                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17863                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17864                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17865            }
17866            if (intent.getComponent() != null) {
17867                throw new SecurityException(
17868                        "Sticky broadcasts can't target a specific component");
17869            }
17870            // We use userId directly here, since the "all" target is maintained
17871            // as a separate set of sticky broadcasts.
17872            if (userId != UserHandle.USER_ALL) {
17873                // But first, if this is not a broadcast to all users, then
17874                // make sure it doesn't conflict with an existing broadcast to
17875                // all users.
17876                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17877                        UserHandle.USER_ALL);
17878                if (stickies != null) {
17879                    ArrayList<Intent> list = stickies.get(intent.getAction());
17880                    if (list != null) {
17881                        int N = list.size();
17882                        int i;
17883                        for (i=0; i<N; i++) {
17884                            if (intent.filterEquals(list.get(i))) {
17885                                throw new IllegalArgumentException(
17886                                        "Sticky broadcast " + intent + " for user "
17887                                        + userId + " conflicts with existing global broadcast");
17888                            }
17889                        }
17890                    }
17891                }
17892            }
17893            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17894            if (stickies == null) {
17895                stickies = new ArrayMap<>();
17896                mStickyBroadcasts.put(userId, stickies);
17897            }
17898            ArrayList<Intent> list = stickies.get(intent.getAction());
17899            if (list == null) {
17900                list = new ArrayList<>();
17901                stickies.put(intent.getAction(), list);
17902            }
17903            final int stickiesCount = list.size();
17904            int i;
17905            for (i = 0; i < stickiesCount; i++) {
17906                if (intent.filterEquals(list.get(i))) {
17907                    // This sticky already exists, replace it.
17908                    list.set(i, new Intent(intent));
17909                    break;
17910                }
17911            }
17912            if (i >= stickiesCount) {
17913                list.add(new Intent(intent));
17914            }
17915        }
17916
17917        int[] users;
17918        if (userId == UserHandle.USER_ALL) {
17919            // Caller wants broadcast to go to all started users.
17920            users = mUserController.getStartedUserArrayLocked();
17921        } else {
17922            // Caller wants broadcast to go to one specific user.
17923            users = new int[] {userId};
17924        }
17925
17926        // Figure out who all will receive this broadcast.
17927        List receivers = null;
17928        List<BroadcastFilter> registeredReceivers = null;
17929        // Need to resolve the intent to interested receivers...
17930        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17931                 == 0) {
17932            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17933        }
17934        if (intent.getComponent() == null) {
17935            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17936                // Query one target user at a time, excluding shell-restricted users
17937                for (int i = 0; i < users.length; i++) {
17938                    if (mUserController.hasUserRestriction(
17939                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17940                        continue;
17941                    }
17942                    List<BroadcastFilter> registeredReceiversForUser =
17943                            mReceiverResolver.queryIntent(intent,
17944                                    resolvedType, false, users[i]);
17945                    if (registeredReceivers == null) {
17946                        registeredReceivers = registeredReceiversForUser;
17947                    } else if (registeredReceiversForUser != null) {
17948                        registeredReceivers.addAll(registeredReceiversForUser);
17949                    }
17950                }
17951            } else {
17952                registeredReceivers = mReceiverResolver.queryIntent(intent,
17953                        resolvedType, false, userId);
17954            }
17955        }
17956
17957        final boolean replacePending =
17958                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17959
17960        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17961                + " replacePending=" + replacePending);
17962
17963        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17964        if (!ordered && NR > 0) {
17965            // If we are not serializing this broadcast, then send the
17966            // registered receivers separately so they don't wait for the
17967            // components to be launched.
17968            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17969            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17970                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17971                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17972                    resultExtras, ordered, sticky, false, userId);
17973            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17974            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17975            if (!replaced) {
17976                queue.enqueueParallelBroadcastLocked(r);
17977                queue.scheduleBroadcastsLocked();
17978            }
17979            registeredReceivers = null;
17980            NR = 0;
17981        }
17982
17983        // Merge into one list.
17984        int ir = 0;
17985        if (receivers != null) {
17986            // A special case for PACKAGE_ADDED: do not allow the package
17987            // being added to see this broadcast.  This prevents them from
17988            // using this as a back door to get run as soon as they are
17989            // installed.  Maybe in the future we want to have a special install
17990            // broadcast or such for apps, but we'd like to deliberately make
17991            // this decision.
17992            String skipPackages[] = null;
17993            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17994                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17995                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17996                Uri data = intent.getData();
17997                if (data != null) {
17998                    String pkgName = data.getSchemeSpecificPart();
17999                    if (pkgName != null) {
18000                        skipPackages = new String[] { pkgName };
18001                    }
18002                }
18003            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18004                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18005            }
18006            if (skipPackages != null && (skipPackages.length > 0)) {
18007                for (String skipPackage : skipPackages) {
18008                    if (skipPackage != null) {
18009                        int NT = receivers.size();
18010                        for (int it=0; it<NT; it++) {
18011                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18012                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18013                                receivers.remove(it);
18014                                it--;
18015                                NT--;
18016                            }
18017                        }
18018                    }
18019                }
18020            }
18021
18022            int NT = receivers != null ? receivers.size() : 0;
18023            int it = 0;
18024            ResolveInfo curt = null;
18025            BroadcastFilter curr = null;
18026            while (it < NT && ir < NR) {
18027                if (curt == null) {
18028                    curt = (ResolveInfo)receivers.get(it);
18029                }
18030                if (curr == null) {
18031                    curr = registeredReceivers.get(ir);
18032                }
18033                if (curr.getPriority() >= curt.priority) {
18034                    // Insert this broadcast record into the final list.
18035                    receivers.add(it, curr);
18036                    ir++;
18037                    curr = null;
18038                    it++;
18039                    NT++;
18040                } else {
18041                    // Skip to the next ResolveInfo in the final list.
18042                    it++;
18043                    curt = null;
18044                }
18045            }
18046        }
18047        while (ir < NR) {
18048            if (receivers == null) {
18049                receivers = new ArrayList();
18050            }
18051            receivers.add(registeredReceivers.get(ir));
18052            ir++;
18053        }
18054
18055        if ((receivers != null && receivers.size() > 0)
18056                || resultTo != null) {
18057            BroadcastQueue queue = broadcastQueueForIntent(intent);
18058            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18059                    callerPackage, callingPid, callingUid, resolvedType,
18060                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18061                    resultData, resultExtras, ordered, sticky, false, userId);
18062
18063            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18064                    + ": prev had " + queue.mOrderedBroadcasts.size());
18065            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18066                    "Enqueueing broadcast " + r.intent.getAction());
18067
18068            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18069            if (!replaced) {
18070                queue.enqueueOrderedBroadcastLocked(r);
18071                queue.scheduleBroadcastsLocked();
18072            }
18073        } else {
18074            // There was nobody interested in the broadcast, but we still want to record
18075            // that it happened.
18076            if (intent.getComponent() == null && intent.getPackage() == null
18077                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18078                // This was an implicit broadcast... let's record it for posterity.
18079                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18080            }
18081        }
18082
18083        return ActivityManager.BROADCAST_SUCCESS;
18084    }
18085
18086    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18087            int skipCount, long dispatchTime) {
18088        final long now = SystemClock.elapsedRealtime();
18089        if (mCurBroadcastStats == null ||
18090                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18091            mLastBroadcastStats = mCurBroadcastStats;
18092            if (mLastBroadcastStats != null) {
18093                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18094                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18095            }
18096            mCurBroadcastStats = new BroadcastStats();
18097        }
18098        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18099    }
18100
18101    final Intent verifyBroadcastLocked(Intent intent) {
18102        // Refuse possible leaked file descriptors
18103        if (intent != null && intent.hasFileDescriptors() == true) {
18104            throw new IllegalArgumentException("File descriptors passed in Intent");
18105        }
18106
18107        int flags = intent.getFlags();
18108
18109        if (!mProcessesReady) {
18110            // if the caller really truly claims to know what they're doing, go
18111            // ahead and allow the broadcast without launching any receivers
18112            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18113                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18114            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18115                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18116                        + " before boot completion");
18117                throw new IllegalStateException("Cannot broadcast before boot completed");
18118            }
18119        }
18120
18121        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18122            throw new IllegalArgumentException(
18123                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18124        }
18125
18126        return intent;
18127    }
18128
18129    public final int broadcastIntent(IApplicationThread caller,
18130            Intent intent, String resolvedType, IIntentReceiver resultTo,
18131            int resultCode, String resultData, Bundle resultExtras,
18132            String[] requiredPermissions, int appOp, Bundle bOptions,
18133            boolean serialized, boolean sticky, int userId) {
18134        enforceNotIsolatedCaller("broadcastIntent");
18135        synchronized(this) {
18136            intent = verifyBroadcastLocked(intent);
18137
18138            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18139            final int callingPid = Binder.getCallingPid();
18140            final int callingUid = Binder.getCallingUid();
18141            final long origId = Binder.clearCallingIdentity();
18142            int res = broadcastIntentLocked(callerApp,
18143                    callerApp != null ? callerApp.info.packageName : null,
18144                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18145                    requiredPermissions, appOp, bOptions, serialized, sticky,
18146                    callingPid, callingUid, userId);
18147            Binder.restoreCallingIdentity(origId);
18148            return res;
18149        }
18150    }
18151
18152
18153    int broadcastIntentInPackage(String packageName, int uid,
18154            Intent intent, String resolvedType, IIntentReceiver resultTo,
18155            int resultCode, String resultData, Bundle resultExtras,
18156            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18157            int userId) {
18158        synchronized(this) {
18159            intent = verifyBroadcastLocked(intent);
18160
18161            final long origId = Binder.clearCallingIdentity();
18162            String[] requiredPermissions = requiredPermission == null ? null
18163                    : new String[] {requiredPermission};
18164            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18165                    resultTo, resultCode, resultData, resultExtras,
18166                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18167                    sticky, -1, uid, userId);
18168            Binder.restoreCallingIdentity(origId);
18169            return res;
18170        }
18171    }
18172
18173    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18174        // Refuse possible leaked file descriptors
18175        if (intent != null && intent.hasFileDescriptors() == true) {
18176            throw new IllegalArgumentException("File descriptors passed in Intent");
18177        }
18178
18179        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18180                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18181
18182        synchronized(this) {
18183            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18184                    != PackageManager.PERMISSION_GRANTED) {
18185                String msg = "Permission Denial: unbroadcastIntent() from pid="
18186                        + Binder.getCallingPid()
18187                        + ", uid=" + Binder.getCallingUid()
18188                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18189                Slog.w(TAG, msg);
18190                throw new SecurityException(msg);
18191            }
18192            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18193            if (stickies != null) {
18194                ArrayList<Intent> list = stickies.get(intent.getAction());
18195                if (list != null) {
18196                    int N = list.size();
18197                    int i;
18198                    for (i=0; i<N; i++) {
18199                        if (intent.filterEquals(list.get(i))) {
18200                            list.remove(i);
18201                            break;
18202                        }
18203                    }
18204                    if (list.size() <= 0) {
18205                        stickies.remove(intent.getAction());
18206                    }
18207                }
18208                if (stickies.size() <= 0) {
18209                    mStickyBroadcasts.remove(userId);
18210                }
18211            }
18212        }
18213    }
18214
18215    void backgroundServicesFinishedLocked(int userId) {
18216        for (BroadcastQueue queue : mBroadcastQueues) {
18217            queue.backgroundServicesFinishedLocked(userId);
18218        }
18219    }
18220
18221    public void finishReceiver(IBinder who, int resultCode, String resultData,
18222            Bundle resultExtras, boolean resultAbort, int flags) {
18223        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18224
18225        // Refuse possible leaked file descriptors
18226        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18227            throw new IllegalArgumentException("File descriptors passed in Bundle");
18228        }
18229
18230        final long origId = Binder.clearCallingIdentity();
18231        try {
18232            boolean doNext = false;
18233            BroadcastRecord r;
18234
18235            synchronized(this) {
18236                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18237                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18238                r = queue.getMatchingOrderedReceiver(who);
18239                if (r != null) {
18240                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18241                        resultData, resultExtras, resultAbort, true);
18242                }
18243            }
18244
18245            if (doNext) {
18246                r.queue.processNextBroadcast(false);
18247            }
18248            trimApplications();
18249        } finally {
18250            Binder.restoreCallingIdentity(origId);
18251        }
18252    }
18253
18254    // =========================================================
18255    // INSTRUMENTATION
18256    // =========================================================
18257
18258    public boolean startInstrumentation(ComponentName className,
18259            String profileFile, int flags, Bundle arguments,
18260            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18261            int userId, String abiOverride) {
18262        enforceNotIsolatedCaller("startInstrumentation");
18263        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18264                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18265        // Refuse possible leaked file descriptors
18266        if (arguments != null && arguments.hasFileDescriptors()) {
18267            throw new IllegalArgumentException("File descriptors passed in Bundle");
18268        }
18269
18270        synchronized(this) {
18271            InstrumentationInfo ii = null;
18272            ApplicationInfo ai = null;
18273            try {
18274                ii = mContext.getPackageManager().getInstrumentationInfo(
18275                    className, STOCK_PM_FLAGS);
18276                ai = AppGlobals.getPackageManager().getApplicationInfo(
18277                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18278            } catch (PackageManager.NameNotFoundException e) {
18279            } catch (RemoteException e) {
18280            }
18281            if (ii == null) {
18282                reportStartInstrumentationFailureLocked(watcher, className,
18283                        "Unable to find instrumentation info for: " + className);
18284                return false;
18285            }
18286            if (ai == null) {
18287                reportStartInstrumentationFailureLocked(watcher, className,
18288                        "Unable to find instrumentation target package: " + ii.targetPackage);
18289                return false;
18290            }
18291            if (!ai.hasCode()) {
18292                reportStartInstrumentationFailureLocked(watcher, className,
18293                        "Instrumentation target has no code: " + ii.targetPackage);
18294                return false;
18295            }
18296
18297            int match = mContext.getPackageManager().checkSignatures(
18298                    ii.targetPackage, ii.packageName);
18299            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18300                String msg = "Permission Denial: starting instrumentation "
18301                        + className + " from pid="
18302                        + Binder.getCallingPid()
18303                        + ", uid=" + Binder.getCallingPid()
18304                        + " not allowed because package " + ii.packageName
18305                        + " does not have a signature matching the target "
18306                        + ii.targetPackage;
18307                reportStartInstrumentationFailureLocked(watcher, className, msg);
18308                throw new SecurityException(msg);
18309            }
18310
18311            final long origId = Binder.clearCallingIdentity();
18312            // Instrumentation can kill and relaunch even persistent processes
18313            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18314                    "start instr");
18315            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18316            app.instrumentationClass = className;
18317            app.instrumentationInfo = ai;
18318            app.instrumentationProfileFile = profileFile;
18319            app.instrumentationArguments = arguments;
18320            app.instrumentationWatcher = watcher;
18321            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18322            app.instrumentationResultClass = className;
18323            Binder.restoreCallingIdentity(origId);
18324        }
18325
18326        return true;
18327    }
18328
18329    /**
18330     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18331     * error to the logs, but if somebody is watching, send the report there too.  This enables
18332     * the "am" command to report errors with more information.
18333     *
18334     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18335     * @param cn The component name of the instrumentation.
18336     * @param report The error report.
18337     */
18338    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18339            ComponentName cn, String report) {
18340        Slog.w(TAG, report);
18341        if (watcher != null) {
18342            Bundle results = new Bundle();
18343            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18344            results.putString("Error", report);
18345            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18346        }
18347    }
18348
18349    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18350        if (app.instrumentationWatcher != null) {
18351            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18352                    app.instrumentationClass, resultCode, results);
18353        }
18354
18355        // Can't call out of the system process with a lock held, so post a message.
18356        if (app.instrumentationUiAutomationConnection != null) {
18357            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18358                    app.instrumentationUiAutomationConnection).sendToTarget();
18359        }
18360
18361        app.instrumentationWatcher = null;
18362        app.instrumentationUiAutomationConnection = null;
18363        app.instrumentationClass = null;
18364        app.instrumentationInfo = null;
18365        app.instrumentationProfileFile = null;
18366        app.instrumentationArguments = null;
18367
18368        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18369                "finished inst");
18370    }
18371
18372    public void finishInstrumentation(IApplicationThread target,
18373            int resultCode, Bundle results) {
18374        int userId = UserHandle.getCallingUserId();
18375        // Refuse possible leaked file descriptors
18376        if (results != null && results.hasFileDescriptors()) {
18377            throw new IllegalArgumentException("File descriptors passed in Intent");
18378        }
18379
18380        synchronized(this) {
18381            ProcessRecord app = getRecordForAppLocked(target);
18382            if (app == null) {
18383                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18384                return;
18385            }
18386            final long origId = Binder.clearCallingIdentity();
18387            finishInstrumentationLocked(app, resultCode, results);
18388            Binder.restoreCallingIdentity(origId);
18389        }
18390    }
18391
18392    // =========================================================
18393    // CONFIGURATION
18394    // =========================================================
18395
18396    public ConfigurationInfo getDeviceConfigurationInfo() {
18397        ConfigurationInfo config = new ConfigurationInfo();
18398        synchronized (this) {
18399            config.reqTouchScreen = mConfiguration.touchscreen;
18400            config.reqKeyboardType = mConfiguration.keyboard;
18401            config.reqNavigation = mConfiguration.navigation;
18402            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18403                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18404                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18405            }
18406            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18407                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18408                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18409            }
18410            config.reqGlEsVersion = GL_ES_VERSION;
18411        }
18412        return config;
18413    }
18414
18415    ActivityStack getFocusedStack() {
18416        return mStackSupervisor.getFocusedStack();
18417    }
18418
18419    @Override
18420    public int getFocusedStackId() throws RemoteException {
18421        ActivityStack focusedStack = getFocusedStack();
18422        if (focusedStack != null) {
18423            return focusedStack.getStackId();
18424        }
18425        return -1;
18426    }
18427
18428    public Configuration getConfiguration() {
18429        Configuration ci;
18430        synchronized(this) {
18431            ci = new Configuration(mConfiguration);
18432            ci.userSetLocale = false;
18433        }
18434        return ci;
18435    }
18436
18437    @Override
18438    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18439        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18440        synchronized (this) {
18441            mSuppressResizeConfigChanges = suppress;
18442        }
18443    }
18444
18445    @Override
18446    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18447        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18448        if (fromStackId == HOME_STACK_ID) {
18449            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18450        }
18451        synchronized (this) {
18452            final long origId = Binder.clearCallingIdentity();
18453            try {
18454                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18455            } finally {
18456                Binder.restoreCallingIdentity(origId);
18457            }
18458        }
18459    }
18460
18461    @Override
18462    public void updatePersistentConfiguration(Configuration values) {
18463        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18464                "updateConfiguration()");
18465        enforceWriteSettingsPermission("updateConfiguration()");
18466        if (values == null) {
18467            throw new NullPointerException("Configuration must not be null");
18468        }
18469
18470        int userId = UserHandle.getCallingUserId();
18471
18472        synchronized(this) {
18473            final long origId = Binder.clearCallingIdentity();
18474            updateConfigurationLocked(values, null, false, true, userId);
18475            Binder.restoreCallingIdentity(origId);
18476        }
18477    }
18478
18479    private void updateFontScaleIfNeeded() {
18480        final int currentUserId;
18481        synchronized(this) {
18482            currentUserId = mUserController.getCurrentUserIdLocked();
18483        }
18484        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18485                FONT_SCALE, 1.0f, currentUserId);
18486        if (mConfiguration.fontScale != scaleFactor) {
18487            final Configuration configuration = mWindowManager.computeNewConfiguration();
18488            configuration.fontScale = scaleFactor;
18489            updatePersistentConfiguration(configuration);
18490        }
18491    }
18492
18493    private void enforceWriteSettingsPermission(String func) {
18494        int uid = Binder.getCallingUid();
18495        if (uid == Process.ROOT_UID) {
18496            return;
18497        }
18498
18499        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18500                Settings.getPackageNameForUid(mContext, uid), false)) {
18501            return;
18502        }
18503
18504        String msg = "Permission Denial: " + func + " from pid="
18505                + Binder.getCallingPid()
18506                + ", uid=" + uid
18507                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18508        Slog.w(TAG, msg);
18509        throw new SecurityException(msg);
18510    }
18511
18512    public void updateConfiguration(Configuration values) {
18513        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18514                "updateConfiguration()");
18515
18516        synchronized(this) {
18517            if (values == null && mWindowManager != null) {
18518                // sentinel: fetch the current configuration from the window manager
18519                values = mWindowManager.computeNewConfiguration();
18520            }
18521
18522            if (mWindowManager != null) {
18523                mProcessList.applyDisplaySize(mWindowManager);
18524            }
18525
18526            final long origId = Binder.clearCallingIdentity();
18527            if (values != null) {
18528                Settings.System.clearConfiguration(values);
18529            }
18530            updateConfigurationLocked(values, null, false);
18531            Binder.restoreCallingIdentity(origId);
18532        }
18533    }
18534
18535    void updateUserConfigurationLocked() {
18536        Configuration configuration = new Configuration(mConfiguration);
18537        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18538                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18539        updateConfigurationLocked(configuration, null, false);
18540    }
18541
18542    boolean updateConfigurationLocked(Configuration values,
18543            ActivityRecord starting, boolean initLocale) {
18544        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18545        return updateConfigurationLocked(values, starting, initLocale, false,
18546                UserHandle.USER_NULL);
18547    }
18548
18549    // To cache the list of supported system locales
18550    private String[] mSupportedSystemLocales = null;
18551
18552    /**
18553     * Do either or both things: (1) change the current configuration, and (2)
18554     * make sure the given activity is running with the (now) current
18555     * configuration.  Returns true if the activity has been left running, or
18556     * false if <var>starting</var> is being destroyed to match the new
18557     * configuration.
18558     *
18559     * @param userId is only used when persistent parameter is set to true to persist configuration
18560     *               for that particular user
18561     */
18562    private boolean updateConfigurationLocked(Configuration values,
18563            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18564        int changes = 0;
18565
18566        if (mWindowManager != null) {
18567            mWindowManager.deferSurfaceLayout();
18568        }
18569        if (values != null) {
18570            Configuration newConfig = new Configuration(mConfiguration);
18571            changes = newConfig.updateFrom(values);
18572            if (changes != 0) {
18573                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18574                        "Updating configuration to: " + values);
18575
18576                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18577
18578                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18579                    final LocaleList locales = values.getLocales();
18580                    int bestLocaleIndex = 0;
18581                    if (locales.size() > 1) {
18582                        if (mSupportedSystemLocales == null) {
18583                            mSupportedSystemLocales =
18584                                    Resources.getSystem().getAssets().getLocales();
18585                        }
18586                        bestLocaleIndex = Math.max(0,
18587                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18588                    }
18589                    SystemProperties.set("persist.sys.locale",
18590                            locales.get(bestLocaleIndex).toLanguageTag());
18591                    LocaleList.setDefault(locales, bestLocaleIndex);
18592                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18593                            locales.get(bestLocaleIndex)));
18594                }
18595
18596                mConfigurationSeq++;
18597                if (mConfigurationSeq <= 0) {
18598                    mConfigurationSeq = 1;
18599                }
18600                newConfig.seq = mConfigurationSeq;
18601                mConfiguration = newConfig;
18602                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18603                mUsageStatsService.reportConfigurationChange(newConfig,
18604                        mUserController.getCurrentUserIdLocked());
18605                //mUsageStatsService.noteStartConfig(newConfig);
18606
18607                final Configuration configCopy = new Configuration(mConfiguration);
18608
18609                // TODO: If our config changes, should we auto dismiss any currently
18610                // showing dialogs?
18611                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18612
18613                AttributeCache ac = AttributeCache.instance();
18614                if (ac != null) {
18615                    ac.updateConfiguration(configCopy);
18616                }
18617
18618                // Make sure all resources in our process are updated
18619                // right now, so that anyone who is going to retrieve
18620                // resource values after we return will be sure to get
18621                // the new ones.  This is especially important during
18622                // boot, where the first config change needs to guarantee
18623                // all resources have that config before following boot
18624                // code is executed.
18625                mSystemThread.applyConfigurationToResources(configCopy);
18626
18627                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18628                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18629                    msg.obj = new Configuration(configCopy);
18630                    msg.arg1 = userId;
18631                    mHandler.sendMessage(msg);
18632                }
18633
18634                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18635                if (isDensityChange) {
18636                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18637                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18638                }
18639
18640                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18641                    ProcessRecord app = mLruProcesses.get(i);
18642                    try {
18643                        if (app.thread != null) {
18644                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18645                                    + app.processName + " new config " + mConfiguration);
18646                            app.thread.scheduleConfigurationChanged(configCopy);
18647                        }
18648                    } catch (Exception e) {
18649                    }
18650                }
18651                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18652                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18653                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18654                        | Intent.FLAG_RECEIVER_FOREGROUND);
18655                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18656                        null, AppOpsManager.OP_NONE, null, false, false,
18657                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18658                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18659                    // Tell the shortcut manager that the system locale changed.  It needs to know
18660                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18661                    // we "push" from here, rather than having the service listen to the broadcast.
18662                    final ShortcutServiceInternal shortcutService =
18663                            LocalServices.getService(ShortcutServiceInternal.class);
18664                    if (shortcutService != null) {
18665                        shortcutService.onSystemLocaleChangedNoLock();
18666                    }
18667
18668                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18669                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18670                    if (!mProcessesReady) {
18671                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18672                    }
18673                    broadcastIntentLocked(null, null, intent,
18674                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18675                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18676                }
18677            }
18678            // Update the configuration with WM first and check if any of the stacks need to be
18679            // resized due to the configuration change. If so, resize the stacks now and do any
18680            // relaunches if necessary. This way we don't need to relaunch again below in
18681            // ensureActivityConfigurationLocked().
18682            if (mWindowManager != null) {
18683                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18684                if (resizedStacks != null) {
18685                    for (int stackId : resizedStacks) {
18686                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18687                        mStackSupervisor.resizeStackLocked(
18688                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18689                    }
18690                }
18691            }
18692        }
18693
18694        boolean kept = true;
18695        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18696        // mainStack is null during startup.
18697        if (mainStack != null) {
18698            if (changes != 0 && starting == null) {
18699                // If the configuration changed, and the caller is not already
18700                // in the process of starting an activity, then find the top
18701                // activity to check if its configuration needs to change.
18702                starting = mainStack.topRunningActivityLocked();
18703            }
18704
18705            if (starting != null) {
18706                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18707                // And we need to make sure at this point that all other activities
18708                // are made visible with the correct configuration.
18709                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18710                        !PRESERVE_WINDOWS);
18711            }
18712        }
18713        if (mWindowManager != null) {
18714            mWindowManager.continueSurfaceLayout();
18715        }
18716        return kept;
18717    }
18718
18719    /**
18720     * Decide based on the configuration whether we should shouw the ANR,
18721     * crash, etc dialogs.  The idea is that if there is no affordnace to
18722     * press the on-screen buttons, we shouldn't show the dialog.
18723     *
18724     * A thought: SystemUI might also want to get told about this, the Power
18725     * dialog / global actions also might want different behaviors.
18726     */
18727    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18728        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18729                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18730                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18731        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18732                                    == Configuration.UI_MODE_TYPE_CAR);
18733        return inputMethodExists && uiIsNotCarType && !inVrMode;
18734    }
18735
18736    @Override
18737    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18738        synchronized (this) {
18739            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18740            if (srec != null) {
18741                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18742            }
18743        }
18744        return false;
18745    }
18746
18747    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18748            Intent resultData) {
18749
18750        synchronized (this) {
18751            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18752            if (r != null) {
18753                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18754            }
18755            return false;
18756        }
18757    }
18758
18759    public int getLaunchedFromUid(IBinder activityToken) {
18760        ActivityRecord srec;
18761        synchronized (this) {
18762            srec = ActivityRecord.forTokenLocked(activityToken);
18763        }
18764        if (srec == null) {
18765            return -1;
18766        }
18767        return srec.launchedFromUid;
18768    }
18769
18770    public String getLaunchedFromPackage(IBinder activityToken) {
18771        ActivityRecord srec;
18772        synchronized (this) {
18773            srec = ActivityRecord.forTokenLocked(activityToken);
18774        }
18775        if (srec == null) {
18776            return null;
18777        }
18778        return srec.launchedFromPackage;
18779    }
18780
18781    // =========================================================
18782    // LIFETIME MANAGEMENT
18783    // =========================================================
18784
18785    // Returns which broadcast queue the app is the current [or imminent] receiver
18786    // on, or 'null' if the app is not an active broadcast recipient.
18787    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18788        BroadcastRecord r = app.curReceiver;
18789        if (r != null) {
18790            return r.queue;
18791        }
18792
18793        // It's not the current receiver, but it might be starting up to become one
18794        synchronized (this) {
18795            for (BroadcastQueue queue : mBroadcastQueues) {
18796                r = queue.mPendingBroadcast;
18797                if (r != null && r.curApp == app) {
18798                    // found it; report which queue it's in
18799                    return queue;
18800                }
18801            }
18802        }
18803
18804        return null;
18805    }
18806
18807    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18808            int targetUid, ComponentName targetComponent, String targetProcess) {
18809        if (!mTrackingAssociations) {
18810            return null;
18811        }
18812        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18813                = mAssociations.get(targetUid);
18814        if (components == null) {
18815            components = new ArrayMap<>();
18816            mAssociations.put(targetUid, components);
18817        }
18818        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18819        if (sourceUids == null) {
18820            sourceUids = new SparseArray<>();
18821            components.put(targetComponent, sourceUids);
18822        }
18823        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18824        if (sourceProcesses == null) {
18825            sourceProcesses = new ArrayMap<>();
18826            sourceUids.put(sourceUid, sourceProcesses);
18827        }
18828        Association ass = sourceProcesses.get(sourceProcess);
18829        if (ass == null) {
18830            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18831                    targetProcess);
18832            sourceProcesses.put(sourceProcess, ass);
18833        }
18834        ass.mCount++;
18835        ass.mNesting++;
18836        if (ass.mNesting == 1) {
18837            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18838            ass.mLastState = sourceState;
18839        }
18840        return ass;
18841    }
18842
18843    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18844            ComponentName targetComponent) {
18845        if (!mTrackingAssociations) {
18846            return;
18847        }
18848        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18849                = mAssociations.get(targetUid);
18850        if (components == null) {
18851            return;
18852        }
18853        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18854        if (sourceUids == null) {
18855            return;
18856        }
18857        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18858        if (sourceProcesses == null) {
18859            return;
18860        }
18861        Association ass = sourceProcesses.get(sourceProcess);
18862        if (ass == null || ass.mNesting <= 0) {
18863            return;
18864        }
18865        ass.mNesting--;
18866        if (ass.mNesting == 0) {
18867            long uptime = SystemClock.uptimeMillis();
18868            ass.mTime += uptime - ass.mStartTime;
18869            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18870                    += uptime - ass.mLastStateUptime;
18871            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18872        }
18873    }
18874
18875    private void noteUidProcessState(final int uid, final int state) {
18876        mBatteryStatsService.noteUidProcessState(uid, state);
18877        if (mTrackingAssociations) {
18878            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18879                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18880                        = mAssociations.valueAt(i1);
18881                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18882                    SparseArray<ArrayMap<String, Association>> sourceUids
18883                            = targetComponents.valueAt(i2);
18884                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18885                    if (sourceProcesses != null) {
18886                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18887                            Association ass = sourceProcesses.valueAt(i4);
18888                            if (ass.mNesting >= 1) {
18889                                // currently associated
18890                                long uptime = SystemClock.uptimeMillis();
18891                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18892                                        += uptime - ass.mLastStateUptime;
18893                                ass.mLastState = state;
18894                                ass.mLastStateUptime = uptime;
18895                            }
18896                        }
18897                    }
18898                }
18899            }
18900        }
18901    }
18902
18903    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18904            boolean doingAll, long now) {
18905        if (mAdjSeq == app.adjSeq) {
18906            // This adjustment has already been computed.
18907            return app.curRawAdj;
18908        }
18909
18910        if (app.thread == null) {
18911            app.adjSeq = mAdjSeq;
18912            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18913            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18914            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18915        }
18916
18917        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18918        app.adjSource = null;
18919        app.adjTarget = null;
18920        app.empty = false;
18921        app.cached = false;
18922
18923        final int activitiesSize = app.activities.size();
18924
18925        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18926            // The max adjustment doesn't allow this app to be anything
18927            // below foreground, so it is not worth doing work for it.
18928            app.adjType = "fixed";
18929            app.adjSeq = mAdjSeq;
18930            app.curRawAdj = app.maxAdj;
18931            app.foregroundActivities = false;
18932            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18933            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18934            // System processes can do UI, and when they do we want to have
18935            // them trim their memory after the user leaves the UI.  To
18936            // facilitate this, here we need to determine whether or not it
18937            // is currently showing UI.
18938            app.systemNoUi = true;
18939            if (app == TOP_APP) {
18940                app.systemNoUi = false;
18941                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18942                app.adjType = "pers-top-activity";
18943            } else if (activitiesSize > 0) {
18944                for (int j = 0; j < activitiesSize; j++) {
18945                    final ActivityRecord r = app.activities.get(j);
18946                    if (r.visible) {
18947                        app.systemNoUi = false;
18948                    }
18949                }
18950            }
18951            if (!app.systemNoUi) {
18952                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18953            }
18954            return (app.curAdj=app.maxAdj);
18955        }
18956
18957        app.systemNoUi = false;
18958
18959        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18960
18961        // Determine the importance of the process, starting with most
18962        // important to least, and assign an appropriate OOM adjustment.
18963        int adj;
18964        int schedGroup;
18965        int procState;
18966        boolean foregroundActivities = false;
18967        BroadcastQueue queue;
18968        if (app == TOP_APP) {
18969            // The last app on the list is the foreground app.
18970            adj = ProcessList.FOREGROUND_APP_ADJ;
18971            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18972            app.adjType = "top-activity";
18973            foregroundActivities = true;
18974            procState = PROCESS_STATE_CUR_TOP;
18975        } else if (app.instrumentationClass != null) {
18976            // Don't want to kill running instrumentation.
18977            adj = ProcessList.FOREGROUND_APP_ADJ;
18978            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18979            app.adjType = "instrumentation";
18980            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18981        } else if ((queue = isReceivingBroadcast(app)) != null) {
18982            // An app that is currently receiving a broadcast also
18983            // counts as being in the foreground for OOM killer purposes.
18984            // It's placed in a sched group based on the nature of the
18985            // broadcast as reflected by which queue it's active in.
18986            adj = ProcessList.FOREGROUND_APP_ADJ;
18987            schedGroup = (queue == mFgBroadcastQueue)
18988                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18989            app.adjType = "broadcast";
18990            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18991        } else if (app.executingServices.size() > 0) {
18992            // An app that is currently executing a service callback also
18993            // counts as being in the foreground.
18994            adj = ProcessList.FOREGROUND_APP_ADJ;
18995            schedGroup = app.execServicesFg ?
18996                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18997            app.adjType = "exec-service";
18998            procState = ActivityManager.PROCESS_STATE_SERVICE;
18999            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19000        } else {
19001            // As far as we know the process is empty.  We may change our mind later.
19002            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19003            // At this point we don't actually know the adjustment.  Use the cached adj
19004            // value that the caller wants us to.
19005            adj = cachedAdj;
19006            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19007            app.cached = true;
19008            app.empty = true;
19009            app.adjType = "cch-empty";
19010        }
19011
19012        // Examine all activities if not already foreground.
19013        if (!foregroundActivities && activitiesSize > 0) {
19014            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19015            for (int j = 0; j < activitiesSize; j++) {
19016                final ActivityRecord r = app.activities.get(j);
19017                if (r.app != app) {
19018                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19019                            + " instead of expected " + app);
19020                    if (r.app == null || (r.app.uid == app.uid)) {
19021                        // Only fix things up when they look sane
19022                        r.app = app;
19023                    } else {
19024                        continue;
19025                    }
19026                }
19027                if (r.visible) {
19028                    // App has a visible activity; only upgrade adjustment.
19029                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19030                        adj = ProcessList.VISIBLE_APP_ADJ;
19031                        app.adjType = "visible";
19032                    }
19033                    if (procState > PROCESS_STATE_CUR_TOP) {
19034                        procState = PROCESS_STATE_CUR_TOP;
19035                    }
19036                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19037                    app.cached = false;
19038                    app.empty = false;
19039                    foregroundActivities = true;
19040                    if (r.task != null && minLayer > 0) {
19041                        final int layer = r.task.mLayerRank;
19042                        if (layer >= 0 && minLayer > layer) {
19043                            minLayer = layer;
19044                        }
19045                    }
19046                    break;
19047                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19048                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19049                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19050                        app.adjType = "pausing";
19051                    }
19052                    if (procState > PROCESS_STATE_CUR_TOP) {
19053                        procState = PROCESS_STATE_CUR_TOP;
19054                    }
19055                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19056                    app.cached = false;
19057                    app.empty = false;
19058                    foregroundActivities = true;
19059                } else if (r.state == ActivityState.STOPPING) {
19060                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19061                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19062                        app.adjType = "stopping";
19063                    }
19064                    // For the process state, we will at this point consider the
19065                    // process to be cached.  It will be cached either as an activity
19066                    // or empty depending on whether the activity is finishing.  We do
19067                    // this so that we can treat the process as cached for purposes of
19068                    // memory trimming (determing current memory level, trim command to
19069                    // send to process) since there can be an arbitrary number of stopping
19070                    // processes and they should soon all go into the cached state.
19071                    if (!r.finishing) {
19072                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19073                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19074                        }
19075                    }
19076                    app.cached = false;
19077                    app.empty = false;
19078                    foregroundActivities = true;
19079                } else {
19080                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19081                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19082                        app.adjType = "cch-act";
19083                    }
19084                }
19085            }
19086            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19087                adj += minLayer;
19088            }
19089        }
19090
19091        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19092                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19093            if (app.foregroundServices) {
19094                // The user is aware of this app, so make it visible.
19095                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19096                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19097                app.cached = false;
19098                app.adjType = "fg-service";
19099                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19100            } else if (app.forcingToForeground != null) {
19101                // The user is aware of this app, so make it visible.
19102                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19103                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19104                app.cached = false;
19105                app.adjType = "force-fg";
19106                app.adjSource = app.forcingToForeground;
19107                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19108            }
19109        }
19110
19111        if (app == mHeavyWeightProcess) {
19112            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19113                // We don't want to kill the current heavy-weight process.
19114                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19115                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19116                app.cached = false;
19117                app.adjType = "heavy";
19118            }
19119            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19120                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19121            }
19122        }
19123
19124        if (app == mHomeProcess) {
19125            if (adj > ProcessList.HOME_APP_ADJ) {
19126                // This process is hosting what we currently consider to be the
19127                // home app, so we don't want to let it go into the background.
19128                adj = ProcessList.HOME_APP_ADJ;
19129                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19130                app.cached = false;
19131                app.adjType = "home";
19132            }
19133            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19134                procState = ActivityManager.PROCESS_STATE_HOME;
19135            }
19136        }
19137
19138        if (app == mPreviousProcess && app.activities.size() > 0) {
19139            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19140                // This was the previous process that showed UI to the user.
19141                // We want to try to keep it around more aggressively, to give
19142                // a good experience around switching between two apps.
19143                adj = ProcessList.PREVIOUS_APP_ADJ;
19144                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19145                app.cached = false;
19146                app.adjType = "previous";
19147            }
19148            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19149                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19150            }
19151        }
19152
19153        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19154                + " reason=" + app.adjType);
19155
19156        // By default, we use the computed adjustment.  It may be changed if
19157        // there are applications dependent on our services or providers, but
19158        // this gives us a baseline and makes sure we don't get into an
19159        // infinite recursion.
19160        app.adjSeq = mAdjSeq;
19161        app.curRawAdj = adj;
19162        app.hasStartedServices = false;
19163
19164        if (mBackupTarget != null && app == mBackupTarget.app) {
19165            // If possible we want to avoid killing apps while they're being backed up
19166            if (adj > ProcessList.BACKUP_APP_ADJ) {
19167                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19168                adj = ProcessList.BACKUP_APP_ADJ;
19169                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19170                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19171                }
19172                app.adjType = "backup";
19173                app.cached = false;
19174            }
19175            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19176                procState = ActivityManager.PROCESS_STATE_BACKUP;
19177            }
19178        }
19179
19180        boolean mayBeTop = false;
19181
19182        for (int is = app.services.size()-1;
19183                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19184                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19185                        || procState > ActivityManager.PROCESS_STATE_TOP);
19186                is--) {
19187            ServiceRecord s = app.services.valueAt(is);
19188            if (s.startRequested) {
19189                app.hasStartedServices = true;
19190                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19191                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19192                }
19193                if (app.hasShownUi && app != mHomeProcess) {
19194                    // If this process has shown some UI, let it immediately
19195                    // go to the LRU list because it may be pretty heavy with
19196                    // UI stuff.  We'll tag it with a label just to help
19197                    // debug and understand what is going on.
19198                    if (adj > ProcessList.SERVICE_ADJ) {
19199                        app.adjType = "cch-started-ui-services";
19200                    }
19201                } else {
19202                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19203                        // This service has seen some activity within
19204                        // recent memory, so we will keep its process ahead
19205                        // of the background processes.
19206                        if (adj > ProcessList.SERVICE_ADJ) {
19207                            adj = ProcessList.SERVICE_ADJ;
19208                            app.adjType = "started-services";
19209                            app.cached = false;
19210                        }
19211                    }
19212                    // If we have let the service slide into the background
19213                    // state, still have some text describing what it is doing
19214                    // even though the service no longer has an impact.
19215                    if (adj > ProcessList.SERVICE_ADJ) {
19216                        app.adjType = "cch-started-services";
19217                    }
19218                }
19219            }
19220
19221            app.whitelistManager = false;
19222
19223            for (int conni = s.connections.size()-1;
19224                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19225                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19226                            || procState > ActivityManager.PROCESS_STATE_TOP);
19227                    conni--) {
19228                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19229                for (int i = 0;
19230                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19231                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19232                                || procState > ActivityManager.PROCESS_STATE_TOP);
19233                        i++) {
19234                    // XXX should compute this based on the max of
19235                    // all connected clients.
19236                    ConnectionRecord cr = clist.get(i);
19237                    if (cr.binding.client == app) {
19238                        // Binding to ourself is not interesting.
19239                        continue;
19240                    }
19241                    if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19242                        app.whitelistManager = true;
19243                    }
19244
19245                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19246                        ProcessRecord client = cr.binding.client;
19247                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19248                                TOP_APP, doingAll, now);
19249                        int clientProcState = client.curProcState;
19250                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19251                            // If the other app is cached for any reason, for purposes here
19252                            // we are going to consider it empty.  The specific cached state
19253                            // doesn't propagate except under certain conditions.
19254                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19255                        }
19256                        String adjType = null;
19257                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19258                            // Not doing bind OOM management, so treat
19259                            // this guy more like a started service.
19260                            if (app.hasShownUi && app != mHomeProcess) {
19261                                // If this process has shown some UI, let it immediately
19262                                // go to the LRU list because it may be pretty heavy with
19263                                // UI stuff.  We'll tag it with a label just to help
19264                                // debug and understand what is going on.
19265                                if (adj > clientAdj) {
19266                                    adjType = "cch-bound-ui-services";
19267                                }
19268                                app.cached = false;
19269                                clientAdj = adj;
19270                                clientProcState = procState;
19271                            } else {
19272                                if (now >= (s.lastActivity
19273                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19274                                    // This service has not seen activity within
19275                                    // recent memory, so allow it to drop to the
19276                                    // LRU list if there is no other reason to keep
19277                                    // it around.  We'll also tag it with a label just
19278                                    // to help debug and undertand what is going on.
19279                                    if (adj > clientAdj) {
19280                                        adjType = "cch-bound-services";
19281                                    }
19282                                    clientAdj = adj;
19283                                }
19284                            }
19285                        }
19286                        if (adj > clientAdj) {
19287                            // If this process has recently shown UI, and
19288                            // the process that is binding to it is less
19289                            // important than being visible, then we don't
19290                            // care about the binding as much as we care
19291                            // about letting this process get into the LRU
19292                            // list to be killed and restarted if needed for
19293                            // memory.
19294                            if (app.hasShownUi && app != mHomeProcess
19295                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19296                                adjType = "cch-bound-ui-services";
19297                            } else {
19298                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19299                                        |Context.BIND_IMPORTANT)) != 0) {
19300                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19301                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19302                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19303                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19304                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19305                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19306                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19307                                    adj = clientAdj;
19308                                } else {
19309                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19310                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19311                                    }
19312                                }
19313                                if (!client.cached) {
19314                                    app.cached = false;
19315                                }
19316                                adjType = "service";
19317                            }
19318                        }
19319                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19320                            // This will treat important bound services identically to
19321                            // the top app, which may behave differently than generic
19322                            // foreground work.
19323                            if (client.curSchedGroup > schedGroup) {
19324                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19325                                    schedGroup = client.curSchedGroup;
19326                                } else {
19327                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19328                                }
19329                            }
19330                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19331                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19332                                    // Special handling of clients who are in the top state.
19333                                    // We *may* want to consider this process to be in the
19334                                    // top state as well, but only if there is not another
19335                                    // reason for it to be running.  Being on the top is a
19336                                    // special state, meaning you are specifically running
19337                                    // for the current top app.  If the process is already
19338                                    // running in the background for some other reason, it
19339                                    // is more important to continue considering it to be
19340                                    // in the background state.
19341                                    mayBeTop = true;
19342                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19343                                } else {
19344                                    // Special handling for above-top states (persistent
19345                                    // processes).  These should not bring the current process
19346                                    // into the top state, since they are not on top.  Instead
19347                                    // give them the best state after that.
19348                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19349                                        clientProcState =
19350                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19351                                    } else if (mWakefulness
19352                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19353                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19354                                                    != 0) {
19355                                        clientProcState =
19356                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19357                                    } else {
19358                                        clientProcState =
19359                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19360                                    }
19361                                }
19362                            }
19363                        } else {
19364                            if (clientProcState <
19365                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19366                                clientProcState =
19367                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19368                            }
19369                        }
19370                        if (procState > clientProcState) {
19371                            procState = clientProcState;
19372                        }
19373                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19374                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19375                            app.pendingUiClean = true;
19376                        }
19377                        if (adjType != null) {
19378                            app.adjType = adjType;
19379                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19380                                    .REASON_SERVICE_IN_USE;
19381                            app.adjSource = cr.binding.client;
19382                            app.adjSourceProcState = clientProcState;
19383                            app.adjTarget = s.name;
19384                        }
19385                    }
19386                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19387                        app.treatLikeActivity = true;
19388                    }
19389                    final ActivityRecord a = cr.activity;
19390                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19391                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19392                            (a.visible || a.state == ActivityState.RESUMED ||
19393                             a.state == ActivityState.PAUSING)) {
19394                            adj = ProcessList.FOREGROUND_APP_ADJ;
19395                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19396                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19397                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19398                                } else {
19399                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19400                                }
19401                            }
19402                            app.cached = false;
19403                            app.adjType = "service";
19404                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19405                                    .REASON_SERVICE_IN_USE;
19406                            app.adjSource = a;
19407                            app.adjSourceProcState = procState;
19408                            app.adjTarget = s.name;
19409                        }
19410                    }
19411                }
19412            }
19413        }
19414
19415        for (int provi = app.pubProviders.size()-1;
19416                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19417                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19418                        || procState > ActivityManager.PROCESS_STATE_TOP);
19419                provi--) {
19420            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19421            for (int i = cpr.connections.size()-1;
19422                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19423                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19424                            || procState > ActivityManager.PROCESS_STATE_TOP);
19425                    i--) {
19426                ContentProviderConnection conn = cpr.connections.get(i);
19427                ProcessRecord client = conn.client;
19428                if (client == app) {
19429                    // Being our own client is not interesting.
19430                    continue;
19431                }
19432                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19433                int clientProcState = client.curProcState;
19434                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19435                    // If the other app is cached for any reason, for purposes here
19436                    // we are going to consider it empty.
19437                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19438                }
19439                if (adj > clientAdj) {
19440                    if (app.hasShownUi && app != mHomeProcess
19441                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19442                        app.adjType = "cch-ui-provider";
19443                    } else {
19444                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19445                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19446                        app.adjType = "provider";
19447                    }
19448                    app.cached &= client.cached;
19449                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19450                            .REASON_PROVIDER_IN_USE;
19451                    app.adjSource = client;
19452                    app.adjSourceProcState = clientProcState;
19453                    app.adjTarget = cpr.name;
19454                }
19455                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19456                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19457                        // Special handling of clients who are in the top state.
19458                        // We *may* want to consider this process to be in the
19459                        // top state as well, but only if there is not another
19460                        // reason for it to be running.  Being on the top is a
19461                        // special state, meaning you are specifically running
19462                        // for the current top app.  If the process is already
19463                        // running in the background for some other reason, it
19464                        // is more important to continue considering it to be
19465                        // in the background state.
19466                        mayBeTop = true;
19467                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19468                    } else {
19469                        // Special handling for above-top states (persistent
19470                        // processes).  These should not bring the current process
19471                        // into the top state, since they are not on top.  Instead
19472                        // give them the best state after that.
19473                        clientProcState =
19474                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19475                    }
19476                }
19477                if (procState > clientProcState) {
19478                    procState = clientProcState;
19479                }
19480                if (client.curSchedGroup > schedGroup) {
19481                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19482                }
19483            }
19484            // If the provider has external (non-framework) process
19485            // dependencies, ensure that its adjustment is at least
19486            // FOREGROUND_APP_ADJ.
19487            if (cpr.hasExternalProcessHandles()) {
19488                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19489                    adj = ProcessList.FOREGROUND_APP_ADJ;
19490                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19491                    app.cached = false;
19492                    app.adjType = "provider";
19493                    app.adjTarget = cpr.name;
19494                }
19495                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19496                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19497                }
19498            }
19499        }
19500
19501        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19502            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19503                adj = ProcessList.PREVIOUS_APP_ADJ;
19504                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19505                app.cached = false;
19506                app.adjType = "provider";
19507            }
19508            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19509                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19510            }
19511        }
19512
19513        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19514            // A client of one of our services or providers is in the top state.  We
19515            // *may* want to be in the top state, but not if we are already running in
19516            // the background for some other reason.  For the decision here, we are going
19517            // to pick out a few specific states that we want to remain in when a client
19518            // is top (states that tend to be longer-term) and otherwise allow it to go
19519            // to the top state.
19520            switch (procState) {
19521                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19522                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19523                case ActivityManager.PROCESS_STATE_SERVICE:
19524                    // These all are longer-term states, so pull them up to the top
19525                    // of the background states, but not all the way to the top state.
19526                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19527                    break;
19528                default:
19529                    // Otherwise, top is a better choice, so take it.
19530                    procState = ActivityManager.PROCESS_STATE_TOP;
19531                    break;
19532            }
19533        }
19534
19535        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19536            if (app.hasClientActivities) {
19537                // This is a cached process, but with client activities.  Mark it so.
19538                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19539                app.adjType = "cch-client-act";
19540            } else if (app.treatLikeActivity) {
19541                // This is a cached process, but somebody wants us to treat it like it has
19542                // an activity, okay!
19543                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19544                app.adjType = "cch-as-act";
19545            }
19546        }
19547
19548        if (adj == ProcessList.SERVICE_ADJ) {
19549            if (doingAll) {
19550                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19551                mNewNumServiceProcs++;
19552                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19553                if (!app.serviceb) {
19554                    // This service isn't far enough down on the LRU list to
19555                    // normally be a B service, but if we are low on RAM and it
19556                    // is large we want to force it down since we would prefer to
19557                    // keep launcher over it.
19558                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19559                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19560                        app.serviceHighRam = true;
19561                        app.serviceb = true;
19562                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19563                    } else {
19564                        mNewNumAServiceProcs++;
19565                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19566                    }
19567                } else {
19568                    app.serviceHighRam = false;
19569                }
19570            }
19571            if (app.serviceb) {
19572                adj = ProcessList.SERVICE_B_ADJ;
19573            }
19574        }
19575
19576        app.curRawAdj = adj;
19577
19578        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19579        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19580        if (adj > app.maxAdj) {
19581            adj = app.maxAdj;
19582            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19583                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19584            }
19585        }
19586
19587        // Do final modification to adj.  Everything we do between here and applying
19588        // the final setAdj must be done in this function, because we will also use
19589        // it when computing the final cached adj later.  Note that we don't need to
19590        // worry about this for max adj above, since max adj will always be used to
19591        // keep it out of the cached vaues.
19592        app.curAdj = app.modifyRawOomAdj(adj);
19593        app.curSchedGroup = schedGroup;
19594        app.curProcState = procState;
19595        app.foregroundActivities = foregroundActivities;
19596
19597        return app.curRawAdj;
19598    }
19599
19600    /**
19601     * Record new PSS sample for a process.
19602     */
19603    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19604            long now) {
19605        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19606                swapPss * 1024);
19607        proc.lastPssTime = now;
19608        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19609        if (DEBUG_PSS) Slog.d(TAG_PSS,
19610                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19611                + " state=" + ProcessList.makeProcStateString(procState));
19612        if (proc.initialIdlePss == 0) {
19613            proc.initialIdlePss = pss;
19614        }
19615        proc.lastPss = pss;
19616        proc.lastSwapPss = swapPss;
19617        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19618            proc.lastCachedPss = pss;
19619            proc.lastCachedSwapPss = swapPss;
19620        }
19621
19622        final SparseArray<Pair<Long, String>> watchUids
19623                = mMemWatchProcesses.getMap().get(proc.processName);
19624        Long check = null;
19625        if (watchUids != null) {
19626            Pair<Long, String> val = watchUids.get(proc.uid);
19627            if (val == null) {
19628                val = watchUids.get(0);
19629            }
19630            if (val != null) {
19631                check = val.first;
19632            }
19633        }
19634        if (check != null) {
19635            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19636                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19637                if (!isDebuggable) {
19638                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19639                        isDebuggable = true;
19640                    }
19641                }
19642                if (isDebuggable) {
19643                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19644                    final ProcessRecord myProc = proc;
19645                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19646                    mMemWatchDumpProcName = proc.processName;
19647                    mMemWatchDumpFile = heapdumpFile.toString();
19648                    mMemWatchDumpPid = proc.pid;
19649                    mMemWatchDumpUid = proc.uid;
19650                    BackgroundThread.getHandler().post(new Runnable() {
19651                        @Override
19652                        public void run() {
19653                            revokeUriPermission(ActivityThread.currentActivityThread()
19654                                            .getApplicationThread(),
19655                                    DumpHeapActivity.JAVA_URI,
19656                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19657                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19658                                    UserHandle.myUserId());
19659                            ParcelFileDescriptor fd = null;
19660                            try {
19661                                heapdumpFile.delete();
19662                                fd = ParcelFileDescriptor.open(heapdumpFile,
19663                                        ParcelFileDescriptor.MODE_CREATE |
19664                                                ParcelFileDescriptor.MODE_TRUNCATE |
19665                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19666                                                ParcelFileDescriptor.MODE_APPEND);
19667                                IApplicationThread thread = myProc.thread;
19668                                if (thread != null) {
19669                                    try {
19670                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19671                                                "Requesting dump heap from "
19672                                                + myProc + " to " + heapdumpFile);
19673                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19674                                    } catch (RemoteException e) {
19675                                    }
19676                                }
19677                            } catch (FileNotFoundException e) {
19678                                e.printStackTrace();
19679                            } finally {
19680                                if (fd != null) {
19681                                    try {
19682                                        fd.close();
19683                                    } catch (IOException e) {
19684                                    }
19685                                }
19686                            }
19687                        }
19688                    });
19689                } else {
19690                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19691                            + ", but debugging not enabled");
19692                }
19693            }
19694        }
19695    }
19696
19697    /**
19698     * Schedule PSS collection of a process.
19699     */
19700    void requestPssLocked(ProcessRecord proc, int procState) {
19701        if (mPendingPssProcesses.contains(proc)) {
19702            return;
19703        }
19704        if (mPendingPssProcesses.size() == 0) {
19705            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19706        }
19707        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19708        proc.pssProcState = procState;
19709        mPendingPssProcesses.add(proc);
19710    }
19711
19712    /**
19713     * Schedule PSS collection of all processes.
19714     */
19715    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19716        if (!always) {
19717            if (now < (mLastFullPssTime +
19718                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19719                return;
19720            }
19721        }
19722        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19723        mLastFullPssTime = now;
19724        mFullPssPending = true;
19725        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19726        mPendingPssProcesses.clear();
19727        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19728            ProcessRecord app = mLruProcesses.get(i);
19729            if (app.thread == null
19730                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19731                continue;
19732            }
19733            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19734                app.pssProcState = app.setProcState;
19735                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19736                        mTestPssMode, isSleeping(), now);
19737                mPendingPssProcesses.add(app);
19738            }
19739        }
19740        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19741    }
19742
19743    public void setTestPssMode(boolean enabled) {
19744        synchronized (this) {
19745            mTestPssMode = enabled;
19746            if (enabled) {
19747                // Whenever we enable the mode, we want to take a snapshot all of current
19748                // process mem use.
19749                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19750            }
19751        }
19752    }
19753
19754    /**
19755     * Ask a given process to GC right now.
19756     */
19757    final void performAppGcLocked(ProcessRecord app) {
19758        try {
19759            app.lastRequestedGc = SystemClock.uptimeMillis();
19760            if (app.thread != null) {
19761                if (app.reportLowMemory) {
19762                    app.reportLowMemory = false;
19763                    app.thread.scheduleLowMemory();
19764                } else {
19765                    app.thread.processInBackground();
19766                }
19767            }
19768        } catch (Exception e) {
19769            // whatever.
19770        }
19771    }
19772
19773    /**
19774     * Returns true if things are idle enough to perform GCs.
19775     */
19776    private final boolean canGcNowLocked() {
19777        boolean processingBroadcasts = false;
19778        for (BroadcastQueue q : mBroadcastQueues) {
19779            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19780                processingBroadcasts = true;
19781            }
19782        }
19783        return !processingBroadcasts
19784                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19785    }
19786
19787    /**
19788     * Perform GCs on all processes that are waiting for it, but only
19789     * if things are idle.
19790     */
19791    final void performAppGcsLocked() {
19792        final int N = mProcessesToGc.size();
19793        if (N <= 0) {
19794            return;
19795        }
19796        if (canGcNowLocked()) {
19797            while (mProcessesToGc.size() > 0) {
19798                ProcessRecord proc = mProcessesToGc.remove(0);
19799                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19800                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19801                            <= SystemClock.uptimeMillis()) {
19802                        // To avoid spamming the system, we will GC processes one
19803                        // at a time, waiting a few seconds between each.
19804                        performAppGcLocked(proc);
19805                        scheduleAppGcsLocked();
19806                        return;
19807                    } else {
19808                        // It hasn't been long enough since we last GCed this
19809                        // process...  put it in the list to wait for its time.
19810                        addProcessToGcListLocked(proc);
19811                        break;
19812                    }
19813                }
19814            }
19815
19816            scheduleAppGcsLocked();
19817        }
19818    }
19819
19820    /**
19821     * If all looks good, perform GCs on all processes waiting for them.
19822     */
19823    final void performAppGcsIfAppropriateLocked() {
19824        if (canGcNowLocked()) {
19825            performAppGcsLocked();
19826            return;
19827        }
19828        // Still not idle, wait some more.
19829        scheduleAppGcsLocked();
19830    }
19831
19832    /**
19833     * Schedule the execution of all pending app GCs.
19834     */
19835    final void scheduleAppGcsLocked() {
19836        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19837
19838        if (mProcessesToGc.size() > 0) {
19839            // Schedule a GC for the time to the next process.
19840            ProcessRecord proc = mProcessesToGc.get(0);
19841            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19842
19843            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19844            long now = SystemClock.uptimeMillis();
19845            if (when < (now+GC_TIMEOUT)) {
19846                when = now + GC_TIMEOUT;
19847            }
19848            mHandler.sendMessageAtTime(msg, when);
19849        }
19850    }
19851
19852    /**
19853     * Add a process to the array of processes waiting to be GCed.  Keeps the
19854     * list in sorted order by the last GC time.  The process can't already be
19855     * on the list.
19856     */
19857    final void addProcessToGcListLocked(ProcessRecord proc) {
19858        boolean added = false;
19859        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19860            if (mProcessesToGc.get(i).lastRequestedGc <
19861                    proc.lastRequestedGc) {
19862                added = true;
19863                mProcessesToGc.add(i+1, proc);
19864                break;
19865            }
19866        }
19867        if (!added) {
19868            mProcessesToGc.add(0, proc);
19869        }
19870    }
19871
19872    /**
19873     * Set up to ask a process to GC itself.  This will either do it
19874     * immediately, or put it on the list of processes to gc the next
19875     * time things are idle.
19876     */
19877    final void scheduleAppGcLocked(ProcessRecord app) {
19878        long now = SystemClock.uptimeMillis();
19879        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19880            return;
19881        }
19882        if (!mProcessesToGc.contains(app)) {
19883            addProcessToGcListLocked(app);
19884            scheduleAppGcsLocked();
19885        }
19886    }
19887
19888    final void checkExcessivePowerUsageLocked(boolean doKills) {
19889        updateCpuStatsNow();
19890
19891        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19892        boolean doWakeKills = doKills;
19893        boolean doCpuKills = doKills;
19894        if (mLastPowerCheckRealtime == 0) {
19895            doWakeKills = false;
19896        }
19897        if (mLastPowerCheckUptime == 0) {
19898            doCpuKills = false;
19899        }
19900        if (stats.isScreenOn()) {
19901            doWakeKills = false;
19902        }
19903        final long curRealtime = SystemClock.elapsedRealtime();
19904        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19905        final long curUptime = SystemClock.uptimeMillis();
19906        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19907        mLastPowerCheckRealtime = curRealtime;
19908        mLastPowerCheckUptime = curUptime;
19909        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19910            doWakeKills = false;
19911        }
19912        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19913            doCpuKills = false;
19914        }
19915        int i = mLruProcesses.size();
19916        while (i > 0) {
19917            i--;
19918            ProcessRecord app = mLruProcesses.get(i);
19919            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19920                long wtime;
19921                synchronized (stats) {
19922                    wtime = stats.getProcessWakeTime(app.info.uid,
19923                            app.pid, curRealtime);
19924                }
19925                long wtimeUsed = wtime - app.lastWakeTime;
19926                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19927                if (DEBUG_POWER) {
19928                    StringBuilder sb = new StringBuilder(128);
19929                    sb.append("Wake for ");
19930                    app.toShortString(sb);
19931                    sb.append(": over ");
19932                    TimeUtils.formatDuration(realtimeSince, sb);
19933                    sb.append(" used ");
19934                    TimeUtils.formatDuration(wtimeUsed, sb);
19935                    sb.append(" (");
19936                    sb.append((wtimeUsed*100)/realtimeSince);
19937                    sb.append("%)");
19938                    Slog.i(TAG_POWER, sb.toString());
19939                    sb.setLength(0);
19940                    sb.append("CPU for ");
19941                    app.toShortString(sb);
19942                    sb.append(": over ");
19943                    TimeUtils.formatDuration(uptimeSince, sb);
19944                    sb.append(" used ");
19945                    TimeUtils.formatDuration(cputimeUsed, sb);
19946                    sb.append(" (");
19947                    sb.append((cputimeUsed*100)/uptimeSince);
19948                    sb.append("%)");
19949                    Slog.i(TAG_POWER, sb.toString());
19950                }
19951                // If a process has held a wake lock for more
19952                // than 50% of the time during this period,
19953                // that sounds bad.  Kill!
19954                if (doWakeKills && realtimeSince > 0
19955                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19956                    synchronized (stats) {
19957                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19958                                realtimeSince, wtimeUsed);
19959                    }
19960                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19961                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19962                } else if (doCpuKills && uptimeSince > 0
19963                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19964                    synchronized (stats) {
19965                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19966                                uptimeSince, cputimeUsed);
19967                    }
19968                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19969                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19970                } else {
19971                    app.lastWakeTime = wtime;
19972                    app.lastCpuTime = app.curCpuTime;
19973                }
19974            }
19975        }
19976    }
19977
19978    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19979            long nowElapsed) {
19980        boolean success = true;
19981
19982        if (app.curRawAdj != app.setRawAdj) {
19983            app.setRawAdj = app.curRawAdj;
19984        }
19985
19986        int changes = 0;
19987
19988        if (app.curAdj != app.setAdj) {
19989            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19990            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19991                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19992                    + app.adjType);
19993            app.setAdj = app.curAdj;
19994        }
19995
19996        if (app.setSchedGroup != app.curSchedGroup) {
19997            app.setSchedGroup = app.curSchedGroup;
19998            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19999                    "Setting sched group of " + app.processName
20000                    + " to " + app.curSchedGroup);
20001            if (app.waitingToKill != null && app.curReceiver == null
20002                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20003                app.kill(app.waitingToKill, true);
20004                success = false;
20005            } else {
20006                int processGroup;
20007                switch (app.curSchedGroup) {
20008                    case ProcessList.SCHED_GROUP_BACKGROUND:
20009                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20010                        break;
20011                    case ProcessList.SCHED_GROUP_TOP_APP:
20012                        processGroup = Process.THREAD_GROUP_TOP_APP;
20013                        break;
20014                    default:
20015                        processGroup = Process.THREAD_GROUP_DEFAULT;
20016                        break;
20017                }
20018                if (true) {
20019                    long oldId = Binder.clearCallingIdentity();
20020                    try {
20021                        Process.setProcessGroup(app.pid, processGroup);
20022                    } catch (Exception e) {
20023                        Slog.w(TAG, "Failed setting process group of " + app.pid
20024                                + " to " + app.curSchedGroup);
20025                        e.printStackTrace();
20026                    } finally {
20027                        Binder.restoreCallingIdentity(oldId);
20028                    }
20029                } else {
20030                    if (app.thread != null) {
20031                        try {
20032                            app.thread.setSchedulingGroup(processGroup);
20033                        } catch (RemoteException e) {
20034                        }
20035                    }
20036                }
20037            }
20038        }
20039        if (app.repForegroundActivities != app.foregroundActivities) {
20040            app.repForegroundActivities = app.foregroundActivities;
20041            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20042        }
20043        if (app.repProcState != app.curProcState) {
20044            app.repProcState = app.curProcState;
20045            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20046            if (app.thread != null) {
20047                try {
20048                    if (false) {
20049                        //RuntimeException h = new RuntimeException("here");
20050                        Slog.i(TAG, "Sending new process state " + app.repProcState
20051                                + " to " + app /*, h*/);
20052                    }
20053                    app.thread.setProcessState(app.repProcState);
20054                } catch (RemoteException e) {
20055                }
20056            }
20057        }
20058        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20059                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20060            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20061                // Experimental code to more aggressively collect pss while
20062                // running test...  the problem is that this tends to collect
20063                // the data right when a process is transitioning between process
20064                // states, which well tend to give noisy data.
20065                long start = SystemClock.uptimeMillis();
20066                long pss = Debug.getPss(app.pid, mTmpLong, null);
20067                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20068                mPendingPssProcesses.remove(app);
20069                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20070                        + " to " + app.curProcState + ": "
20071                        + (SystemClock.uptimeMillis()-start) + "ms");
20072            }
20073            app.lastStateTime = now;
20074            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20075                    mTestPssMode, isSleeping(), now);
20076            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20077                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20078                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20079                    + (app.nextPssTime-now) + ": " + app);
20080        } else {
20081            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20082                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20083                    mTestPssMode)))) {
20084                requestPssLocked(app, app.setProcState);
20085                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20086                        mTestPssMode, isSleeping(), now);
20087            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20088                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20089        }
20090        if (app.setProcState != app.curProcState) {
20091            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20092                    "Proc state change of " + app.processName
20093                            + " to " + app.curProcState);
20094            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20095            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20096            if (setImportant && !curImportant) {
20097                // This app is no longer something we consider important enough to allow to
20098                // use arbitrary amounts of battery power.  Note
20099                // its current wake lock time to later know to kill it if
20100                // it is not behaving well.
20101                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20102                synchronized (stats) {
20103                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20104                            app.pid, nowElapsed);
20105                }
20106                app.lastCpuTime = app.curCpuTime;
20107
20108            }
20109            // Inform UsageStats of important process state change
20110            // Must be called before updating setProcState
20111            maybeUpdateUsageStatsLocked(app, nowElapsed);
20112
20113            app.setProcState = app.curProcState;
20114            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20115                app.notCachedSinceIdle = false;
20116            }
20117            if (!doingAll) {
20118                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20119            } else {
20120                app.procStateChanged = true;
20121            }
20122        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20123                > USAGE_STATS_INTERACTION_INTERVAL) {
20124            // For apps that sit around for a long time in the interactive state, we need
20125            // to report this at least once a day so they don't go idle.
20126            maybeUpdateUsageStatsLocked(app, nowElapsed);
20127        }
20128
20129        if (changes != 0) {
20130            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20131                    "Changes in " + app + ": " + changes);
20132            int i = mPendingProcessChanges.size()-1;
20133            ProcessChangeItem item = null;
20134            while (i >= 0) {
20135                item = mPendingProcessChanges.get(i);
20136                if (item.pid == app.pid) {
20137                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20138                            "Re-using existing item: " + item);
20139                    break;
20140                }
20141                i--;
20142            }
20143            if (i < 0) {
20144                // No existing item in pending changes; need a new one.
20145                final int NA = mAvailProcessChanges.size();
20146                if (NA > 0) {
20147                    item = mAvailProcessChanges.remove(NA-1);
20148                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20149                            "Retrieving available item: " + item);
20150                } else {
20151                    item = new ProcessChangeItem();
20152                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20153                            "Allocating new item: " + item);
20154                }
20155                item.changes = 0;
20156                item.pid = app.pid;
20157                item.uid = app.info.uid;
20158                if (mPendingProcessChanges.size() == 0) {
20159                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20160                            "*** Enqueueing dispatch processes changed!");
20161                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20162                }
20163                mPendingProcessChanges.add(item);
20164            }
20165            item.changes |= changes;
20166            item.processState = app.repProcState;
20167            item.foregroundActivities = app.repForegroundActivities;
20168            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20169                    "Item " + Integer.toHexString(System.identityHashCode(item))
20170                    + " " + app.toShortString() + ": changes=" + item.changes
20171                    + " procState=" + item.processState
20172                    + " foreground=" + item.foregroundActivities
20173                    + " type=" + app.adjType + " source=" + app.adjSource
20174                    + " target=" + app.adjTarget);
20175        }
20176
20177        return success;
20178    }
20179
20180    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20181        final UidRecord.ChangeItem pendingChange;
20182        if (uidRec == null || uidRec.pendingChange == null) {
20183            if (mPendingUidChanges.size() == 0) {
20184                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20185                        "*** Enqueueing dispatch uid changed!");
20186                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20187            }
20188            final int NA = mAvailUidChanges.size();
20189            if (NA > 0) {
20190                pendingChange = mAvailUidChanges.remove(NA-1);
20191                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20192                        "Retrieving available item: " + pendingChange);
20193            } else {
20194                pendingChange = new UidRecord.ChangeItem();
20195                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20196                        "Allocating new item: " + pendingChange);
20197            }
20198            if (uidRec != null) {
20199                uidRec.pendingChange = pendingChange;
20200                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20201                    // If this uid is going away, and we haven't yet reported it is gone,
20202                    // then do so now.
20203                    change = UidRecord.CHANGE_GONE_IDLE;
20204                }
20205            } else if (uid < 0) {
20206                throw new IllegalArgumentException("No UidRecord or uid");
20207            }
20208            pendingChange.uidRecord = uidRec;
20209            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20210            mPendingUidChanges.add(pendingChange);
20211        } else {
20212            pendingChange = uidRec.pendingChange;
20213            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20214                change = UidRecord.CHANGE_GONE_IDLE;
20215            }
20216        }
20217        pendingChange.change = change;
20218        pendingChange.processState = uidRec != null
20219                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20220    }
20221
20222    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20223            String authority) {
20224        if (app == null) return;
20225        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20226            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20227            if (userState == null) return;
20228            final long now = SystemClock.elapsedRealtime();
20229            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20230            if (lastReported == null || lastReported < now - 60 * 1000L) {
20231                mUsageStatsService.reportContentProviderUsage(
20232                        authority, providerPkgName, app.userId);
20233                userState.mProviderLastReportedFg.put(authority, now);
20234            }
20235        }
20236    }
20237
20238    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20239        if (DEBUG_USAGE_STATS) {
20240            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20241                    + "] state changes: old = " + app.setProcState + ", new = "
20242                    + app.curProcState);
20243        }
20244        if (mUsageStatsService == null) {
20245            return;
20246        }
20247        boolean isInteraction;
20248        // To avoid some abuse patterns, we are going to be careful about what we consider
20249        // to be an app interaction.  Being the top activity doesn't count while the display
20250        // is sleeping, nor do short foreground services.
20251        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20252            isInteraction = true;
20253            app.fgInteractionTime = 0;
20254        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20255            if (app.fgInteractionTime == 0) {
20256                app.fgInteractionTime = nowElapsed;
20257                isInteraction = false;
20258            } else {
20259                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20260            }
20261        } else {
20262            isInteraction = app.curProcState
20263                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20264            app.fgInteractionTime = 0;
20265        }
20266        if (isInteraction && (!app.reportedInteraction
20267                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20268            app.interactionEventTime = nowElapsed;
20269            String[] packages = app.getPackageList();
20270            if (packages != null) {
20271                for (int i = 0; i < packages.length; i++) {
20272                    mUsageStatsService.reportEvent(packages[i], app.userId,
20273                            UsageEvents.Event.SYSTEM_INTERACTION);
20274                }
20275            }
20276        }
20277        app.reportedInteraction = isInteraction;
20278        if (!isInteraction) {
20279            app.interactionEventTime = 0;
20280        }
20281    }
20282
20283    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20284        if (proc.thread != null) {
20285            if (proc.baseProcessTracker != null) {
20286                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20287            }
20288        }
20289    }
20290
20291    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20292            ProcessRecord TOP_APP, boolean doingAll, long now) {
20293        if (app.thread == null) {
20294            return false;
20295        }
20296
20297        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20298
20299        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20300    }
20301
20302    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20303            boolean oomAdj) {
20304        if (isForeground != proc.foregroundServices) {
20305            proc.foregroundServices = isForeground;
20306            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20307                    proc.info.uid);
20308            if (isForeground) {
20309                if (curProcs == null) {
20310                    curProcs = new ArrayList<ProcessRecord>();
20311                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20312                }
20313                if (!curProcs.contains(proc)) {
20314                    curProcs.add(proc);
20315                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20316                            proc.info.packageName, proc.info.uid);
20317                }
20318            } else {
20319                if (curProcs != null) {
20320                    if (curProcs.remove(proc)) {
20321                        mBatteryStatsService.noteEvent(
20322                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20323                                proc.info.packageName, proc.info.uid);
20324                        if (curProcs.size() <= 0) {
20325                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20326                        }
20327                    }
20328                }
20329            }
20330            if (oomAdj) {
20331                updateOomAdjLocked();
20332            }
20333        }
20334    }
20335
20336    private final ActivityRecord resumedAppLocked() {
20337        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20338        String pkg;
20339        int uid;
20340        if (act != null) {
20341            pkg = act.packageName;
20342            uid = act.info.applicationInfo.uid;
20343        } else {
20344            pkg = null;
20345            uid = -1;
20346        }
20347        // Has the UID or resumed package name changed?
20348        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20349                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20350            if (mCurResumedPackage != null) {
20351                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20352                        mCurResumedPackage, mCurResumedUid);
20353            }
20354            mCurResumedPackage = pkg;
20355            mCurResumedUid = uid;
20356            if (mCurResumedPackage != null) {
20357                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20358                        mCurResumedPackage, mCurResumedUid);
20359            }
20360        }
20361        return act;
20362    }
20363
20364    final boolean updateOomAdjLocked(ProcessRecord app) {
20365        final ActivityRecord TOP_ACT = resumedAppLocked();
20366        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20367        final boolean wasCached = app.cached;
20368
20369        mAdjSeq++;
20370
20371        // This is the desired cached adjusment we want to tell it to use.
20372        // If our app is currently cached, we know it, and that is it.  Otherwise,
20373        // we don't know it yet, and it needs to now be cached we will then
20374        // need to do a complete oom adj.
20375        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20376                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20377        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20378                SystemClock.uptimeMillis());
20379        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20380            // Changed to/from cached state, so apps after it in the LRU
20381            // list may also be changed.
20382            updateOomAdjLocked();
20383        }
20384        return success;
20385    }
20386
20387    final void updateOomAdjLocked() {
20388        final ActivityRecord TOP_ACT = resumedAppLocked();
20389        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20390        final long now = SystemClock.uptimeMillis();
20391        final long nowElapsed = SystemClock.elapsedRealtime();
20392        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20393        final int N = mLruProcesses.size();
20394
20395        if (false) {
20396            RuntimeException e = new RuntimeException();
20397            e.fillInStackTrace();
20398            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20399        }
20400
20401        // Reset state in all uid records.
20402        for (int i=mActiveUids.size()-1; i>=0; i--) {
20403            final UidRecord uidRec = mActiveUids.valueAt(i);
20404            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20405                    "Starting update of " + uidRec);
20406            uidRec.reset();
20407        }
20408
20409        mStackSupervisor.rankTaskLayersIfNeeded();
20410
20411        mAdjSeq++;
20412        mNewNumServiceProcs = 0;
20413        mNewNumAServiceProcs = 0;
20414
20415        final int emptyProcessLimit;
20416        final int cachedProcessLimit;
20417        if (mProcessLimit <= 0) {
20418            emptyProcessLimit = cachedProcessLimit = 0;
20419        } else if (mProcessLimit == 1) {
20420            emptyProcessLimit = 1;
20421            cachedProcessLimit = 0;
20422        } else {
20423            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20424            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20425        }
20426
20427        // Let's determine how many processes we have running vs.
20428        // how many slots we have for background processes; we may want
20429        // to put multiple processes in a slot of there are enough of
20430        // them.
20431        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20432                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20433        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20434        if (numEmptyProcs > cachedProcessLimit) {
20435            // If there are more empty processes than our limit on cached
20436            // processes, then use the cached process limit for the factor.
20437            // This ensures that the really old empty processes get pushed
20438            // down to the bottom, so if we are running low on memory we will
20439            // have a better chance at keeping around more cached processes
20440            // instead of a gazillion empty processes.
20441            numEmptyProcs = cachedProcessLimit;
20442        }
20443        int emptyFactor = numEmptyProcs/numSlots;
20444        if (emptyFactor < 1) emptyFactor = 1;
20445        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20446        if (cachedFactor < 1) cachedFactor = 1;
20447        int stepCached = 0;
20448        int stepEmpty = 0;
20449        int numCached = 0;
20450        int numEmpty = 0;
20451        int numTrimming = 0;
20452
20453        mNumNonCachedProcs = 0;
20454        mNumCachedHiddenProcs = 0;
20455
20456        // First update the OOM adjustment for each of the
20457        // application processes based on their current state.
20458        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20459        int nextCachedAdj = curCachedAdj+1;
20460        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20461        int nextEmptyAdj = curEmptyAdj+2;
20462        for (int i=N-1; i>=0; i--) {
20463            ProcessRecord app = mLruProcesses.get(i);
20464            if (!app.killedByAm && app.thread != null) {
20465                app.procStateChanged = false;
20466                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20467
20468                // If we haven't yet assigned the final cached adj
20469                // to the process, do that now.
20470                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20471                    switch (app.curProcState) {
20472                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20473                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20474                            // This process is a cached process holding activities...
20475                            // assign it the next cached value for that type, and then
20476                            // step that cached level.
20477                            app.curRawAdj = curCachedAdj;
20478                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20479                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20480                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20481                                    + ")");
20482                            if (curCachedAdj != nextCachedAdj) {
20483                                stepCached++;
20484                                if (stepCached >= cachedFactor) {
20485                                    stepCached = 0;
20486                                    curCachedAdj = nextCachedAdj;
20487                                    nextCachedAdj += 2;
20488                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20489                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20490                                    }
20491                                }
20492                            }
20493                            break;
20494                        default:
20495                            // For everything else, assign next empty cached process
20496                            // level and bump that up.  Note that this means that
20497                            // long-running services that have dropped down to the
20498                            // cached level will be treated as empty (since their process
20499                            // state is still as a service), which is what we want.
20500                            app.curRawAdj = curEmptyAdj;
20501                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20502                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20503                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20504                                    + ")");
20505                            if (curEmptyAdj != nextEmptyAdj) {
20506                                stepEmpty++;
20507                                if (stepEmpty >= emptyFactor) {
20508                                    stepEmpty = 0;
20509                                    curEmptyAdj = nextEmptyAdj;
20510                                    nextEmptyAdj += 2;
20511                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20512                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20513                                    }
20514                                }
20515                            }
20516                            break;
20517                    }
20518                }
20519
20520                applyOomAdjLocked(app, true, now, nowElapsed);
20521
20522                // Count the number of process types.
20523                switch (app.curProcState) {
20524                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20525                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20526                        mNumCachedHiddenProcs++;
20527                        numCached++;
20528                        if (numCached > cachedProcessLimit) {
20529                            app.kill("cached #" + numCached, true);
20530                        }
20531                        break;
20532                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20533                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20534                                && app.lastActivityTime < oldTime) {
20535                            app.kill("empty for "
20536                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20537                                    / 1000) + "s", true);
20538                        } else {
20539                            numEmpty++;
20540                            if (numEmpty > emptyProcessLimit) {
20541                                app.kill("empty #" + numEmpty, true);
20542                            }
20543                        }
20544                        break;
20545                    default:
20546                        mNumNonCachedProcs++;
20547                        break;
20548                }
20549
20550                if (app.isolated && app.services.size() <= 0) {
20551                    // If this is an isolated process, and there are no
20552                    // services running in it, then the process is no longer
20553                    // needed.  We agressively kill these because we can by
20554                    // definition not re-use the same process again, and it is
20555                    // good to avoid having whatever code was running in them
20556                    // left sitting around after no longer needed.
20557                    app.kill("isolated not needed", true);
20558                } else {
20559                    // Keeping this process, update its uid.
20560                    final UidRecord uidRec = app.uidRecord;
20561                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20562                        uidRec.curProcState = app.curProcState;
20563                    }
20564                }
20565
20566                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20567                        && !app.killedByAm) {
20568                    numTrimming++;
20569                }
20570            }
20571        }
20572
20573        mNumServiceProcs = mNewNumServiceProcs;
20574
20575        // Now determine the memory trimming level of background processes.
20576        // Unfortunately we need to start at the back of the list to do this
20577        // properly.  We only do this if the number of background apps we
20578        // are managing to keep around is less than half the maximum we desire;
20579        // if we are keeping a good number around, we'll let them use whatever
20580        // memory they want.
20581        final int numCachedAndEmpty = numCached + numEmpty;
20582        int memFactor;
20583        if (numCached <= ProcessList.TRIM_CACHED_APPS
20584                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20585            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20586                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20587            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20588                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20589            } else {
20590                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20591            }
20592        } else {
20593            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20594        }
20595        // We always allow the memory level to go up (better).  We only allow it to go
20596        // down if we are in a state where that is allowed, *and* the total number of processes
20597        // has gone down since last time.
20598        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20599                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20600                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20601        if (memFactor > mLastMemoryLevel) {
20602            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20603                memFactor = mLastMemoryLevel;
20604                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20605            }
20606        }
20607        if (memFactor != mLastMemoryLevel) {
20608            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20609        }
20610        mLastMemoryLevel = memFactor;
20611        mLastNumProcesses = mLruProcesses.size();
20612        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20613        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20614        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20615            if (mLowRamStartTime == 0) {
20616                mLowRamStartTime = now;
20617            }
20618            int step = 0;
20619            int fgTrimLevel;
20620            switch (memFactor) {
20621                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20622                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20623                    break;
20624                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20625                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20626                    break;
20627                default:
20628                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20629                    break;
20630            }
20631            int factor = numTrimming/3;
20632            int minFactor = 2;
20633            if (mHomeProcess != null) minFactor++;
20634            if (mPreviousProcess != null) minFactor++;
20635            if (factor < minFactor) factor = minFactor;
20636            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20637            for (int i=N-1; i>=0; i--) {
20638                ProcessRecord app = mLruProcesses.get(i);
20639                if (allChanged || app.procStateChanged) {
20640                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20641                    app.procStateChanged = false;
20642                }
20643                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20644                        && !app.killedByAm) {
20645                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20646                        try {
20647                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20648                                    "Trimming memory of " + app.processName + " to " + curLevel);
20649                            app.thread.scheduleTrimMemory(curLevel);
20650                        } catch (RemoteException e) {
20651                        }
20652                        if (false) {
20653                            // For now we won't do this; our memory trimming seems
20654                            // to be good enough at this point that destroying
20655                            // activities causes more harm than good.
20656                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20657                                    && app != mHomeProcess && app != mPreviousProcess) {
20658                                // Need to do this on its own message because the stack may not
20659                                // be in a consistent state at this point.
20660                                // For these apps we will also finish their activities
20661                                // to help them free memory.
20662                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20663                            }
20664                        }
20665                    }
20666                    app.trimMemoryLevel = curLevel;
20667                    step++;
20668                    if (step >= factor) {
20669                        step = 0;
20670                        switch (curLevel) {
20671                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20672                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20673                                break;
20674                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20675                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20676                                break;
20677                        }
20678                    }
20679                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20680                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20681                            && app.thread != null) {
20682                        try {
20683                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20684                                    "Trimming memory of heavy-weight " + app.processName
20685                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20686                            app.thread.scheduleTrimMemory(
20687                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20688                        } catch (RemoteException e) {
20689                        }
20690                    }
20691                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20692                } else {
20693                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20694                            || app.systemNoUi) && app.pendingUiClean) {
20695                        // If this application is now in the background and it
20696                        // had done UI, then give it the special trim level to
20697                        // have it free UI resources.
20698                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20699                        if (app.trimMemoryLevel < level && app.thread != null) {
20700                            try {
20701                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20702                                        "Trimming memory of bg-ui " + app.processName
20703                                        + " to " + level);
20704                                app.thread.scheduleTrimMemory(level);
20705                            } catch (RemoteException e) {
20706                            }
20707                        }
20708                        app.pendingUiClean = false;
20709                    }
20710                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20711                        try {
20712                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20713                                    "Trimming memory of fg " + app.processName
20714                                    + " to " + fgTrimLevel);
20715                            app.thread.scheduleTrimMemory(fgTrimLevel);
20716                        } catch (RemoteException e) {
20717                        }
20718                    }
20719                    app.trimMemoryLevel = fgTrimLevel;
20720                }
20721            }
20722        } else {
20723            if (mLowRamStartTime != 0) {
20724                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20725                mLowRamStartTime = 0;
20726            }
20727            for (int i=N-1; i>=0; i--) {
20728                ProcessRecord app = mLruProcesses.get(i);
20729                if (allChanged || app.procStateChanged) {
20730                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20731                    app.procStateChanged = false;
20732                }
20733                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20734                        || app.systemNoUi) && app.pendingUiClean) {
20735                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20736                            && app.thread != null) {
20737                        try {
20738                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20739                                    "Trimming memory of ui hidden " + app.processName
20740                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20741                            app.thread.scheduleTrimMemory(
20742                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20743                        } catch (RemoteException e) {
20744                        }
20745                    }
20746                    app.pendingUiClean = false;
20747                }
20748                app.trimMemoryLevel = 0;
20749            }
20750        }
20751
20752        if (mAlwaysFinishActivities) {
20753            // Need to do this on its own message because the stack may not
20754            // be in a consistent state at this point.
20755            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20756        }
20757
20758        if (allChanged) {
20759            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20760        }
20761
20762        // Update from any uid changes.
20763        for (int i=mActiveUids.size()-1; i>=0; i--) {
20764            final UidRecord uidRec = mActiveUids.valueAt(i);
20765            int uidChange = UidRecord.CHANGE_PROCSTATE;
20766            if (uidRec.setProcState != uidRec.curProcState) {
20767                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20768                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20769                        + " to " + uidRec.curProcState);
20770                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20771                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20772                        uidRec.lastBackgroundTime = nowElapsed;
20773                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20774                            // Note: the background settle time is in elapsed realtime, while
20775                            // the handler time base is uptime.  All this means is that we may
20776                            // stop background uids later than we had intended, but that only
20777                            // happens because the device was sleeping so we are okay anyway.
20778                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20779                        }
20780                    }
20781                } else {
20782                    if (uidRec.idle) {
20783                        uidChange = UidRecord.CHANGE_ACTIVE;
20784                        uidRec.idle = false;
20785                    }
20786                    uidRec.lastBackgroundTime = 0;
20787                }
20788                uidRec.setProcState = uidRec.curProcState;
20789                enqueueUidChangeLocked(uidRec, -1, uidChange);
20790                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20791            }
20792        }
20793
20794        if (mProcessStats.shouldWriteNowLocked(now)) {
20795            mHandler.post(new Runnable() {
20796                @Override public void run() {
20797                    synchronized (ActivityManagerService.this) {
20798                        mProcessStats.writeStateAsyncLocked();
20799                    }
20800                }
20801            });
20802        }
20803
20804        if (DEBUG_OOM_ADJ) {
20805            final long duration = SystemClock.uptimeMillis() - now;
20806            if (false) {
20807                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20808                        new RuntimeException("here").fillInStackTrace());
20809            } else {
20810                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20811            }
20812        }
20813    }
20814
20815    final void idleUids() {
20816        synchronized (this) {
20817            final long nowElapsed = SystemClock.elapsedRealtime();
20818            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20819            long nextTime = 0;
20820            for (int i=mActiveUids.size()-1; i>=0; i--) {
20821                final UidRecord uidRec = mActiveUids.valueAt(i);
20822                final long bgTime = uidRec.lastBackgroundTime;
20823                if (bgTime > 0 && !uidRec.idle) {
20824                    if (bgTime <= maxBgTime) {
20825                        uidRec.idle = true;
20826                        doStopUidLocked(uidRec.uid, uidRec);
20827                    } else {
20828                        if (nextTime == 0 || nextTime > bgTime) {
20829                            nextTime = bgTime;
20830                        }
20831                    }
20832                }
20833            }
20834            if (nextTime > 0) {
20835                mHandler.removeMessages(IDLE_UIDS_MSG);
20836                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20837                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20838            }
20839        }
20840    }
20841
20842    final void runInBackgroundDisabled(int uid) {
20843        synchronized (this) {
20844            UidRecord uidRec = mActiveUids.get(uid);
20845            if (uidRec != null) {
20846                // This uid is actually running...  should it be considered background now?
20847                if (uidRec.idle) {
20848                    doStopUidLocked(uidRec.uid, uidRec);
20849                }
20850            } else {
20851                // This uid isn't actually running...  still send a report about it being "stopped".
20852                doStopUidLocked(uid, null);
20853            }
20854        }
20855    }
20856
20857    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20858        mServices.stopInBackgroundLocked(uid);
20859        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20860    }
20861
20862    final void trimApplications() {
20863        synchronized (this) {
20864            int i;
20865
20866            // First remove any unused application processes whose package
20867            // has been removed.
20868            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20869                final ProcessRecord app = mRemovedProcesses.get(i);
20870                if (app.activities.size() == 0
20871                        && app.curReceiver == null && app.services.size() == 0) {
20872                    Slog.i(
20873                        TAG, "Exiting empty application process "
20874                        + app.toShortString() + " ("
20875                        + (app.thread != null ? app.thread.asBinder() : null)
20876                        + ")\n");
20877                    if (app.pid > 0 && app.pid != MY_PID) {
20878                        app.kill("empty", false);
20879                    } else {
20880                        try {
20881                            app.thread.scheduleExit();
20882                        } catch (Exception e) {
20883                            // Ignore exceptions.
20884                        }
20885                    }
20886                    cleanUpApplicationRecordLocked(app, false, true, -1);
20887                    mRemovedProcesses.remove(i);
20888
20889                    if (app.persistent) {
20890                        addAppLocked(app.info, false, null /* ABI override */);
20891                    }
20892                }
20893            }
20894
20895            // Now update the oom adj for all processes.
20896            updateOomAdjLocked();
20897        }
20898    }
20899
20900    /** This method sends the specified signal to each of the persistent apps */
20901    public void signalPersistentProcesses(int sig) throws RemoteException {
20902        if (sig != Process.SIGNAL_USR1) {
20903            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20904        }
20905
20906        synchronized (this) {
20907            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20908                    != PackageManager.PERMISSION_GRANTED) {
20909                throw new SecurityException("Requires permission "
20910                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20911            }
20912
20913            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20914                ProcessRecord r = mLruProcesses.get(i);
20915                if (r.thread != null && r.persistent) {
20916                    Process.sendSignal(r.pid, sig);
20917                }
20918            }
20919        }
20920    }
20921
20922    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20923        if (proc == null || proc == mProfileProc) {
20924            proc = mProfileProc;
20925            profileType = mProfileType;
20926            clearProfilerLocked();
20927        }
20928        if (proc == null) {
20929            return;
20930        }
20931        try {
20932            proc.thread.profilerControl(false, null, profileType);
20933        } catch (RemoteException e) {
20934            throw new IllegalStateException("Process disappeared");
20935        }
20936    }
20937
20938    private void clearProfilerLocked() {
20939        if (mProfileFd != null) {
20940            try {
20941                mProfileFd.close();
20942            } catch (IOException e) {
20943            }
20944        }
20945        mProfileApp = null;
20946        mProfileProc = null;
20947        mProfileFile = null;
20948        mProfileType = 0;
20949        mAutoStopProfiler = false;
20950        mSamplingInterval = 0;
20951    }
20952
20953    public boolean profileControl(String process, int userId, boolean start,
20954            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20955
20956        try {
20957            synchronized (this) {
20958                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20959                // its own permission.
20960                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20961                        != PackageManager.PERMISSION_GRANTED) {
20962                    throw new SecurityException("Requires permission "
20963                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20964                }
20965
20966                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20967                    throw new IllegalArgumentException("null profile info or fd");
20968                }
20969
20970                ProcessRecord proc = null;
20971                if (process != null) {
20972                    proc = findProcessLocked(process, userId, "profileControl");
20973                }
20974
20975                if (start && (proc == null || proc.thread == null)) {
20976                    throw new IllegalArgumentException("Unknown process: " + process);
20977                }
20978
20979                if (start) {
20980                    stopProfilerLocked(null, 0);
20981                    setProfileApp(proc.info, proc.processName, profilerInfo);
20982                    mProfileProc = proc;
20983                    mProfileType = profileType;
20984                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20985                    try {
20986                        fd = fd.dup();
20987                    } catch (IOException e) {
20988                        fd = null;
20989                    }
20990                    profilerInfo.profileFd = fd;
20991                    proc.thread.profilerControl(start, profilerInfo, profileType);
20992                    fd = null;
20993                    mProfileFd = null;
20994                } else {
20995                    stopProfilerLocked(proc, profileType);
20996                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20997                        try {
20998                            profilerInfo.profileFd.close();
20999                        } catch (IOException e) {
21000                        }
21001                    }
21002                }
21003
21004                return true;
21005            }
21006        } catch (RemoteException e) {
21007            throw new IllegalStateException("Process disappeared");
21008        } finally {
21009            if (profilerInfo != null && profilerInfo.profileFd != null) {
21010                try {
21011                    profilerInfo.profileFd.close();
21012                } catch (IOException e) {
21013                }
21014            }
21015        }
21016    }
21017
21018    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21019        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21020                userId, true, ALLOW_FULL_ONLY, callName, null);
21021        ProcessRecord proc = null;
21022        try {
21023            int pid = Integer.parseInt(process);
21024            synchronized (mPidsSelfLocked) {
21025                proc = mPidsSelfLocked.get(pid);
21026            }
21027        } catch (NumberFormatException e) {
21028        }
21029
21030        if (proc == null) {
21031            ArrayMap<String, SparseArray<ProcessRecord>> all
21032                    = mProcessNames.getMap();
21033            SparseArray<ProcessRecord> procs = all.get(process);
21034            if (procs != null && procs.size() > 0) {
21035                proc = procs.valueAt(0);
21036                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21037                    for (int i=1; i<procs.size(); i++) {
21038                        ProcessRecord thisProc = procs.valueAt(i);
21039                        if (thisProc.userId == userId) {
21040                            proc = thisProc;
21041                            break;
21042                        }
21043                    }
21044                }
21045            }
21046        }
21047
21048        return proc;
21049    }
21050
21051    public boolean dumpHeap(String process, int userId, boolean managed,
21052            String path, ParcelFileDescriptor fd) throws RemoteException {
21053
21054        try {
21055            synchronized (this) {
21056                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21057                // its own permission (same as profileControl).
21058                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21059                        != PackageManager.PERMISSION_GRANTED) {
21060                    throw new SecurityException("Requires permission "
21061                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21062                }
21063
21064                if (fd == null) {
21065                    throw new IllegalArgumentException("null fd");
21066                }
21067
21068                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21069                if (proc == null || proc.thread == null) {
21070                    throw new IllegalArgumentException("Unknown process: " + process);
21071                }
21072
21073                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21074                if (!isDebuggable) {
21075                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21076                        throw new SecurityException("Process not debuggable: " + proc);
21077                    }
21078                }
21079
21080                proc.thread.dumpHeap(managed, path, fd);
21081                fd = null;
21082                return true;
21083            }
21084        } catch (RemoteException e) {
21085            throw new IllegalStateException("Process disappeared");
21086        } finally {
21087            if (fd != null) {
21088                try {
21089                    fd.close();
21090                } catch (IOException e) {
21091                }
21092            }
21093        }
21094    }
21095
21096    @Override
21097    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21098            String reportPackage) {
21099        if (processName != null) {
21100            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21101                    "setDumpHeapDebugLimit()");
21102        } else {
21103            synchronized (mPidsSelfLocked) {
21104                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21105                if (proc == null) {
21106                    throw new SecurityException("No process found for calling pid "
21107                            + Binder.getCallingPid());
21108                }
21109                if (!Build.IS_DEBUGGABLE
21110                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21111                    throw new SecurityException("Not running a debuggable build");
21112                }
21113                processName = proc.processName;
21114                uid = proc.uid;
21115                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21116                    throw new SecurityException("Package " + reportPackage + " is not running in "
21117                            + proc);
21118                }
21119            }
21120        }
21121        synchronized (this) {
21122            if (maxMemSize > 0) {
21123                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21124            } else {
21125                if (uid != 0) {
21126                    mMemWatchProcesses.remove(processName, uid);
21127                } else {
21128                    mMemWatchProcesses.getMap().remove(processName);
21129                }
21130            }
21131        }
21132    }
21133
21134    @Override
21135    public void dumpHeapFinished(String path) {
21136        synchronized (this) {
21137            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21138                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21139                        + " does not match last pid " + mMemWatchDumpPid);
21140                return;
21141            }
21142            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21143                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21144                        + " does not match last path " + mMemWatchDumpFile);
21145                return;
21146            }
21147            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21148            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21149        }
21150    }
21151
21152    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21153    public void monitor() {
21154        synchronized (this) { }
21155    }
21156
21157    void onCoreSettingsChange(Bundle settings) {
21158        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21159            ProcessRecord processRecord = mLruProcesses.get(i);
21160            try {
21161                if (processRecord.thread != null) {
21162                    processRecord.thread.setCoreSettings(settings);
21163                }
21164            } catch (RemoteException re) {
21165                /* ignore */
21166            }
21167        }
21168    }
21169
21170    // Multi-user methods
21171
21172    /**
21173     * Start user, if its not already running, but don't bring it to foreground.
21174     */
21175    @Override
21176    public boolean startUserInBackground(final int userId) {
21177        return mUserController.startUser(userId, /* foreground */ false);
21178    }
21179
21180    @Override
21181    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21182        return mUserController.unlockUser(userId, token, secret, listener);
21183    }
21184
21185    @Override
21186    public boolean switchUser(final int targetUserId) {
21187        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21188        UserInfo currentUserInfo;
21189        UserInfo targetUserInfo;
21190        synchronized (this) {
21191            int currentUserId = mUserController.getCurrentUserIdLocked();
21192            currentUserInfo = mUserController.getUserInfo(currentUserId);
21193            targetUserInfo = mUserController.getUserInfo(targetUserId);
21194            if (targetUserInfo == null) {
21195                Slog.w(TAG, "No user info for user #" + targetUserId);
21196                return false;
21197            }
21198            if (!targetUserInfo.supportsSwitchTo()) {
21199                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21200                return false;
21201            }
21202            if (targetUserInfo.isManagedProfile()) {
21203                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21204                return false;
21205            }
21206            mUserController.setTargetUserIdLocked(targetUserId);
21207        }
21208        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21209        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21210        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21211        return true;
21212    }
21213
21214    void scheduleStartProfilesLocked() {
21215        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21216            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21217                    DateUtils.SECOND_IN_MILLIS);
21218        }
21219    }
21220
21221    @Override
21222    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21223        return mUserController.stopUser(userId, force, callback);
21224    }
21225
21226    @Override
21227    public UserInfo getCurrentUser() {
21228        return mUserController.getCurrentUser();
21229    }
21230
21231    @Override
21232    public boolean isUserRunning(int userId, int flags) {
21233        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21234                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21235            String msg = "Permission Denial: isUserRunning() from pid="
21236                    + Binder.getCallingPid()
21237                    + ", uid=" + Binder.getCallingUid()
21238                    + " requires " + INTERACT_ACROSS_USERS;
21239            Slog.w(TAG, msg);
21240            throw new SecurityException(msg);
21241        }
21242        synchronized (this) {
21243            return mUserController.isUserRunningLocked(userId, flags);
21244        }
21245    }
21246
21247    @Override
21248    public int[] getRunningUserIds() {
21249        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21250                != PackageManager.PERMISSION_GRANTED) {
21251            String msg = "Permission Denial: isUserRunning() from pid="
21252                    + Binder.getCallingPid()
21253                    + ", uid=" + Binder.getCallingUid()
21254                    + " requires " + INTERACT_ACROSS_USERS;
21255            Slog.w(TAG, msg);
21256            throw new SecurityException(msg);
21257        }
21258        synchronized (this) {
21259            return mUserController.getStartedUserArrayLocked();
21260        }
21261    }
21262
21263    @Override
21264    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21265        mUserController.registerUserSwitchObserver(observer);
21266    }
21267
21268    @Override
21269    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21270        mUserController.unregisterUserSwitchObserver(observer);
21271    }
21272
21273    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21274        if (info == null) return null;
21275        ApplicationInfo newInfo = new ApplicationInfo(info);
21276        newInfo.initForUser(userId);
21277        return newInfo;
21278    }
21279
21280    public boolean isUserStopped(int userId) {
21281        synchronized (this) {
21282            return mUserController.getStartedUserStateLocked(userId) == null;
21283        }
21284    }
21285
21286    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21287        if (aInfo == null
21288                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21289            return aInfo;
21290        }
21291
21292        ActivityInfo info = new ActivityInfo(aInfo);
21293        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21294        return info;
21295    }
21296
21297    private boolean processSanityChecksLocked(ProcessRecord process) {
21298        if (process == null || process.thread == null) {
21299            return false;
21300        }
21301
21302        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21303        if (!isDebuggable) {
21304            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21305                return false;
21306            }
21307        }
21308
21309        return true;
21310    }
21311
21312    public boolean startBinderTracking() throws RemoteException {
21313        synchronized (this) {
21314            mBinderTransactionTrackingEnabled = true;
21315            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21316            // permission (same as profileControl).
21317            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21318                    != PackageManager.PERMISSION_GRANTED) {
21319                throw new SecurityException("Requires permission "
21320                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21321            }
21322
21323            for (int i = 0; i < mLruProcesses.size(); i++) {
21324                ProcessRecord process = mLruProcesses.get(i);
21325                if (!processSanityChecksLocked(process)) {
21326                    continue;
21327                }
21328                try {
21329                    process.thread.startBinderTracking();
21330                } catch (RemoteException e) {
21331                    Log.v(TAG, "Process disappared");
21332                }
21333            }
21334            return true;
21335        }
21336    }
21337
21338    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21339        try {
21340            synchronized (this) {
21341                mBinderTransactionTrackingEnabled = false;
21342                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21343                // permission (same as profileControl).
21344                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21345                        != PackageManager.PERMISSION_GRANTED) {
21346                    throw new SecurityException("Requires permission "
21347                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21348                }
21349
21350                if (fd == null) {
21351                    throw new IllegalArgumentException("null fd");
21352                }
21353
21354                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21355                pw.println("Binder transaction traces for all processes.\n");
21356                for (ProcessRecord process : mLruProcesses) {
21357                    if (!processSanityChecksLocked(process)) {
21358                        continue;
21359                    }
21360
21361                    pw.println("Traces for process: " + process.processName);
21362                    pw.flush();
21363                    try {
21364                        TransferPipe tp = new TransferPipe();
21365                        try {
21366                            process.thread.stopBinderTrackingAndDump(
21367                                    tp.getWriteFd().getFileDescriptor());
21368                            tp.go(fd.getFileDescriptor());
21369                        } finally {
21370                            tp.kill();
21371                        }
21372                    } catch (IOException e) {
21373                        pw.println("Failure while dumping IPC traces from " + process +
21374                                ".  Exception: " + e);
21375                        pw.flush();
21376                    } catch (RemoteException e) {
21377                        pw.println("Got a RemoteException while dumping IPC traces from " +
21378                                process + ".  Exception: " + e);
21379                        pw.flush();
21380                    }
21381                }
21382                fd = null;
21383                return true;
21384            }
21385        } finally {
21386            if (fd != null) {
21387                try {
21388                    fd.close();
21389                } catch (IOException e) {
21390                }
21391            }
21392        }
21393    }
21394
21395    private final class LocalService extends ActivityManagerInternal {
21396        @Override
21397        public void onWakefulnessChanged(int wakefulness) {
21398            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21399        }
21400
21401        @Override
21402        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21403                String processName, String abiOverride, int uid, Runnable crashHandler) {
21404            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21405                    processName, abiOverride, uid, crashHandler);
21406        }
21407
21408        @Override
21409        public SleepToken acquireSleepToken(String tag) {
21410            Preconditions.checkNotNull(tag);
21411
21412            synchronized (ActivityManagerService.this) {
21413                SleepTokenImpl token = new SleepTokenImpl(tag);
21414                mSleepTokens.add(token);
21415                updateSleepIfNeededLocked();
21416                applyVrModeIfNeededLocked(mFocusedActivity, false);
21417                return token;
21418            }
21419        }
21420
21421        @Override
21422        public ComponentName getHomeActivityForUser(int userId) {
21423            synchronized (ActivityManagerService.this) {
21424                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21425                return homeActivity == null ? null : homeActivity.realActivity;
21426            }
21427        }
21428
21429        @Override
21430        public void onUserRemoved(int userId) {
21431            synchronized (ActivityManagerService.this) {
21432                ActivityManagerService.this.onUserStoppedLocked(userId);
21433            }
21434        }
21435
21436        @Override
21437        public void onLocalVoiceInteractionStarted(IBinder activity,
21438                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21439            synchronized (ActivityManagerService.this) {
21440                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21441                        voiceSession, voiceInteractor);
21442            }
21443        }
21444
21445        @Override
21446        public void notifyStartingWindowDrawn() {
21447            synchronized (ActivityManagerService.this) {
21448                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21449            }
21450        }
21451
21452        @Override
21453        public void notifyAppTransitionStarting(int reason) {
21454            synchronized (ActivityManagerService.this) {
21455                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21456            }
21457        }
21458
21459        @Override
21460        public void notifyAppTransitionFinished() {
21461            synchronized (ActivityManagerService.this) {
21462                mStackSupervisor.notifyAppTransitionDone();
21463            }
21464        }
21465
21466        @Override
21467        public void notifyAppTransitionCancelled() {
21468            synchronized (ActivityManagerService.this) {
21469                mStackSupervisor.notifyAppTransitionDone();
21470            }
21471        }
21472
21473        @Override
21474        public List<IBinder> getTopVisibleActivities() {
21475            synchronized (ActivityManagerService.this) {
21476                return mStackSupervisor.getTopVisibleActivities();
21477            }
21478        }
21479
21480        @Override
21481        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21482            synchronized (ActivityManagerService.this) {
21483                mStackSupervisor.setDockedStackMinimized(minimized);
21484            }
21485        }
21486
21487        @Override
21488        public void killForegroundAppsForUser(int userHandle) {
21489            synchronized (ActivityManagerService.this) {
21490                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21491                final int NP = mProcessNames.getMap().size();
21492                for (int ip = 0; ip < NP; ip++) {
21493                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21494                    final int NA = apps.size();
21495                    for (int ia = 0; ia < NA; ia++) {
21496                        final ProcessRecord app = apps.valueAt(ia);
21497                        if (app.persistent) {
21498                            // We don't kill persistent processes.
21499                            continue;
21500                        }
21501                        if (app.removed) {
21502                            procs.add(app);
21503                        } else if (app.userId == userHandle && app.foregroundActivities) {
21504                            app.removed = true;
21505                            procs.add(app);
21506                        }
21507                    }
21508                }
21509
21510                final int N = procs.size();
21511                for (int i = 0; i < N; i++) {
21512                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21513                }
21514            }
21515        }
21516
21517        @Override
21518        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21519            if (!(target instanceof PendingIntentRecord)) {
21520                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21521                return;
21522            }
21523            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21524        }
21525    }
21526
21527    private final class SleepTokenImpl extends SleepToken {
21528        private final String mTag;
21529        private final long mAcquireTime;
21530
21531        public SleepTokenImpl(String tag) {
21532            mTag = tag;
21533            mAcquireTime = SystemClock.uptimeMillis();
21534        }
21535
21536        @Override
21537        public void release() {
21538            synchronized (ActivityManagerService.this) {
21539                if (mSleepTokens.remove(this)) {
21540                    updateSleepIfNeededLocked();
21541                }
21542            }
21543        }
21544
21545        @Override
21546        public String toString() {
21547            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21548        }
21549    }
21550
21551    /**
21552     * An implementation of IAppTask, that allows an app to manage its own tasks via
21553     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21554     * only the process that calls getAppTasks() can call the AppTask methods.
21555     */
21556    class AppTaskImpl extends IAppTask.Stub {
21557        private int mTaskId;
21558        private int mCallingUid;
21559
21560        public AppTaskImpl(int taskId, int callingUid) {
21561            mTaskId = taskId;
21562            mCallingUid = callingUid;
21563        }
21564
21565        private void checkCaller() {
21566            if (mCallingUid != Binder.getCallingUid()) {
21567                throw new SecurityException("Caller " + mCallingUid
21568                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21569            }
21570        }
21571
21572        @Override
21573        public void finishAndRemoveTask() {
21574            checkCaller();
21575
21576            synchronized (ActivityManagerService.this) {
21577                long origId = Binder.clearCallingIdentity();
21578                try {
21579                    // We remove the task from recents to preserve backwards
21580                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21581                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21582                    }
21583                } finally {
21584                    Binder.restoreCallingIdentity(origId);
21585                }
21586            }
21587        }
21588
21589        @Override
21590        public ActivityManager.RecentTaskInfo getTaskInfo() {
21591            checkCaller();
21592
21593            synchronized (ActivityManagerService.this) {
21594                long origId = Binder.clearCallingIdentity();
21595                try {
21596                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21597                    if (tr == null) {
21598                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21599                    }
21600                    return createRecentTaskInfoFromTaskRecord(tr);
21601                } finally {
21602                    Binder.restoreCallingIdentity(origId);
21603                }
21604            }
21605        }
21606
21607        @Override
21608        public void moveToFront() {
21609            checkCaller();
21610            // Will bring task to front if it already has a root activity.
21611            final long origId = Binder.clearCallingIdentity();
21612            try {
21613                synchronized (this) {
21614                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21615                }
21616            } finally {
21617                Binder.restoreCallingIdentity(origId);
21618            }
21619        }
21620
21621        @Override
21622        public int startActivity(IBinder whoThread, String callingPackage,
21623                Intent intent, String resolvedType, Bundle bOptions) {
21624            checkCaller();
21625
21626            int callingUser = UserHandle.getCallingUserId();
21627            TaskRecord tr;
21628            IApplicationThread appThread;
21629            synchronized (ActivityManagerService.this) {
21630                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21631                if (tr == null) {
21632                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21633                }
21634                appThread = ApplicationThreadNative.asInterface(whoThread);
21635                if (appThread == null) {
21636                    throw new IllegalArgumentException("Bad app thread " + appThread);
21637                }
21638            }
21639            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21640                    resolvedType, null, null, null, null, 0, 0, null, null,
21641                    null, bOptions, false, callingUser, null, tr);
21642        }
21643
21644        @Override
21645        public void setExcludeFromRecents(boolean exclude) {
21646            checkCaller();
21647
21648            synchronized (ActivityManagerService.this) {
21649                long origId = Binder.clearCallingIdentity();
21650                try {
21651                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21652                    if (tr == null) {
21653                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21654                    }
21655                    Intent intent = tr.getBaseIntent();
21656                    if (exclude) {
21657                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21658                    } else {
21659                        intent.setFlags(intent.getFlags()
21660                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21661                    }
21662                } finally {
21663                    Binder.restoreCallingIdentity(origId);
21664                }
21665            }
21666        }
21667    }
21668
21669    /**
21670     * Kill processes for the user with id userId and that depend on the package named packageName
21671     */
21672    @Override
21673    public void killPackageDependents(String packageName, int userId) {
21674        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21675        if (packageName == null) {
21676            throw new NullPointerException(
21677                    "Cannot kill the dependents of a package without its name.");
21678        }
21679
21680        long callingId = Binder.clearCallingIdentity();
21681        IPackageManager pm = AppGlobals.getPackageManager();
21682        int pkgUid = -1;
21683        try {
21684            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21685        } catch (RemoteException e) {
21686        }
21687        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21688            throw new IllegalArgumentException(
21689                    "Cannot kill dependents of non-existing package " + packageName);
21690        }
21691        try {
21692            synchronized(this) {
21693                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21694                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21695                        "dep: " + packageName);
21696            }
21697        } finally {
21698            Binder.restoreCallingIdentity(callingId);
21699        }
21700    }
21701}
21702