ActivityManagerService.java revision c8da41e2f4f6087b5ae0e08a30962d8f5231b01c
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.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
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.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.Looper;
171import android.os.Message;
172import android.os.Parcel;
173import android.os.ParcelFileDescriptor;
174import android.os.PersistableBundle;
175import android.os.PowerManager;
176import android.os.PowerManagerInternal;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.ResultReceiver;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.Trace;
186import android.os.TransactionTooLargeException;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.os.WorkSource;
191import android.os.storage.IMountService;
192import android.os.storage.MountServiceInternal;
193import android.os.storage.StorageManager;
194import android.provider.Settings;
195import android.service.voice.IVoiceInteractionSession;
196import android.service.voice.VoiceInteractionManagerInternal;
197import android.service.voice.VoiceInteractionSession;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.ArrayMap;
201import android.util.ArraySet;
202import android.util.AtomicFile;
203import android.util.DebugUtils;
204import android.util.EventLog;
205import android.util.LocaleList;
206import android.util.Log;
207import android.util.Pair;
208import android.util.PrintWriterPrinter;
209import android.util.Slog;
210import android.util.SparseArray;
211import android.util.TimeUtils;
212import android.util.Xml;
213import android.view.Display;
214import android.view.Gravity;
215import android.view.LayoutInflater;
216import android.view.View;
217import android.view.WindowManager;
218
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
277import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
278import static android.provider.Settings.System.FONT_SCALE;
279import static com.android.internal.util.XmlUtils.readBooleanAttribute;
280import static com.android.internal.util.XmlUtils.readIntAttribute;
281import static com.android.internal.util.XmlUtils.readLongAttribute;
282import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
283import static com.android.internal.util.XmlUtils.writeIntAttribute;
284import static com.android.internal.util.XmlUtils.writeLongAttribute;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
341import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
343import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
344import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
345import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
346import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
347import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
348import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
349import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
353import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
354import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
355import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
358import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
359import static org.xmlpull.v1.XmlPullParser.START_TAG;
360
361public final class ActivityManagerService extends ActivityManagerNative
362        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
363
364    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
365    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
366    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
367    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
368    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
369    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
370    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
371    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
372    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
373    private static final String TAG_LRU = TAG + POSTFIX_LRU;
374    private static final String TAG_MU = TAG + POSTFIX_MU;
375    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
376    private static final String TAG_POWER = TAG + POSTFIX_POWER;
377    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
378    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
379    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
380    private static final String TAG_PSS = TAG + POSTFIX_PSS;
381    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
382    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
383    private static final String TAG_STACK = TAG + POSTFIX_STACK;
384    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
385    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
386    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
387    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
388    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
389
390    /** Control over CPU and battery monitoring */
391    // write battery stats every 30 minutes.
392    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
393    static final boolean MONITOR_CPU_USAGE = true;
394    // don't sample cpu less than every 5 seconds.
395    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
396    // wait possibly forever for next cpu sample.
397    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
398    static final boolean MONITOR_THREAD_CPU_USAGE = false;
399
400    // The flags that are set for all calls we make to the package manager.
401    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
402
403    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
404
405    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
406
407    // Amount of time after a call to stopAppSwitches() during which we will
408    // prevent further untrusted switches from happening.
409    static final long APP_SWITCH_DELAY_TIME = 5*1000;
410
411    // How long we wait for a launched process to attach to the activity manager
412    // before we decide it's never going to come up for real.
413    static final int PROC_START_TIMEOUT = 10*1000;
414    // How long we wait for an attached process to publish its content providers
415    // before we decide it must be hung.
416    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
417
418    // How long we will retain processes hosting content providers in the "last activity"
419    // state before allowing them to drop down to the regular cached LRU list.  This is
420    // to avoid thrashing of provider processes under low memory situations.
421    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*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, when the process was
425    // started with a wrapper for instrumentation (such as Valgrind) because it
426    // could take much longer than usual.
427    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
428
429    // How long to wait after going idle before forcing apps to GC.
430    static final int GC_TIMEOUT = 5*1000;
431
432    // The minimum amount of time between successive GC requests for a process.
433    static final int GC_MIN_INTERVAL = 60*1000;
434
435    // The minimum amount of time between successive PSS requests for a process.
436    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
437
438    // The minimum amount of time between successive PSS requests for a process
439    // when the request is due to the memory state being lowered.
440    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
441
442    // The rate at which we check for apps using excessive power -- 15 mins.
443    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
444
445    // The minimum sample duration we will allow before deciding we have
446    // enough data on wake locks to start killing things.
447    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
448
449    // The minimum sample duration we will allow before deciding we have
450    // enough data on CPU usage to start killing things.
451    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
452
453    // How long we allow a receiver to run before giving up on it.
454    static final int BROADCAST_FG_TIMEOUT = 10*1000;
455    static final int BROADCAST_BG_TIMEOUT = 60*1000;
456
457    // How long we wait until we timeout on key dispatching.
458    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
459
460    // How long we wait until we timeout on key dispatching during instrumentation.
461    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
462
463    // This is the amount of time an app needs to be running a foreground service before
464    // we will consider it to be doing interaction for usage stats.
465    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
466
467    // Maximum amount of time we will allow to elapse before re-reporting usage stats
468    // interaction with foreground processes.
469    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
470
471    // This is the amount of time we allow an app to settle after it goes into the background,
472    // before we start restricting what it can do.
473    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
474
475    // How long to wait in getAssistContextExtras for the activity and foreground services
476    // to respond with the result.
477    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
478
479    // How long top wait when going through the modern assist (which doesn't need to block
480    // on getting this result before starting to launch its UI).
481    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
482
483    // Maximum number of persisted Uri grants a package is allowed
484    static final int MAX_PERSISTED_URI_GRANTS = 128;
485
486    static final int MY_PID = Process.myPid();
487
488    static final String[] EMPTY_STRING_ARRAY = new String[0];
489
490    // How many bytes to write into the dropbox log before truncating
491    static final int DROPBOX_MAX_SIZE = 256 * 1024;
492
493    // Access modes for handleIncomingUser.
494    static final int ALLOW_NON_FULL = 0;
495    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
496    static final int ALLOW_FULL_ONLY = 2;
497
498    // Delay in notifying task stack change listeners (in millis)
499    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
500
501    // Necessary ApplicationInfo flags to mark an app as persistent
502    private static final int PERSISTENT_MASK =
503            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
504
505    // Intent sent when remote bugreport collection has been completed
506    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
507            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
508
509    // Delay to disable app launch boost
510    static final int APP_BOOST_MESSAGE_DELAY = 3000;
511    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
512    static final int APP_BOOST_TIMEOUT = 2500;
513
514    // Used to indicate that a task is removed it should also be removed from recents.
515    private static final boolean REMOVE_FROM_RECENTS = true;
516    // Used to indicate that an app transition should be animated.
517    static final boolean ANIMATE = true;
518
519    // Determines whether to take full screen screenshots
520    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
521    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
522
523    private static native int nativeMigrateToBoost();
524    private static native int nativeMigrateFromBoost();
525    private boolean mIsBoosted = false;
526    private long mBoostStartTime = 0;
527
528    /** All system services */
529    SystemServiceManager mSystemServiceManager;
530
531    private Installer mInstaller;
532
533    /** Run all ActivityStacks through this */
534    final ActivityStackSupervisor mStackSupervisor;
535
536    final ActivityStarter mActivityStarter;
537
538    /** Task stack change listeners. */
539    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
540            new RemoteCallbackList<ITaskStackListener>();
541
542    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
543
544    public IntentFirewall mIntentFirewall;
545
546    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
547    // default actuion automatically.  Important for devices without direct input
548    // devices.
549    private boolean mShowDialogs = true;
550    private boolean mInVrMode = false;
551
552    BroadcastQueue mFgBroadcastQueue;
553    BroadcastQueue mBgBroadcastQueue;
554    // Convenient for easy iteration over the queues. Foreground is first
555    // so that dispatch of foreground broadcasts gets precedence.
556    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
557
558    BroadcastQueue broadcastQueueForIntent(Intent intent) {
559        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
560        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
561                "Broadcast intent " + intent + " on "
562                + (isFg ? "foreground" : "background") + " queue");
563        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
564    }
565
566    /**
567     * Activity we have told the window manager to have key focus.
568     */
569    ActivityRecord mFocusedActivity = null;
570
571    /**
572     * User id of the last activity mFocusedActivity was set to.
573     */
574    private int mLastFocusedUserId;
575
576    /**
577     * If non-null, we are tracking the time the user spends in the currently focused app.
578     */
579    private AppTimeTracker mCurAppTimeTracker;
580
581    /**
582     * List of intents that were used to start the most recent tasks.
583     */
584    final RecentTasks mRecentTasks;
585
586    /**
587     * For addAppTask: cached of the last activity component that was added.
588     */
589    ComponentName mLastAddedTaskComponent;
590
591    /**
592     * For addAppTask: cached of the last activity uid that was added.
593     */
594    int mLastAddedTaskUid;
595
596    /**
597     * For addAppTask: cached of the last ActivityInfo that was added.
598     */
599    ActivityInfo mLastAddedTaskActivity;
600
601    /**
602     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
603     */
604    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
605
606    /**
607     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
608     */
609    String mDeviceOwnerName;
610
611    final UserController mUserController;
612
613    final AppErrors mAppErrors;
614
615    boolean mDoingSetFocusedActivity;
616
617    public boolean canShowErrorDialogs() {
618        return mShowDialogs && !mSleeping && !mShuttingDown;
619    }
620
621    public class PendingAssistExtras extends Binder implements Runnable {
622        public final ActivityRecord activity;
623        public final Bundle extras;
624        public final Intent intent;
625        public final String hint;
626        public final IResultReceiver receiver;
627        public final int userHandle;
628        public boolean haveResult = false;
629        public Bundle result = null;
630        public AssistStructure structure = null;
631        public AssistContent content = null;
632        public Bundle receiverExtras;
633
634        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
635                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
636            activity = _activity;
637            extras = _extras;
638            intent = _intent;
639            hint = _hint;
640            receiver = _receiver;
641            receiverExtras = _receiverExtras;
642            userHandle = _userHandle;
643        }
644        @Override
645        public void run() {
646            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
647            synchronized (this) {
648                haveResult = true;
649                notifyAll();
650            }
651            pendingAssistExtrasTimedOut(this);
652        }
653    }
654
655    final ArrayList<PendingAssistExtras> mPendingAssistExtras
656            = new ArrayList<PendingAssistExtras>();
657
658    /**
659     * Process management.
660     */
661    final ProcessList mProcessList = new ProcessList();
662
663    /**
664     * All of the applications we currently have running organized by name.
665     * The keys are strings of the application package name (as
666     * returned by the package manager), and the keys are ApplicationRecord
667     * objects.
668     */
669    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
670
671    /**
672     * Tracking long-term execution of processes to look for abuse and other
673     * bad app behavior.
674     */
675    final ProcessStatsService mProcessStats;
676
677    /**
678     * The currently running isolated processes.
679     */
680    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
681
682    /**
683     * Counter for assigning isolated process uids, to avoid frequently reusing the
684     * same ones.
685     */
686    int mNextIsolatedProcessUid = 0;
687
688    /**
689     * The currently running heavy-weight process, if any.
690     */
691    ProcessRecord mHeavyWeightProcess = null;
692
693    /**
694     * All of the processes we currently have running organized by pid.
695     * The keys are the pid running the application.
696     *
697     * <p>NOTE: This object is protected by its own lock, NOT the global
698     * activity manager lock!
699     */
700    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
701
702    /**
703     * All of the processes that have been forced to be foreground.  The key
704     * is the pid of the caller who requested it (we hold a death
705     * link on it).
706     */
707    abstract class ForegroundToken implements IBinder.DeathRecipient {
708        int pid;
709        IBinder token;
710    }
711    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
712
713    /**
714     * List of records for processes that someone had tried to start before the
715     * system was ready.  We don't start them at that point, but ensure they
716     * are started by the time booting is complete.
717     */
718    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
719
720    /**
721     * List of persistent applications that are in the process
722     * of being started.
723     */
724    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
725
726    /**
727     * Processes that are being forcibly torn down.
728     */
729    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
730
731    /**
732     * List of running applications, sorted by recent usage.
733     * The first entry in the list is the least recently used.
734     */
735    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
736
737    /**
738     * Where in mLruProcesses that the processes hosting activities start.
739     */
740    int mLruProcessActivityStart = 0;
741
742    /**
743     * Where in mLruProcesses that the processes hosting services start.
744     * This is after (lower index) than mLruProcessesActivityStart.
745     */
746    int mLruProcessServiceStart = 0;
747
748    /**
749     * List of processes that should gc as soon as things are idle.
750     */
751    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
752
753    /**
754     * Processes we want to collect PSS data from.
755     */
756    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
757
758    private boolean mBinderTransactionTrackingEnabled = false;
759
760    /**
761     * Last time we requested PSS data of all processes.
762     */
763    long mLastFullPssTime = SystemClock.uptimeMillis();
764
765    /**
766     * If set, the next time we collect PSS data we should do a full collection
767     * with data from native processes and the kernel.
768     */
769    boolean mFullPssPending = false;
770
771    /**
772     * This is the process holding what we currently consider to be
773     * the "home" activity.
774     */
775    ProcessRecord mHomeProcess;
776
777    /**
778     * This is the process holding the activity the user last visited that
779     * is in a different process from the one they are currently in.
780     */
781    ProcessRecord mPreviousProcess;
782
783    /**
784     * The time at which the previous process was last visible.
785     */
786    long mPreviousProcessVisibleTime;
787
788    /**
789     * Track all uids that have actively running processes.
790     */
791    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
792
793    /**
794     * This is for verifying the UID report flow.
795     */
796    static final boolean VALIDATE_UID_STATES = true;
797    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
798
799    /**
800     * Packages that the user has asked to have run in screen size
801     * compatibility mode instead of filling the screen.
802     */
803    final CompatModePackages mCompatModePackages;
804
805    /**
806     * Set of IntentSenderRecord objects that are currently active.
807     */
808    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
809            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
810
811    /**
812     * Fingerprints (hashCode()) of stack traces that we've
813     * already logged DropBox entries for.  Guarded by itself.  If
814     * something (rogue user app) forces this over
815     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
816     */
817    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
818    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
819
820    /**
821     * Strict Mode background batched logging state.
822     *
823     * The string buffer is guarded by itself, and its lock is also
824     * used to determine if another batched write is already
825     * in-flight.
826     */
827    private final StringBuilder mStrictModeBuffer = new StringBuilder();
828
829    /**
830     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
831     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
832     */
833    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
834
835    /**
836     * Resolver for broadcast intents to registered receivers.
837     * Holds BroadcastFilter (subclass of IntentFilter).
838     */
839    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
840            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
841        @Override
842        protected boolean allowFilterResult(
843                BroadcastFilter filter, List<BroadcastFilter> dest) {
844            IBinder target = filter.receiverList.receiver.asBinder();
845            for (int i = dest.size() - 1; i >= 0; i--) {
846                if (dest.get(i).receiverList.receiver.asBinder() == target) {
847                    return false;
848                }
849            }
850            return true;
851        }
852
853        @Override
854        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
855            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
856                    || userId == filter.owningUserId) {
857                return super.newResult(filter, match, userId);
858            }
859            return null;
860        }
861
862        @Override
863        protected BroadcastFilter[] newArray(int size) {
864            return new BroadcastFilter[size];
865        }
866
867        @Override
868        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
869            return packageName.equals(filter.packageName);
870        }
871    };
872
873    /**
874     * State of all active sticky broadcasts per user.  Keys are the action of the
875     * sticky Intent, values are an ArrayList of all broadcasted intents with
876     * that action (which should usually be one).  The SparseArray is keyed
877     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
878     * for stickies that are sent to all users.
879     */
880    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
881            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
882
883    final ActiveServices mServices;
884
885    final static class Association {
886        final int mSourceUid;
887        final String mSourceProcess;
888        final int mTargetUid;
889        final ComponentName mTargetComponent;
890        final String mTargetProcess;
891
892        int mCount;
893        long mTime;
894
895        int mNesting;
896        long mStartTime;
897
898        // states of the source process when the bind occurred.
899        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
900        long mLastStateUptime;
901        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
902                - ActivityManager.MIN_PROCESS_STATE+1];
903
904        Association(int sourceUid, String sourceProcess, int targetUid,
905                ComponentName targetComponent, String targetProcess) {
906            mSourceUid = sourceUid;
907            mSourceProcess = sourceProcess;
908            mTargetUid = targetUid;
909            mTargetComponent = targetComponent;
910            mTargetProcess = targetProcess;
911        }
912    }
913
914    /**
915     * When service association tracking is enabled, this is all of the associations we
916     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
917     * -> association data.
918     */
919    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
920            mAssociations = new SparseArray<>();
921    boolean mTrackingAssociations;
922
923    /**
924     * Backup/restore process management
925     */
926    String mBackupAppName = null;
927    BackupRecord mBackupTarget = null;
928
929    final ProviderMap mProviderMap;
930
931    /**
932     * List of content providers who have clients waiting for them.  The
933     * application is currently being launched and the provider will be
934     * removed from this list once it is published.
935     */
936    final ArrayList<ContentProviderRecord> mLaunchingProviders
937            = new ArrayList<ContentProviderRecord>();
938
939    /**
940     * File storing persisted {@link #mGrantedUriPermissions}.
941     */
942    private final AtomicFile mGrantFile;
943
944    /** XML constants used in {@link #mGrantFile} */
945    private static final String TAG_URI_GRANTS = "uri-grants";
946    private static final String TAG_URI_GRANT = "uri-grant";
947    private static final String ATTR_USER_HANDLE = "userHandle";
948    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
949    private static final String ATTR_TARGET_USER_ID = "targetUserId";
950    private static final String ATTR_SOURCE_PKG = "sourcePkg";
951    private static final String ATTR_TARGET_PKG = "targetPkg";
952    private static final String ATTR_URI = "uri";
953    private static final String ATTR_MODE_FLAGS = "modeFlags";
954    private static final String ATTR_CREATED_TIME = "createdTime";
955    private static final String ATTR_PREFIX = "prefix";
956
957    /**
958     * Global set of specific {@link Uri} permissions that have been granted.
959     * This optimized lookup structure maps from {@link UriPermission#targetUid}
960     * to {@link UriPermission#uri} to {@link UriPermission}.
961     */
962    @GuardedBy("this")
963    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
964            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
965
966    public static class GrantUri {
967        public final int sourceUserId;
968        public final Uri uri;
969        public boolean prefix;
970
971        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
972            this.sourceUserId = sourceUserId;
973            this.uri = uri;
974            this.prefix = prefix;
975        }
976
977        @Override
978        public int hashCode() {
979            int hashCode = 1;
980            hashCode = 31 * hashCode + sourceUserId;
981            hashCode = 31 * hashCode + uri.hashCode();
982            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
983            return hashCode;
984        }
985
986        @Override
987        public boolean equals(Object o) {
988            if (o instanceof GrantUri) {
989                GrantUri other = (GrantUri) o;
990                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
991                        && prefix == other.prefix;
992            }
993            return false;
994        }
995
996        @Override
997        public String toString() {
998            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
999            if (prefix) result += " [prefix]";
1000            return result;
1001        }
1002
1003        public String toSafeString() {
1004            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1005            if (prefix) result += " [prefix]";
1006            return result;
1007        }
1008
1009        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1010            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1011                    ContentProvider.getUriWithoutUserId(uri), false);
1012        }
1013    }
1014
1015    CoreSettingsObserver mCoreSettingsObserver;
1016
1017    FontScaleSettingObserver mFontScaleSettingObserver;
1018
1019    private final class FontScaleSettingObserver extends ContentObserver {
1020        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1021
1022        public FontScaleSettingObserver() {
1023            super(mHandler);
1024            ContentResolver resolver = mContext.getContentResolver();
1025            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1026        }
1027
1028        @Override
1029        public void onChange(boolean selfChange, Uri uri) {
1030            if (mFontScaleUri.equals(uri)) {
1031                updateFontScaleIfNeeded();
1032            }
1033        }
1034    }
1035
1036    /**
1037     * Thread-local storage used to carry caller permissions over through
1038     * indirect content-provider access.
1039     */
1040    private class Identity {
1041        public final IBinder token;
1042        public final int pid;
1043        public final int uid;
1044
1045        Identity(IBinder _token, int _pid, int _uid) {
1046            token = _token;
1047            pid = _pid;
1048            uid = _uid;
1049        }
1050    }
1051
1052    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1053
1054    /**
1055     * All information we have collected about the runtime performance of
1056     * any user id that can impact battery performance.
1057     */
1058    final BatteryStatsService mBatteryStatsService;
1059
1060    /**
1061     * Information about component usage
1062     */
1063    UsageStatsManagerInternal mUsageStatsService;
1064
1065    /**
1066     * Access to DeviceIdleController service.
1067     */
1068    DeviceIdleController.LocalService mLocalDeviceIdleController;
1069
1070    /**
1071     * Information about and control over application operations
1072     */
1073    final AppOpsService mAppOpsService;
1074
1075    /**
1076     * Current configuration information.  HistoryRecord objects are given
1077     * a reference to this object to indicate which configuration they are
1078     * currently running in, so this object must be kept immutable.
1079     */
1080    Configuration mConfiguration = new Configuration();
1081
1082    /**
1083     * Current sequencing integer of the configuration, for skipping old
1084     * configurations.
1085     */
1086    int mConfigurationSeq = 0;
1087
1088    boolean mSuppressResizeConfigChanges = false;
1089
1090    /**
1091     * Hardware-reported OpenGLES version.
1092     */
1093    final int GL_ES_VERSION;
1094
1095    /**
1096     * List of initialization arguments to pass to all processes when binding applications to them.
1097     * For example, references to the commonly used services.
1098     */
1099    HashMap<String, IBinder> mAppBindArgs;
1100
1101    /**
1102     * Temporary to avoid allocations.  Protected by main lock.
1103     */
1104    final StringBuilder mStringBuilder = new StringBuilder(256);
1105
1106    /**
1107     * Used to control how we initialize the service.
1108     */
1109    ComponentName mTopComponent;
1110    String mTopAction = Intent.ACTION_MAIN;
1111    String mTopData;
1112
1113    volatile boolean mProcessesReady = false;
1114    volatile boolean mSystemReady = false;
1115    volatile boolean mOnBattery = false;
1116    volatile int mFactoryTest;
1117
1118    @GuardedBy("this") boolean mBooting = false;
1119    @GuardedBy("this") boolean mCallFinishBooting = false;
1120    @GuardedBy("this") boolean mBootAnimationComplete = false;
1121    @GuardedBy("this") boolean mLaunchWarningShown = false;
1122    @GuardedBy("this") boolean mCheckedForSetup = false;
1123
1124    Context mContext;
1125
1126    /**
1127     * The time at which we will allow normal application switches again,
1128     * after a call to {@link #stopAppSwitches()}.
1129     */
1130    long mAppSwitchesAllowedTime;
1131
1132    /**
1133     * This is set to true after the first switch after mAppSwitchesAllowedTime
1134     * is set; any switches after that will clear the time.
1135     */
1136    boolean mDidAppSwitch;
1137
1138    /**
1139     * Last time (in realtime) at which we checked for power usage.
1140     */
1141    long mLastPowerCheckRealtime;
1142
1143    /**
1144     * Last time (in uptime) at which we checked for power usage.
1145     */
1146    long mLastPowerCheckUptime;
1147
1148    /**
1149     * Set while we are wanting to sleep, to prevent any
1150     * activities from being started/resumed.
1151     */
1152    private boolean mSleeping = false;
1153
1154    /**
1155     * The process state used for processes that are running the top activities.
1156     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1157     */
1158    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1159
1160    /**
1161     * Set while we are running a voice interaction.  This overrides
1162     * sleeping while it is active.
1163     */
1164    private IVoiceInteractionSession mRunningVoice;
1165
1166    /**
1167     * For some direct access we need to power manager.
1168     */
1169    PowerManagerInternal mLocalPowerManager;
1170
1171    /**
1172     * We want to hold a wake lock while running a voice interaction session, since
1173     * this may happen with the screen off and we need to keep the CPU running to
1174     * be able to continue to interact with the user.
1175     */
1176    PowerManager.WakeLock mVoiceWakeLock;
1177
1178    /**
1179     * State of external calls telling us if the device is awake or asleep.
1180     */
1181    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1182
1183    /**
1184     * A list of tokens that cause the top activity to be put to sleep.
1185     * They are used by components that may hide and block interaction with underlying
1186     * activities.
1187     */
1188    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1189
1190    static final int LOCK_SCREEN_HIDDEN = 0;
1191    static final int LOCK_SCREEN_LEAVING = 1;
1192    static final int LOCK_SCREEN_SHOWN = 2;
1193    /**
1194     * State of external call telling us if the lock screen is shown.
1195     */
1196    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1197
1198    /**
1199     * Set if we are shutting down the system, similar to sleeping.
1200     */
1201    boolean mShuttingDown = false;
1202
1203    /**
1204     * Current sequence id for oom_adj computation traversal.
1205     */
1206    int mAdjSeq = 0;
1207
1208    /**
1209     * Current sequence id for process LRU updating.
1210     */
1211    int mLruSeq = 0;
1212
1213    /**
1214     * Keep track of the non-cached/empty process we last found, to help
1215     * determine how to distribute cached/empty processes next time.
1216     */
1217    int mNumNonCachedProcs = 0;
1218
1219    /**
1220     * Keep track of the number of cached hidden procs, to balance oom adj
1221     * distribution between those and empty procs.
1222     */
1223    int mNumCachedHiddenProcs = 0;
1224
1225    /**
1226     * Keep track of the number of service processes we last found, to
1227     * determine on the next iteration which should be B services.
1228     */
1229    int mNumServiceProcs = 0;
1230    int mNewNumAServiceProcs = 0;
1231    int mNewNumServiceProcs = 0;
1232
1233    /**
1234     * Allow the current computed overall memory level of the system to go down?
1235     * This is set to false when we are killing processes for reasons other than
1236     * memory management, so that the now smaller process list will not be taken as
1237     * an indication that memory is tighter.
1238     */
1239    boolean mAllowLowerMemLevel = false;
1240
1241    /**
1242     * The last computed memory level, for holding when we are in a state that
1243     * processes are going away for other reasons.
1244     */
1245    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1246
1247    /**
1248     * The last total number of process we have, to determine if changes actually look
1249     * like a shrinking number of process due to lower RAM.
1250     */
1251    int mLastNumProcesses;
1252
1253    /**
1254     * The uptime of the last time we performed idle maintenance.
1255     */
1256    long mLastIdleTime = SystemClock.uptimeMillis();
1257
1258    /**
1259     * Total time spent with RAM that has been added in the past since the last idle time.
1260     */
1261    long mLowRamTimeSinceLastIdle = 0;
1262
1263    /**
1264     * If RAM is currently low, when that horrible situation started.
1265     */
1266    long mLowRamStartTime = 0;
1267
1268    /**
1269     * For reporting to battery stats the current top application.
1270     */
1271    private String mCurResumedPackage = null;
1272    private int mCurResumedUid = -1;
1273
1274    /**
1275     * For reporting to battery stats the apps currently running foreground
1276     * service.  The ProcessMap is package/uid tuples; each of these contain
1277     * an array of the currently foreground processes.
1278     */
1279    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1280            = new ProcessMap<ArrayList<ProcessRecord>>();
1281
1282    /**
1283     * This is set if we had to do a delayed dexopt of an app before launching
1284     * it, to increase the ANR timeouts in that case.
1285     */
1286    boolean mDidDexOpt;
1287
1288    /**
1289     * Set if the systemServer made a call to enterSafeMode.
1290     */
1291    boolean mSafeMode;
1292
1293    /**
1294     * If true, we are running under a test environment so will sample PSS from processes
1295     * much more rapidly to try to collect better data when the tests are rapidly
1296     * running through apps.
1297     */
1298    boolean mTestPssMode = false;
1299
1300    String mDebugApp = null;
1301    boolean mWaitForDebugger = false;
1302    boolean mDebugTransient = false;
1303    String mOrigDebugApp = null;
1304    boolean mOrigWaitForDebugger = false;
1305    boolean mAlwaysFinishActivities = false;
1306    boolean mLenientBackgroundCheck = false;
1307    boolean mForceResizableActivities;
1308    boolean mSupportsMultiWindow;
1309    boolean mSupportsFreeformWindowManagement;
1310    boolean mSupportsPictureInPicture;
1311    Rect mDefaultPinnedStackBounds;
1312    IActivityController mController = null;
1313    boolean mControllerIsAMonkey = false;
1314    String mProfileApp = null;
1315    ProcessRecord mProfileProc = null;
1316    String mProfileFile;
1317    ParcelFileDescriptor mProfileFd;
1318    int mSamplingInterval = 0;
1319    boolean mAutoStopProfiler = false;
1320    int mProfileType = 0;
1321    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1322    String mMemWatchDumpProcName;
1323    String mMemWatchDumpFile;
1324    int mMemWatchDumpPid;
1325    int mMemWatchDumpUid;
1326    String mTrackAllocationApp = null;
1327    String mNativeDebuggingApp = null;
1328
1329    final long[] mTmpLong = new long[2];
1330
1331    static final class ProcessChangeItem {
1332        static final int CHANGE_ACTIVITIES = 1<<0;
1333        static final int CHANGE_PROCESS_STATE = 1<<1;
1334        int changes;
1335        int uid;
1336        int pid;
1337        int processState;
1338        boolean foregroundActivities;
1339    }
1340
1341    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1342    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1343
1344    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1345    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1346
1347    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1348    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1349
1350    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1351    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1352
1353    /**
1354     * Runtime CPU use collection thread.  This object's lock is used to
1355     * perform synchronization with the thread (notifying it to run).
1356     */
1357    final Thread mProcessCpuThread;
1358
1359    /**
1360     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1361     * Must acquire this object's lock when accessing it.
1362     * NOTE: this lock will be held while doing long operations (trawling
1363     * through all processes in /proc), so it should never be acquired by
1364     * any critical paths such as when holding the main activity manager lock.
1365     */
1366    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1367            MONITOR_THREAD_CPU_USAGE);
1368    final AtomicLong mLastCpuTime = new AtomicLong(0);
1369    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1370
1371    long mLastWriteTime = 0;
1372
1373    /**
1374     * Used to retain an update lock when the foreground activity is in
1375     * immersive mode.
1376     */
1377    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1378
1379    /**
1380     * Set to true after the system has finished booting.
1381     */
1382    boolean mBooted = false;
1383
1384    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1385    int mProcessLimitOverride = -1;
1386
1387    WindowManagerService mWindowManager;
1388    final ActivityThread mSystemThread;
1389
1390    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1391        final ProcessRecord mApp;
1392        final int mPid;
1393        final IApplicationThread mAppThread;
1394
1395        AppDeathRecipient(ProcessRecord app, int pid,
1396                IApplicationThread thread) {
1397            if (DEBUG_ALL) Slog.v(
1398                TAG, "New death recipient " + this
1399                + " for thread " + thread.asBinder());
1400            mApp = app;
1401            mPid = pid;
1402            mAppThread = thread;
1403        }
1404
1405        @Override
1406        public void binderDied() {
1407            if (DEBUG_ALL) Slog.v(
1408                TAG, "Death received in " + this
1409                + " for thread " + mAppThread.asBinder());
1410            synchronized(ActivityManagerService.this) {
1411                appDiedLocked(mApp, mPid, mAppThread, true);
1412            }
1413        }
1414    }
1415
1416    static final int SHOW_ERROR_UI_MSG = 1;
1417    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1418    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1419    static final int UPDATE_CONFIGURATION_MSG = 4;
1420    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1421    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1422    static final int SERVICE_TIMEOUT_MSG = 12;
1423    static final int UPDATE_TIME_ZONE = 13;
1424    static final int SHOW_UID_ERROR_UI_MSG = 14;
1425    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1426    static final int PROC_START_TIMEOUT_MSG = 20;
1427    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1428    static final int KILL_APPLICATION_MSG = 22;
1429    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1430    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1431    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1432    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1433    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1434    static final int CLEAR_DNS_CACHE_MSG = 28;
1435    static final int UPDATE_HTTP_PROXY_MSG = 29;
1436    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1437    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1438    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1439    static final int REPORT_MEM_USAGE_MSG = 33;
1440    static final int REPORT_USER_SWITCH_MSG = 34;
1441    static final int CONTINUE_USER_SWITCH_MSG = 35;
1442    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1443    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1444    static final int PERSIST_URI_GRANTS_MSG = 38;
1445    static final int REQUEST_ALL_PSS_MSG = 39;
1446    static final int START_PROFILES_MSG = 40;
1447    static final int UPDATE_TIME = 41;
1448    static final int SYSTEM_USER_START_MSG = 42;
1449    static final int SYSTEM_USER_CURRENT_MSG = 43;
1450    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1451    static final int FINISH_BOOTING_MSG = 45;
1452    static final int START_USER_SWITCH_UI_MSG = 46;
1453    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1454    static final int DISMISS_DIALOG_UI_MSG = 48;
1455    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1456    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1457    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1458    static final int DELETE_DUMPHEAP_MSG = 52;
1459    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1460    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1461    static final int REPORT_TIME_TRACKER_MSG = 55;
1462    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1463    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1464    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1465    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1466    static final int IDLE_UIDS_MSG = 60;
1467    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1468    static final int LOG_STACK_STATE = 62;
1469    static final int VR_MODE_CHANGE_MSG = 63;
1470    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1471    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1472    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1473    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1474    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1475
1476    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1477    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1478    static final int FIRST_COMPAT_MODE_MSG = 300;
1479    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1480
1481    static ServiceThread sKillThread = null;
1482    static KillHandler sKillHandler = null;
1483
1484    CompatModeDialog mCompatModeDialog;
1485    long mLastMemUsageReportTime = 0;
1486
1487    /**
1488     * Flag whether the current user is a "monkey", i.e. whether
1489     * the UI is driven by a UI automation tool.
1490     */
1491    private boolean mUserIsMonkey;
1492
1493    /** Flag whether the device has a Recents UI */
1494    boolean mHasRecents;
1495
1496    /** The dimensions of the thumbnails in the Recents UI. */
1497    int mThumbnailWidth;
1498    int mThumbnailHeight;
1499    float mFullscreenThumbnailScale;
1500
1501    final ServiceThread mHandlerThread;
1502    final MainHandler mHandler;
1503    final UiHandler mUiHandler;
1504
1505    PackageManagerInternal mPackageManagerInt;
1506
1507    final class KillHandler extends Handler {
1508        static final int KILL_PROCESS_GROUP_MSG = 4000;
1509
1510        public KillHandler(Looper looper) {
1511            super(looper, null, true);
1512        }
1513
1514        @Override
1515        public void handleMessage(Message msg) {
1516            switch (msg.what) {
1517                case KILL_PROCESS_GROUP_MSG:
1518                {
1519                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1520                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1521                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1522                }
1523                break;
1524
1525                default:
1526                    super.handleMessage(msg);
1527            }
1528        }
1529    }
1530
1531    final class UiHandler extends Handler {
1532        public UiHandler() {
1533            super(com.android.server.UiThread.get().getLooper(), null, true);
1534        }
1535
1536        @Override
1537        public void handleMessage(Message msg) {
1538            switch (msg.what) {
1539            case SHOW_ERROR_UI_MSG: {
1540                mAppErrors.handleShowAppErrorUi(msg);
1541                ensureBootCompleted();
1542            } break;
1543            case SHOW_NOT_RESPONDING_UI_MSG: {
1544                mAppErrors.handleShowAnrUi(msg);
1545                ensureBootCompleted();
1546            } break;
1547            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1548                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1549                synchronized (ActivityManagerService.this) {
1550                    ProcessRecord proc = (ProcessRecord) data.get("app");
1551                    if (proc == null) {
1552                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1553                        break;
1554                    }
1555                    if (proc.crashDialog != null) {
1556                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1557                        return;
1558                    }
1559                    AppErrorResult res = (AppErrorResult) data.get("result");
1560                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1561                        Dialog d = new StrictModeViolationDialog(mContext,
1562                                ActivityManagerService.this, res, proc);
1563                        d.show();
1564                        proc.crashDialog = d;
1565                    } else {
1566                        // The device is asleep, so just pretend that the user
1567                        // saw a crash dialog and hit "force quit".
1568                        res.set(0);
1569                    }
1570                }
1571                ensureBootCompleted();
1572            } break;
1573            case SHOW_FACTORY_ERROR_UI_MSG: {
1574                Dialog d = new FactoryErrorDialog(
1575                    mContext, msg.getData().getCharSequence("msg"));
1576                d.show();
1577                ensureBootCompleted();
1578            } break;
1579            case WAIT_FOR_DEBUGGER_UI_MSG: {
1580                synchronized (ActivityManagerService.this) {
1581                    ProcessRecord app = (ProcessRecord)msg.obj;
1582                    if (msg.arg1 != 0) {
1583                        if (!app.waitedForDebugger) {
1584                            Dialog d = new AppWaitingForDebuggerDialog(
1585                                    ActivityManagerService.this,
1586                                    mContext, app);
1587                            app.waitDialog = d;
1588                            app.waitedForDebugger = true;
1589                            d.show();
1590                        }
1591                    } else {
1592                        if (app.waitDialog != null) {
1593                            app.waitDialog.dismiss();
1594                            app.waitDialog = null;
1595                        }
1596                    }
1597                }
1598            } break;
1599            case SHOW_UID_ERROR_UI_MSG: {
1600                if (mShowDialogs) {
1601                    AlertDialog d = new BaseErrorDialog(mContext);
1602                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1603                    d.setCancelable(false);
1604                    d.setTitle(mContext.getText(R.string.android_system_label));
1605                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1606                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1607                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1608                    d.show();
1609                }
1610            } break;
1611            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1612                if (mShowDialogs) {
1613                    AlertDialog d = new BaseErrorDialog(mContext);
1614                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1615                    d.setCancelable(false);
1616                    d.setTitle(mContext.getText(R.string.android_system_label));
1617                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1618                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1619                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1620                    d.show();
1621                }
1622            } break;
1623            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1624                synchronized (ActivityManagerService.this) {
1625                    ActivityRecord ar = (ActivityRecord) msg.obj;
1626                    if (mCompatModeDialog != null) {
1627                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1628                                ar.info.applicationInfo.packageName)) {
1629                            return;
1630                        }
1631                        mCompatModeDialog.dismiss();
1632                        mCompatModeDialog = null;
1633                    }
1634                    if (ar != null && false) {
1635                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1636                                ar.packageName)) {
1637                            int mode = mCompatModePackages.computeCompatModeLocked(
1638                                    ar.info.applicationInfo);
1639                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1640                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1641                                mCompatModeDialog = new CompatModeDialog(
1642                                        ActivityManagerService.this, mContext,
1643                                        ar.info.applicationInfo);
1644                                mCompatModeDialog.show();
1645                            }
1646                        }
1647                    }
1648                }
1649                break;
1650            }
1651            case START_USER_SWITCH_UI_MSG: {
1652                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1653                break;
1654            }
1655            case DISMISS_DIALOG_UI_MSG: {
1656                final Dialog d = (Dialog) msg.obj;
1657                d.dismiss();
1658                break;
1659            }
1660            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1661                dispatchProcessesChanged();
1662                break;
1663            }
1664            case DISPATCH_PROCESS_DIED_UI_MSG: {
1665                final int pid = msg.arg1;
1666                final int uid = msg.arg2;
1667                dispatchProcessDied(pid, uid);
1668                break;
1669            }
1670            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1671                dispatchUidsChanged();
1672            } break;
1673            }
1674        }
1675    }
1676
1677    final class MainHandler extends Handler {
1678        public MainHandler(Looper looper) {
1679            super(looper, null, true);
1680        }
1681
1682        @Override
1683        public void handleMessage(Message msg) {
1684            switch (msg.what) {
1685            case UPDATE_CONFIGURATION_MSG: {
1686                final ContentResolver resolver = mContext.getContentResolver();
1687                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1688                        msg.arg1);
1689            } break;
1690            case GC_BACKGROUND_PROCESSES_MSG: {
1691                synchronized (ActivityManagerService.this) {
1692                    performAppGcsIfAppropriateLocked();
1693                }
1694            } break;
1695            case SERVICE_TIMEOUT_MSG: {
1696                if (mDidDexOpt) {
1697                    mDidDexOpt = false;
1698                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1699                    nmsg.obj = msg.obj;
1700                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1701                    return;
1702                }
1703                mServices.serviceTimeout((ProcessRecord)msg.obj);
1704            } break;
1705            case UPDATE_TIME_ZONE: {
1706                synchronized (ActivityManagerService.this) {
1707                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1708                        ProcessRecord r = mLruProcesses.get(i);
1709                        if (r.thread != null) {
1710                            try {
1711                                r.thread.updateTimeZone();
1712                            } catch (RemoteException ex) {
1713                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1714                            }
1715                        }
1716                    }
1717                }
1718            } break;
1719            case CLEAR_DNS_CACHE_MSG: {
1720                synchronized (ActivityManagerService.this) {
1721                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1722                        ProcessRecord r = mLruProcesses.get(i);
1723                        if (r.thread != null) {
1724                            try {
1725                                r.thread.clearDnsCache();
1726                            } catch (RemoteException ex) {
1727                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1728                            }
1729                        }
1730                    }
1731                }
1732            } break;
1733            case UPDATE_HTTP_PROXY_MSG: {
1734                ProxyInfo proxy = (ProxyInfo)msg.obj;
1735                String host = "";
1736                String port = "";
1737                String exclList = "";
1738                Uri pacFileUrl = Uri.EMPTY;
1739                if (proxy != null) {
1740                    host = proxy.getHost();
1741                    port = Integer.toString(proxy.getPort());
1742                    exclList = proxy.getExclusionListAsString();
1743                    pacFileUrl = proxy.getPacFileUrl();
1744                }
1745                synchronized (ActivityManagerService.this) {
1746                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1747                        ProcessRecord r = mLruProcesses.get(i);
1748                        if (r.thread != null) {
1749                            try {
1750                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1751                            } catch (RemoteException ex) {
1752                                Slog.w(TAG, "Failed to update http proxy for: " +
1753                                        r.info.processName);
1754                            }
1755                        }
1756                    }
1757                }
1758            } break;
1759            case PROC_START_TIMEOUT_MSG: {
1760                if (mDidDexOpt) {
1761                    mDidDexOpt = false;
1762                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1763                    nmsg.obj = msg.obj;
1764                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1765                    return;
1766                }
1767                ProcessRecord app = (ProcessRecord)msg.obj;
1768                synchronized (ActivityManagerService.this) {
1769                    processStartTimedOutLocked(app);
1770                }
1771            } break;
1772            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1773                ProcessRecord app = (ProcessRecord)msg.obj;
1774                synchronized (ActivityManagerService.this) {
1775                    processContentProviderPublishTimedOutLocked(app);
1776                }
1777            } break;
1778            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1779                synchronized (ActivityManagerService.this) {
1780                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1781                }
1782            } break;
1783            case KILL_APPLICATION_MSG: {
1784                synchronized (ActivityManagerService.this) {
1785                    int appid = msg.arg1;
1786                    boolean restart = (msg.arg2 == 1);
1787                    Bundle bundle = (Bundle)msg.obj;
1788                    String pkg = bundle.getString("pkg");
1789                    String reason = bundle.getString("reason");
1790                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1791                            false, UserHandle.USER_ALL, reason);
1792                }
1793            } break;
1794            case FINALIZE_PENDING_INTENT_MSG: {
1795                ((PendingIntentRecord)msg.obj).completeFinalize();
1796            } break;
1797            case POST_HEAVY_NOTIFICATION_MSG: {
1798                INotificationManager inm = NotificationManager.getService();
1799                if (inm == null) {
1800                    return;
1801                }
1802
1803                ActivityRecord root = (ActivityRecord)msg.obj;
1804                ProcessRecord process = root.app;
1805                if (process == null) {
1806                    return;
1807                }
1808
1809                try {
1810                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1811                    String text = mContext.getString(R.string.heavy_weight_notification,
1812                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1813                    Notification notification = new Notification.Builder(context)
1814                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1815                            .setWhen(0)
1816                            .setOngoing(true)
1817                            .setTicker(text)
1818                            .setColor(mContext.getColor(
1819                                    com.android.internal.R.color.system_notification_accent_color))
1820                            .setContentTitle(text)
1821                            .setContentText(
1822                                    mContext.getText(R.string.heavy_weight_notification_detail))
1823                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1824                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1825                                    new UserHandle(root.userId)))
1826                            .build();
1827                    try {
1828                        int[] outId = new int[1];
1829                        inm.enqueueNotificationWithTag("android", "android", null,
1830                                R.string.heavy_weight_notification,
1831                                notification, outId, root.userId);
1832                    } catch (RuntimeException e) {
1833                        Slog.w(ActivityManagerService.TAG,
1834                                "Error showing notification for heavy-weight app", e);
1835                    } catch (RemoteException e) {
1836                    }
1837                } catch (NameNotFoundException e) {
1838                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1839                }
1840            } break;
1841            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1842                INotificationManager inm = NotificationManager.getService();
1843                if (inm == null) {
1844                    return;
1845                }
1846                try {
1847                    inm.cancelNotificationWithTag("android", null,
1848                            R.string.heavy_weight_notification,  msg.arg1);
1849                } catch (RuntimeException e) {
1850                    Slog.w(ActivityManagerService.TAG,
1851                            "Error canceling notification for service", e);
1852                } catch (RemoteException e) {
1853                }
1854            } break;
1855            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    checkExcessivePowerUsageLocked(true);
1858                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1859                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1860                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1861                }
1862            } break;
1863            case REPORT_MEM_USAGE_MSG: {
1864                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1865                Thread thread = new Thread() {
1866                    @Override public void run() {
1867                        reportMemUsage(memInfos);
1868                    }
1869                };
1870                thread.start();
1871                break;
1872            }
1873            case REPORT_USER_SWITCH_MSG: {
1874                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1875                break;
1876            }
1877            case CONTINUE_USER_SWITCH_MSG: {
1878                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1879                break;
1880            }
1881            case USER_SWITCH_TIMEOUT_MSG: {
1882                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1883                break;
1884            }
1885            case IMMERSIVE_MODE_LOCK_MSG: {
1886                final boolean nextState = (msg.arg1 != 0);
1887                if (mUpdateLock.isHeld() != nextState) {
1888                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1889                            "Applying new update lock state '" + nextState
1890                            + "' for " + (ActivityRecord)msg.obj);
1891                    if (nextState) {
1892                        mUpdateLock.acquire();
1893                    } else {
1894                        mUpdateLock.release();
1895                    }
1896                }
1897                break;
1898            }
1899            case PERSIST_URI_GRANTS_MSG: {
1900                writeGrantedUriPermissions();
1901                break;
1902            }
1903            case REQUEST_ALL_PSS_MSG: {
1904                synchronized (ActivityManagerService.this) {
1905                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1906                }
1907                break;
1908            }
1909            case START_PROFILES_MSG: {
1910                synchronized (ActivityManagerService.this) {
1911                    mUserController.startProfilesLocked();
1912                }
1913                break;
1914            }
1915            case UPDATE_TIME: {
1916                synchronized (ActivityManagerService.this) {
1917                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1918                        ProcessRecord r = mLruProcesses.get(i);
1919                        if (r.thread != null) {
1920                            try {
1921                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1922                            } catch (RemoteException ex) {
1923                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1924                            }
1925                        }
1926                    }
1927                }
1928                break;
1929            }
1930            case SYSTEM_USER_START_MSG: {
1931                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1932                        Integer.toString(msg.arg1), msg.arg1);
1933                mSystemServiceManager.startUser(msg.arg1);
1934                break;
1935            }
1936            case SYSTEM_USER_UNLOCK_MSG: {
1937                final int userId = msg.arg1;
1938                mSystemServiceManager.unlockUser(userId);
1939                synchronized (ActivityManagerService.this) {
1940                    mRecentTasks.loadUserRecentsLocked(userId);
1941                }
1942                if (userId == UserHandle.USER_SYSTEM) {
1943                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1944                }
1945                installEncryptionUnawareProviders(userId);
1946                break;
1947            }
1948            case SYSTEM_USER_CURRENT_MSG: {
1949                mBatteryStatsService.noteEvent(
1950                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1951                        Integer.toString(msg.arg2), msg.arg2);
1952                mBatteryStatsService.noteEvent(
1953                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1954                        Integer.toString(msg.arg1), msg.arg1);
1955                mSystemServiceManager.switchUser(msg.arg1);
1956                break;
1957            }
1958            case ENTER_ANIMATION_COMPLETE_MSG: {
1959                synchronized (ActivityManagerService.this) {
1960                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1961                    if (r != null && r.app != null && r.app.thread != null) {
1962                        try {
1963                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1964                        } catch (RemoteException e) {
1965                        }
1966                    }
1967                }
1968                break;
1969            }
1970            case FINISH_BOOTING_MSG: {
1971                if (msg.arg1 != 0) {
1972                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1973                    finishBooting();
1974                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1975                }
1976                if (msg.arg2 != 0) {
1977                    enableScreenAfterBoot();
1978                }
1979                break;
1980            }
1981            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1982                try {
1983                    Locale l = (Locale) msg.obj;
1984                    IBinder service = ServiceManager.getService("mount");
1985                    IMountService mountService = IMountService.Stub.asInterface(service);
1986                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1987                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1988                } catch (RemoteException e) {
1989                    Log.e(TAG, "Error storing locale for decryption UI", e);
1990                }
1991                break;
1992            }
1993            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1994                synchronized (ActivityManagerService.this) {
1995                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1996                        try {
1997                            // Make a one-way callback to the listener
1998                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1999                        } catch (RemoteException e){
2000                            // Handled by the RemoteCallbackList
2001                        }
2002                    }
2003                    mTaskStackListeners.finishBroadcast();
2004                }
2005                break;
2006            }
2007            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2010                        try {
2011                            // Make a one-way callback to the listener
2012                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2013                        } catch (RemoteException e){
2014                            // Handled by the RemoteCallbackList
2015                        }
2016                    }
2017                    mTaskStackListeners.finishBroadcast();
2018                }
2019                break;
2020            }
2021            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2022                synchronized (ActivityManagerService.this) {
2023                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2024                        try {
2025                            // Make a one-way callback to the listener
2026                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2027                        } catch (RemoteException e){
2028                            // Handled by the RemoteCallbackList
2029                        }
2030                    }
2031                    mTaskStackListeners.finishBroadcast();
2032                }
2033                break;
2034            }
2035            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_FORCED_RESIZABLE_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2055                                    (String) msg.obj, msg.arg1);
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2065                    synchronized (ActivityManagerService.this) {
2066                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                            try {
2068                                // Make a one-way callback to the listener
2069                                mTaskStackListeners.getBroadcastItem(i)
2070                                        .onActivityDismissingDockedStack();
2071                            } catch (RemoteException e){
2072                                // Handled by the RemoteCallbackList
2073                            }
2074                        }
2075                        mTaskStackListeners.finishBroadcast();
2076                    }
2077                    break;
2078                }
2079            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2080                final int uid = msg.arg1;
2081                final byte[] firstPacket = (byte[]) msg.obj;
2082
2083                synchronized (mPidsSelfLocked) {
2084                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2085                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2086                        if (p.uid == uid) {
2087                            try {
2088                                p.thread.notifyCleartextNetwork(firstPacket);
2089                            } catch (RemoteException ignored) {
2090                            }
2091                        }
2092                    }
2093                }
2094                break;
2095            }
2096            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2097                final String procName;
2098                final int uid;
2099                final long memLimit;
2100                final String reportPackage;
2101                synchronized (ActivityManagerService.this) {
2102                    procName = mMemWatchDumpProcName;
2103                    uid = mMemWatchDumpUid;
2104                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2105                    if (val == null) {
2106                        val = mMemWatchProcesses.get(procName, 0);
2107                    }
2108                    if (val != null) {
2109                        memLimit = val.first;
2110                        reportPackage = val.second;
2111                    } else {
2112                        memLimit = 0;
2113                        reportPackage = null;
2114                    }
2115                }
2116                if (procName == null) {
2117                    return;
2118                }
2119
2120                if (DEBUG_PSS) Slog.d(TAG_PSS,
2121                        "Showing dump heap notification from " + procName + "/" + uid);
2122
2123                INotificationManager inm = NotificationManager.getService();
2124                if (inm == null) {
2125                    return;
2126                }
2127
2128                String text = mContext.getString(R.string.dump_heap_notification, procName);
2129
2130
2131                Intent deleteIntent = new Intent();
2132                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2133                Intent intent = new Intent();
2134                intent.setClassName("android", DumpHeapActivity.class.getName());
2135                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2136                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2137                if (reportPackage != null) {
2138                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2139                }
2140                int userId = UserHandle.getUserId(uid);
2141                Notification notification = new Notification.Builder(mContext)
2142                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2143                        .setWhen(0)
2144                        .setOngoing(true)
2145                        .setAutoCancel(true)
2146                        .setTicker(text)
2147                        .setColor(mContext.getColor(
2148                                com.android.internal.R.color.system_notification_accent_color))
2149                        .setContentTitle(text)
2150                        .setContentText(
2151                                mContext.getText(R.string.dump_heap_notification_detail))
2152                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2153                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2154                                new UserHandle(userId)))
2155                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2156                                deleteIntent, 0, UserHandle.SYSTEM))
2157                        .build();
2158
2159                try {
2160                    int[] outId = new int[1];
2161                    inm.enqueueNotificationWithTag("android", "android", null,
2162                            R.string.dump_heap_notification,
2163                            notification, outId, userId);
2164                } catch (RuntimeException e) {
2165                    Slog.w(ActivityManagerService.TAG,
2166                            "Error showing notification for dump heap", e);
2167                } catch (RemoteException e) {
2168                }
2169            } break;
2170            case DELETE_DUMPHEAP_MSG: {
2171                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2172                        DumpHeapActivity.JAVA_URI,
2173                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2174                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2175                        UserHandle.myUserId());
2176                synchronized (ActivityManagerService.this) {
2177                    mMemWatchDumpFile = null;
2178                    mMemWatchDumpProcName = null;
2179                    mMemWatchDumpPid = -1;
2180                    mMemWatchDumpUid = -1;
2181                }
2182            } break;
2183            case FOREGROUND_PROFILE_CHANGED_MSG: {
2184                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2185            } break;
2186            case REPORT_TIME_TRACKER_MSG: {
2187                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2188                tracker.deliverResult(mContext);
2189            } break;
2190            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2191                mUserController.dispatchUserSwitchComplete(msg.arg1);
2192            } break;
2193            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2194                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2195                try {
2196                    connection.shutdown();
2197                } catch (RemoteException e) {
2198                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2199                }
2200                // Only a UiAutomation can set this flag and now that
2201                // it is finished we make sure it is reset to its default.
2202                mUserIsMonkey = false;
2203            } break;
2204            case APP_BOOST_DEACTIVATE_MSG: {
2205                synchronized(ActivityManagerService.this) {
2206                    if (mIsBoosted) {
2207                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2208                            nativeMigrateFromBoost();
2209                            mIsBoosted = false;
2210                            mBoostStartTime = 0;
2211                        } else {
2212                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2213                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2214                        }
2215                    }
2216                }
2217            } break;
2218            case IDLE_UIDS_MSG: {
2219                idleUids();
2220            } break;
2221            case LOG_STACK_STATE: {
2222                synchronized (ActivityManagerService.this) {
2223                    mStackSupervisor.logStackState();
2224                }
2225            } break;
2226            case VR_MODE_CHANGE_MSG: {
2227                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2228                final ActivityRecord r = (ActivityRecord) msg.obj;
2229                boolean vrMode;
2230                ComponentName requestedPackage;
2231                ComponentName callingPackage;
2232                int userId;
2233                synchronized (ActivityManagerService.this) {
2234                    vrMode = r.requestedVrComponent != null;
2235                    requestedPackage = r.requestedVrComponent;
2236                    userId = r.userId;
2237                    callingPackage = r.info.getComponentName();
2238                    if (mInVrMode != vrMode) {
2239                        mInVrMode = vrMode;
2240                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2241                    }
2242                }
2243                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2244            } break;
2245            }
2246        }
2247    };
2248
2249    static final int COLLECT_PSS_BG_MSG = 1;
2250
2251    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2252        @Override
2253        public void handleMessage(Message msg) {
2254            switch (msg.what) {
2255            case COLLECT_PSS_BG_MSG: {
2256                long start = SystemClock.uptimeMillis();
2257                MemInfoReader memInfo = null;
2258                synchronized (ActivityManagerService.this) {
2259                    if (mFullPssPending) {
2260                        mFullPssPending = false;
2261                        memInfo = new MemInfoReader();
2262                    }
2263                }
2264                if (memInfo != null) {
2265                    updateCpuStatsNow();
2266                    long nativeTotalPss = 0;
2267                    synchronized (mProcessCpuTracker) {
2268                        final int N = mProcessCpuTracker.countStats();
2269                        for (int j=0; j<N; j++) {
2270                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2271                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2272                                // This is definitely an application process; skip it.
2273                                continue;
2274                            }
2275                            synchronized (mPidsSelfLocked) {
2276                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2277                                    // This is one of our own processes; skip it.
2278                                    continue;
2279                                }
2280                            }
2281                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2282                        }
2283                    }
2284                    memInfo.readMemInfo();
2285                    synchronized (ActivityManagerService.this) {
2286                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2287                                + (SystemClock.uptimeMillis()-start) + "ms");
2288                        final long cachedKb = memInfo.getCachedSizeKb();
2289                        final long freeKb = memInfo.getFreeSizeKb();
2290                        final long zramKb = memInfo.getZramTotalSizeKb();
2291                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2292                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2293                                kernelKb*1024, nativeTotalPss*1024);
2294                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2295                                nativeTotalPss);
2296                    }
2297                }
2298
2299                int num = 0;
2300                long[] tmp = new long[2];
2301                do {
2302                    ProcessRecord proc;
2303                    int procState;
2304                    int pid;
2305                    long lastPssTime;
2306                    synchronized (ActivityManagerService.this) {
2307                        if (mPendingPssProcesses.size() <= 0) {
2308                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2309                                    "Collected PSS of " + num + " processes in "
2310                                    + (SystemClock.uptimeMillis() - start) + "ms");
2311                            mPendingPssProcesses.clear();
2312                            return;
2313                        }
2314                        proc = mPendingPssProcesses.remove(0);
2315                        procState = proc.pssProcState;
2316                        lastPssTime = proc.lastPssTime;
2317                        if (proc.thread != null && procState == proc.setProcState
2318                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2319                                        < SystemClock.uptimeMillis()) {
2320                            pid = proc.pid;
2321                        } else {
2322                            proc = null;
2323                            pid = 0;
2324                        }
2325                    }
2326                    if (proc != null) {
2327                        long pss = Debug.getPss(pid, tmp, null);
2328                        synchronized (ActivityManagerService.this) {
2329                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2330                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2331                                num++;
2332                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2333                                        SystemClock.uptimeMillis());
2334                            }
2335                        }
2336                    }
2337                } while (true);
2338            }
2339            }
2340        }
2341    };
2342
2343    public void setSystemProcess() {
2344        try {
2345            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2346            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2347            ServiceManager.addService("meminfo", new MemBinder(this));
2348            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2349            ServiceManager.addService("dbinfo", new DbBinder(this));
2350            if (MONITOR_CPU_USAGE) {
2351                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2352            }
2353            ServiceManager.addService("permission", new PermissionController(this));
2354            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2355
2356            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2357                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2358            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2359
2360            synchronized (this) {
2361                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2362                app.persistent = true;
2363                app.pid = MY_PID;
2364                app.maxAdj = ProcessList.SYSTEM_ADJ;
2365                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2366                synchronized (mPidsSelfLocked) {
2367                    mPidsSelfLocked.put(app.pid, app);
2368                }
2369                updateLruProcessLocked(app, false, null);
2370                updateOomAdjLocked();
2371            }
2372        } catch (PackageManager.NameNotFoundException e) {
2373            throw new RuntimeException(
2374                    "Unable to find android system package", e);
2375        }
2376    }
2377
2378    public void setWindowManager(WindowManagerService wm) {
2379        mWindowManager = wm;
2380        mStackSupervisor.setWindowManager(wm);
2381        mActivityStarter.setWindowManager(wm);
2382    }
2383
2384    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2385        mUsageStatsService = usageStatsManager;
2386    }
2387
2388    public void startObservingNativeCrashes() {
2389        final NativeCrashListener ncl = new NativeCrashListener(this);
2390        ncl.start();
2391    }
2392
2393    public IAppOpsService getAppOpsService() {
2394        return mAppOpsService;
2395    }
2396
2397    static class MemBinder extends Binder {
2398        ActivityManagerService mActivityManagerService;
2399        MemBinder(ActivityManagerService activityManagerService) {
2400            mActivityManagerService = activityManagerService;
2401        }
2402
2403        @Override
2404        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2405            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2406                    != PackageManager.PERMISSION_GRANTED) {
2407                pw.println("Permission Denial: can't dump meminfo from from pid="
2408                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2409                        + " without permission " + android.Manifest.permission.DUMP);
2410                return;
2411            }
2412
2413            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2414        }
2415    }
2416
2417    static class GraphicsBinder extends Binder {
2418        ActivityManagerService mActivityManagerService;
2419        GraphicsBinder(ActivityManagerService activityManagerService) {
2420            mActivityManagerService = activityManagerService;
2421        }
2422
2423        @Override
2424        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2425            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2426                    != PackageManager.PERMISSION_GRANTED) {
2427                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2428                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2429                        + " without permission " + android.Manifest.permission.DUMP);
2430                return;
2431            }
2432
2433            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2434        }
2435    }
2436
2437    static class DbBinder extends Binder {
2438        ActivityManagerService mActivityManagerService;
2439        DbBinder(ActivityManagerService activityManagerService) {
2440            mActivityManagerService = activityManagerService;
2441        }
2442
2443        @Override
2444        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2445            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2446                    != PackageManager.PERMISSION_GRANTED) {
2447                pw.println("Permission Denial: can't dump dbinfo from from pid="
2448                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2449                        + " without permission " + android.Manifest.permission.DUMP);
2450                return;
2451            }
2452
2453            mActivityManagerService.dumpDbInfo(fd, pw, args);
2454        }
2455    }
2456
2457    static class CpuBinder extends Binder {
2458        ActivityManagerService mActivityManagerService;
2459        CpuBinder(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 cpuinfo from from pid="
2468                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2469                        + " without permission " + android.Manifest.permission.DUMP);
2470                return;
2471            }
2472
2473            synchronized (mActivityManagerService.mProcessCpuTracker) {
2474                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2475                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2476                        SystemClock.uptimeMillis()));
2477            }
2478        }
2479    }
2480
2481    public static final class Lifecycle extends SystemService {
2482        private final ActivityManagerService mService;
2483
2484        public Lifecycle(Context context) {
2485            super(context);
2486            mService = new ActivityManagerService(context);
2487        }
2488
2489        @Override
2490        public void onStart() {
2491            mService.start();
2492        }
2493
2494        public ActivityManagerService getService() {
2495            return mService;
2496        }
2497    }
2498
2499    // Note: This method is invoked on the main thread but may need to attach various
2500    // handlers to other threads.  So take care to be explicit about the looper.
2501    public ActivityManagerService(Context systemContext) {
2502        mContext = systemContext;
2503        mFactoryTest = FactoryTest.getMode();
2504        mSystemThread = ActivityThread.currentActivityThread();
2505
2506        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2507
2508        mHandlerThread = new ServiceThread(TAG,
2509                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2510        mHandlerThread.start();
2511        mHandler = new MainHandler(mHandlerThread.getLooper());
2512        mUiHandler = new UiHandler();
2513
2514        /* static; one-time init here */
2515        if (sKillHandler == null) {
2516            sKillThread = new ServiceThread(TAG + ":kill",
2517                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2518            sKillThread.start();
2519            sKillHandler = new KillHandler(sKillThread.getLooper());
2520        }
2521
2522        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2523                "foreground", BROADCAST_FG_TIMEOUT, false);
2524        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2525                "background", BROADCAST_BG_TIMEOUT, true);
2526        mBroadcastQueues[0] = mFgBroadcastQueue;
2527        mBroadcastQueues[1] = mBgBroadcastQueue;
2528
2529        mServices = new ActiveServices(this);
2530        mProviderMap = new ProviderMap(this);
2531        mAppErrors = new AppErrors(mContext, this);
2532
2533        // TODO: Move creation of battery stats service outside of activity manager service.
2534        File dataDir = Environment.getDataDirectory();
2535        File systemDir = new File(dataDir, "system");
2536        systemDir.mkdirs();
2537        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2538        mBatteryStatsService.getActiveStatistics().readLocked();
2539        mBatteryStatsService.scheduleWriteToDisk();
2540        mOnBattery = DEBUG_POWER ? true
2541                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2542        mBatteryStatsService.getActiveStatistics().setCallback(this);
2543
2544        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2545
2546        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2547        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2548                new IAppOpsCallback.Stub() {
2549                    @Override public void opChanged(int op, int uid, String packageName) {
2550                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2551                            if (mAppOpsService.checkOperation(op, uid, packageName)
2552                                    != AppOpsManager.MODE_ALLOWED) {
2553                                runInBackgroundDisabled(uid);
2554                            }
2555                        }
2556                    }
2557                });
2558
2559        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2560
2561        mUserController = new UserController(this);
2562
2563        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2564            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2565
2566        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2567
2568        mConfiguration.setToDefaults();
2569        mConfiguration.setLocales(LocaleList.getDefault());
2570
2571        mConfigurationSeq = mConfiguration.seq = 1;
2572        mProcessCpuTracker.init();
2573
2574        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2575        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2576        mStackSupervisor = new ActivityStackSupervisor(this);
2577        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2578        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2579
2580        mProcessCpuThread = new Thread("CpuTracker") {
2581            @Override
2582            public void run() {
2583                while (true) {
2584                    try {
2585                        try {
2586                            synchronized(this) {
2587                                final long now = SystemClock.uptimeMillis();
2588                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2589                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2590                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2591                                //        + ", write delay=" + nextWriteDelay);
2592                                if (nextWriteDelay < nextCpuDelay) {
2593                                    nextCpuDelay = nextWriteDelay;
2594                                }
2595                                if (nextCpuDelay > 0) {
2596                                    mProcessCpuMutexFree.set(true);
2597                                    this.wait(nextCpuDelay);
2598                                }
2599                            }
2600                        } catch (InterruptedException e) {
2601                        }
2602                        updateCpuStatsNow();
2603                    } catch (Exception e) {
2604                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2605                    }
2606                }
2607            }
2608        };
2609
2610        Watchdog.getInstance().addMonitor(this);
2611        Watchdog.getInstance().addThread(mHandler);
2612    }
2613
2614    public void setSystemServiceManager(SystemServiceManager mgr) {
2615        mSystemServiceManager = mgr;
2616    }
2617
2618    public void setInstaller(Installer installer) {
2619        mInstaller = installer;
2620    }
2621
2622    private void start() {
2623        Process.removeAllProcessGroups();
2624        mProcessCpuThread.start();
2625
2626        mBatteryStatsService.publish(mContext);
2627        mAppOpsService.publish(mContext);
2628        Slog.d("AppOps", "AppOpsService published");
2629        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2630    }
2631
2632    void onUserStoppedLocked(int userId) {
2633        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2634    }
2635
2636    public void initPowerManagement() {
2637        mStackSupervisor.initPowerManagement();
2638        mBatteryStatsService.initPowerManagement();
2639        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2640        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2641        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2642        mVoiceWakeLock.setReferenceCounted(false);
2643    }
2644
2645    @Override
2646    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2647            throws RemoteException {
2648        if (code == SYSPROPS_TRANSACTION) {
2649            // We need to tell all apps about the system property change.
2650            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2651            synchronized(this) {
2652                final int NP = mProcessNames.getMap().size();
2653                for (int ip=0; ip<NP; ip++) {
2654                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2655                    final int NA = apps.size();
2656                    for (int ia=0; ia<NA; ia++) {
2657                        ProcessRecord app = apps.valueAt(ia);
2658                        if (app.thread != null) {
2659                            procs.add(app.thread.asBinder());
2660                        }
2661                    }
2662                }
2663            }
2664
2665            int N = procs.size();
2666            for (int i=0; i<N; i++) {
2667                Parcel data2 = Parcel.obtain();
2668                try {
2669                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2670                } catch (RemoteException e) {
2671                }
2672                data2.recycle();
2673            }
2674        }
2675        try {
2676            return super.onTransact(code, data, reply, flags);
2677        } catch (RuntimeException e) {
2678            // The activity manager only throws security exceptions, so let's
2679            // log all others.
2680            if (!(e instanceof SecurityException)) {
2681                Slog.wtf(TAG, "Activity Manager Crash", e);
2682            }
2683            throw e;
2684        }
2685    }
2686
2687    void updateCpuStats() {
2688        final long now = SystemClock.uptimeMillis();
2689        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2690            return;
2691        }
2692        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2693            synchronized (mProcessCpuThread) {
2694                mProcessCpuThread.notify();
2695            }
2696        }
2697    }
2698
2699    void updateCpuStatsNow() {
2700        synchronized (mProcessCpuTracker) {
2701            mProcessCpuMutexFree.set(false);
2702            final long now = SystemClock.uptimeMillis();
2703            boolean haveNewCpuStats = false;
2704
2705            if (MONITOR_CPU_USAGE &&
2706                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2707                mLastCpuTime.set(now);
2708                mProcessCpuTracker.update();
2709                if (mProcessCpuTracker.hasGoodLastStats()) {
2710                    haveNewCpuStats = true;
2711                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2712                    //Slog.i(TAG, "Total CPU usage: "
2713                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2714
2715                    // Slog the cpu usage if the property is set.
2716                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2717                        int user = mProcessCpuTracker.getLastUserTime();
2718                        int system = mProcessCpuTracker.getLastSystemTime();
2719                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2720                        int irq = mProcessCpuTracker.getLastIrqTime();
2721                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2722                        int idle = mProcessCpuTracker.getLastIdleTime();
2723
2724                        int total = user + system + iowait + irq + softIrq + idle;
2725                        if (total == 0) total = 1;
2726
2727                        EventLog.writeEvent(EventLogTags.CPU,
2728                                ((user+system+iowait+irq+softIrq) * 100) / total,
2729                                (user * 100) / total,
2730                                (system * 100) / total,
2731                                (iowait * 100) / total,
2732                                (irq * 100) / total,
2733                                (softIrq * 100) / total);
2734                    }
2735                }
2736            }
2737
2738            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2739            synchronized(bstats) {
2740                synchronized(mPidsSelfLocked) {
2741                    if (haveNewCpuStats) {
2742                        if (bstats.startAddingCpuLocked()) {
2743                            int totalUTime = 0;
2744                            int totalSTime = 0;
2745                            final int N = mProcessCpuTracker.countStats();
2746                            for (int i=0; i<N; i++) {
2747                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2748                                if (!st.working) {
2749                                    continue;
2750                                }
2751                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2752                                totalUTime += st.rel_utime;
2753                                totalSTime += st.rel_stime;
2754                                if (pr != null) {
2755                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2756                                    if (ps == null || !ps.isActive()) {
2757                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2758                                                pr.info.uid, pr.processName);
2759                                    }
2760                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2761                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2762                                } else {
2763                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2764                                    if (ps == null || !ps.isActive()) {
2765                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2766                                                bstats.mapUid(st.uid), st.name);
2767                                    }
2768                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2769                                }
2770                            }
2771                            final int userTime = mProcessCpuTracker.getLastUserTime();
2772                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2773                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2774                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2775                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2776                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2777                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2778                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2779                        }
2780                    }
2781                }
2782
2783                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2784                    mLastWriteTime = now;
2785                    mBatteryStatsService.scheduleWriteToDisk();
2786                }
2787            }
2788        }
2789    }
2790
2791    @Override
2792    public void batteryNeedsCpuUpdate() {
2793        updateCpuStatsNow();
2794    }
2795
2796    @Override
2797    public void batteryPowerChanged(boolean onBattery) {
2798        // When plugging in, update the CPU stats first before changing
2799        // the plug state.
2800        updateCpuStatsNow();
2801        synchronized (this) {
2802            synchronized(mPidsSelfLocked) {
2803                mOnBattery = DEBUG_POWER ? true : onBattery;
2804            }
2805        }
2806    }
2807
2808    @Override
2809    public void batterySendBroadcast(Intent intent) {
2810        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2811                AppOpsManager.OP_NONE, null, false, false,
2812                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2813    }
2814
2815    /**
2816     * Initialize the application bind args. These are passed to each
2817     * process when the bindApplication() IPC is sent to the process. They're
2818     * lazily setup to make sure the services are running when they're asked for.
2819     */
2820    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2821        if (mAppBindArgs == null) {
2822            mAppBindArgs = new HashMap<>();
2823
2824            // Isolated processes won't get this optimization, so that we don't
2825            // violate the rules about which services they have access to.
2826            if (!isolated) {
2827                // Setup the application init args
2828                mAppBindArgs.put("package", ServiceManager.getService("package"));
2829                mAppBindArgs.put("window", ServiceManager.getService("window"));
2830                mAppBindArgs.put(Context.ALARM_SERVICE,
2831                        ServiceManager.getService(Context.ALARM_SERVICE));
2832            }
2833        }
2834        return mAppBindArgs;
2835    }
2836
2837    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2838        if (r == null || mFocusedActivity == r) {
2839            return false;
2840        }
2841
2842        if (!r.isFocusable()) {
2843            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2844            return false;
2845        }
2846
2847        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2848
2849        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2850        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2851                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2852        mDoingSetFocusedActivity = true;
2853
2854        final ActivityRecord last = mFocusedActivity;
2855        mFocusedActivity = r;
2856        if (r.task.isApplicationTask()) {
2857            if (mCurAppTimeTracker != r.appTimeTracker) {
2858                // We are switching app tracking.  Complete the current one.
2859                if (mCurAppTimeTracker != null) {
2860                    mCurAppTimeTracker.stop();
2861                    mHandler.obtainMessage(
2862                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2863                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2864                    mCurAppTimeTracker = null;
2865                }
2866                if (r.appTimeTracker != null) {
2867                    mCurAppTimeTracker = r.appTimeTracker;
2868                    startTimeTrackingFocusedActivityLocked();
2869                }
2870            } else {
2871                startTimeTrackingFocusedActivityLocked();
2872            }
2873        } else {
2874            r.appTimeTracker = null;
2875        }
2876        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2877        // TODO: Probably not, because we don't want to resume voice on switching
2878        // back to this activity
2879        if (r.task.voiceInteractor != null) {
2880            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2881        } else {
2882            finishRunningVoiceLocked();
2883            IVoiceInteractionSession session;
2884            if (last != null && ((session = last.task.voiceSession) != null
2885                    || (session = last.voiceSession) != null)) {
2886                // We had been in a voice interaction session, but now focused has
2887                // move to something different.  Just finish the session, we can't
2888                // return to it and retain the proper state and synchronization with
2889                // the voice interaction service.
2890                finishVoiceTask(session);
2891            }
2892        }
2893        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2894            mWindowManager.setFocusedApp(r.appToken, true);
2895        }
2896        applyUpdateLockStateLocked(r);
2897        applyUpdateVrModeLocked(r);
2898        if (mFocusedActivity.userId != mLastFocusedUserId) {
2899            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2900            mHandler.obtainMessage(
2901                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2902            mLastFocusedUserId = mFocusedActivity.userId;
2903        }
2904
2905        // Log a warning if the focused app is changed during the process. This could
2906        // indicate a problem of the focus setting logic!
2907        if (mFocusedActivity != r) Slog.w(TAG,
2908                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2909        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2910
2911        EventLogTags.writeAmFocusedActivity(
2912                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2913                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2914                reason);
2915        return true;
2916    }
2917
2918    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2919        if (mFocusedActivity != goingAway) {
2920            return;
2921        }
2922
2923        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2924        if (focusedStack != null) {
2925            final ActivityRecord top = focusedStack.topActivity();
2926            if (top != null && top.userId != mLastFocusedUserId) {
2927                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2928                mHandler.sendMessage(
2929                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2930                mLastFocusedUserId = top.userId;
2931            }
2932        }
2933
2934        // Try to move focus to another activity if possible.
2935        if (setFocusedActivityLocked(
2936                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2937            return;
2938        }
2939
2940        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2941                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2942        mFocusedActivity = null;
2943        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2944    }
2945
2946    @Override
2947    public void setFocusedStack(int stackId) {
2948        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2949        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2950        final long callingId = Binder.clearCallingIdentity();
2951        try {
2952            synchronized (this) {
2953                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2954                if (stack == null) {
2955                    return;
2956                }
2957                final ActivityRecord r = stack.topRunningActivityLocked();
2958                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2959                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2960                }
2961            }
2962        } finally {
2963            Binder.restoreCallingIdentity(callingId);
2964        }
2965    }
2966
2967    @Override
2968    public void setFocusedTask(int taskId) {
2969        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2970        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2971        final long callingId = Binder.clearCallingIdentity();
2972        try {
2973            synchronized (this) {
2974                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2975                if (task == null) {
2976                    return;
2977                }
2978                final ActivityRecord r = task.topRunningActivityLocked();
2979                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2980                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2981                }
2982            }
2983        } finally {
2984            Binder.restoreCallingIdentity(callingId);
2985        }
2986    }
2987
2988    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2989    @Override
2990    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2992        synchronized (this) {
2993            if (listener != null) {
2994                mTaskStackListeners.register(listener);
2995            }
2996        }
2997    }
2998
2999    @Override
3000    public void notifyActivityDrawn(IBinder token) {
3001        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3002        synchronized (this) {
3003            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3004            if (r != null) {
3005                r.task.stack.notifyActivityDrawnLocked(r);
3006            }
3007        }
3008    }
3009
3010    final void applyUpdateLockStateLocked(ActivityRecord r) {
3011        // Modifications to the UpdateLock state are done on our handler, outside
3012        // the activity manager's locks.  The new state is determined based on the
3013        // state *now* of the relevant activity record.  The object is passed to
3014        // the handler solely for logging detail, not to be consulted/modified.
3015        final boolean nextState = r != null && r.immersive;
3016        mHandler.sendMessage(
3017                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3018    }
3019
3020    final void applyUpdateVrModeLocked(ActivityRecord r) {
3021        mHandler.sendMessage(
3022                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3023    }
3024
3025    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3026        Message msg = Message.obtain();
3027        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3028        msg.obj = r.task.askedCompatMode ? null : r;
3029        mUiHandler.sendMessage(msg);
3030    }
3031
3032    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3033            String what, Object obj, ProcessRecord srcApp) {
3034        app.lastActivityTime = now;
3035
3036        if (app.activities.size() > 0) {
3037            // Don't want to touch dependent processes that are hosting activities.
3038            return index;
3039        }
3040
3041        int lrui = mLruProcesses.lastIndexOf(app);
3042        if (lrui < 0) {
3043            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3044                    + what + " " + obj + " from " + srcApp);
3045            return index;
3046        }
3047
3048        if (lrui >= index) {
3049            // Don't want to cause this to move dependent processes *back* in the
3050            // list as if they were less frequently used.
3051            return index;
3052        }
3053
3054        if (lrui >= mLruProcessActivityStart) {
3055            // Don't want to touch dependent processes that are hosting activities.
3056            return index;
3057        }
3058
3059        mLruProcesses.remove(lrui);
3060        if (index > 0) {
3061            index--;
3062        }
3063        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3064                + " in LRU list: " + app);
3065        mLruProcesses.add(index, app);
3066        return index;
3067    }
3068
3069    static void killProcessGroup(int uid, int pid) {
3070        if (sKillHandler != null) {
3071            sKillHandler.sendMessage(
3072                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3073        } else {
3074            Slog.w(TAG, "Asked to kill process group before system bringup!");
3075            Process.killProcessGroup(uid, pid);
3076        }
3077    }
3078
3079    final void removeLruProcessLocked(ProcessRecord app) {
3080        int lrui = mLruProcesses.lastIndexOf(app);
3081        if (lrui >= 0) {
3082            if (!app.killed) {
3083                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3084                Process.killProcessQuiet(app.pid);
3085                killProcessGroup(app.uid, app.pid);
3086            }
3087            if (lrui <= mLruProcessActivityStart) {
3088                mLruProcessActivityStart--;
3089            }
3090            if (lrui <= mLruProcessServiceStart) {
3091                mLruProcessServiceStart--;
3092            }
3093            mLruProcesses.remove(lrui);
3094        }
3095    }
3096
3097    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3098            ProcessRecord client) {
3099        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3100                || app.treatLikeActivity;
3101        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3102        if (!activityChange && hasActivity) {
3103            // The process has activities, so we are only allowing activity-based adjustments
3104            // to move it.  It should be kept in the front of the list with other
3105            // processes that have activities, and we don't want those to change their
3106            // order except due to activity operations.
3107            return;
3108        }
3109
3110        mLruSeq++;
3111        final long now = SystemClock.uptimeMillis();
3112        app.lastActivityTime = now;
3113
3114        // First a quick reject: if the app is already at the position we will
3115        // put it, then there is nothing to do.
3116        if (hasActivity) {
3117            final int N = mLruProcesses.size();
3118            if (N > 0 && mLruProcesses.get(N-1) == app) {
3119                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3120                return;
3121            }
3122        } else {
3123            if (mLruProcessServiceStart > 0
3124                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3125                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3126                return;
3127            }
3128        }
3129
3130        int lrui = mLruProcesses.lastIndexOf(app);
3131
3132        if (app.persistent && lrui >= 0) {
3133            // We don't care about the position of persistent processes, as long as
3134            // they are in the list.
3135            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3136            return;
3137        }
3138
3139        /* In progress: compute new position first, so we can avoid doing work
3140           if the process is not actually going to move.  Not yet working.
3141        int addIndex;
3142        int nextIndex;
3143        boolean inActivity = false, inService = false;
3144        if (hasActivity) {
3145            // Process has activities, put it at the very tipsy-top.
3146            addIndex = mLruProcesses.size();
3147            nextIndex = mLruProcessServiceStart;
3148            inActivity = true;
3149        } else if (hasService) {
3150            // Process has services, put it at the top of the service list.
3151            addIndex = mLruProcessActivityStart;
3152            nextIndex = mLruProcessServiceStart;
3153            inActivity = true;
3154            inService = true;
3155        } else  {
3156            // Process not otherwise of interest, it goes to the top of the non-service area.
3157            addIndex = mLruProcessServiceStart;
3158            if (client != null) {
3159                int clientIndex = mLruProcesses.lastIndexOf(client);
3160                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3161                        + app);
3162                if (clientIndex >= 0 && addIndex > clientIndex) {
3163                    addIndex = clientIndex;
3164                }
3165            }
3166            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3167        }
3168
3169        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3170                + mLruProcessActivityStart + "): " + app);
3171        */
3172
3173        if (lrui >= 0) {
3174            if (lrui < mLruProcessActivityStart) {
3175                mLruProcessActivityStart--;
3176            }
3177            if (lrui < mLruProcessServiceStart) {
3178                mLruProcessServiceStart--;
3179            }
3180            /*
3181            if (addIndex > lrui) {
3182                addIndex--;
3183            }
3184            if (nextIndex > lrui) {
3185                nextIndex--;
3186            }
3187            */
3188            mLruProcesses.remove(lrui);
3189        }
3190
3191        /*
3192        mLruProcesses.add(addIndex, app);
3193        if (inActivity) {
3194            mLruProcessActivityStart++;
3195        }
3196        if (inService) {
3197            mLruProcessActivityStart++;
3198        }
3199        */
3200
3201        int nextIndex;
3202        if (hasActivity) {
3203            final int N = mLruProcesses.size();
3204            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3205                // Process doesn't have activities, but has clients with
3206                // activities...  move it up, but one below the top (the top
3207                // should always have a real activity).
3208                if (DEBUG_LRU) Slog.d(TAG_LRU,
3209                        "Adding to second-top of LRU activity list: " + app);
3210                mLruProcesses.add(N - 1, app);
3211                // To keep it from spamming the LRU list (by making a bunch of clients),
3212                // we will push down any other entries owned by the app.
3213                final int uid = app.info.uid;
3214                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3215                    ProcessRecord subProc = mLruProcesses.get(i);
3216                    if (subProc.info.uid == uid) {
3217                        // We want to push this one down the list.  If the process after
3218                        // it is for the same uid, however, don't do so, because we don't
3219                        // want them internally to be re-ordered.
3220                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3221                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3222                                    "Pushing uid " + uid + " swapping at " + i + ": "
3223                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3224                            ProcessRecord tmp = mLruProcesses.get(i);
3225                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3226                            mLruProcesses.set(i - 1, tmp);
3227                            i--;
3228                        }
3229                    } else {
3230                        // A gap, we can stop here.
3231                        break;
3232                    }
3233                }
3234            } else {
3235                // Process has activities, put it at the very tipsy-top.
3236                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3237                mLruProcesses.add(app);
3238            }
3239            nextIndex = mLruProcessServiceStart;
3240        } else if (hasService) {
3241            // Process has services, put it at the top of the service list.
3242            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3243            mLruProcesses.add(mLruProcessActivityStart, app);
3244            nextIndex = mLruProcessServiceStart;
3245            mLruProcessActivityStart++;
3246        } else  {
3247            // Process not otherwise of interest, it goes to the top of the non-service area.
3248            int index = mLruProcessServiceStart;
3249            if (client != null) {
3250                // If there is a client, don't allow the process to be moved up higher
3251                // in the list than that client.
3252                int clientIndex = mLruProcesses.lastIndexOf(client);
3253                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3254                        + " when updating " + app);
3255                if (clientIndex <= lrui) {
3256                    // Don't allow the client index restriction to push it down farther in the
3257                    // list than it already is.
3258                    clientIndex = lrui;
3259                }
3260                if (clientIndex >= 0 && index > clientIndex) {
3261                    index = clientIndex;
3262                }
3263            }
3264            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3265            mLruProcesses.add(index, app);
3266            nextIndex = index-1;
3267            mLruProcessActivityStart++;
3268            mLruProcessServiceStart++;
3269        }
3270
3271        // If the app is currently using a content provider or service,
3272        // bump those processes as well.
3273        for (int j=app.connections.size()-1; j>=0; j--) {
3274            ConnectionRecord cr = app.connections.valueAt(j);
3275            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3276                    && cr.binding.service.app != null
3277                    && cr.binding.service.app.lruSeq != mLruSeq
3278                    && !cr.binding.service.app.persistent) {
3279                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3280                        "service connection", cr, app);
3281            }
3282        }
3283        for (int j=app.conProviders.size()-1; j>=0; j--) {
3284            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3285            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3286                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3287                        "provider reference", cpr, app);
3288            }
3289        }
3290    }
3291
3292    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3293        if (uid == Process.SYSTEM_UID) {
3294            // The system gets to run in any process.  If there are multiple
3295            // processes with the same uid, just pick the first (this
3296            // should never happen).
3297            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3298            if (procs == null) return null;
3299            final int procCount = procs.size();
3300            for (int i = 0; i < procCount; i++) {
3301                final int procUid = procs.keyAt(i);
3302                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3303                    // Don't use an app process or different user process for system component.
3304                    continue;
3305                }
3306                return procs.valueAt(i);
3307            }
3308        }
3309        ProcessRecord proc = mProcessNames.get(processName, uid);
3310        if (false && proc != null && !keepIfLarge
3311                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3312                && proc.lastCachedPss >= 4000) {
3313            // Turn this condition on to cause killing to happen regularly, for testing.
3314            if (proc.baseProcessTracker != null) {
3315                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3316            }
3317            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3318        } else if (proc != null && !keepIfLarge
3319                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3320                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3321            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3322            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3323                if (proc.baseProcessTracker != null) {
3324                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3325                }
3326                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3327            }
3328        }
3329        return proc;
3330    }
3331
3332    void notifyPackageUse(String packageName) {
3333        IPackageManager pm = AppGlobals.getPackageManager();
3334        try {
3335            pm.notifyPackageUse(packageName);
3336        } catch (RemoteException e) {
3337        }
3338    }
3339
3340    boolean isNextTransitionForward() {
3341        int transit = mWindowManager.getPendingAppTransition();
3342        return transit == TRANSIT_ACTIVITY_OPEN
3343                || transit == TRANSIT_TASK_OPEN
3344                || transit == TRANSIT_TASK_TO_FRONT;
3345    }
3346
3347    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3348            String processName, String abiOverride, int uid, Runnable crashHandler) {
3349        synchronized(this) {
3350            ApplicationInfo info = new ApplicationInfo();
3351            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3352            // For isolated processes, the former contains the parent's uid and the latter the
3353            // actual uid of the isolated process.
3354            // In the special case introduced by this method (which is, starting an isolated
3355            // process directly from the SystemServer without an actual parent app process) the
3356            // closest thing to a parent's uid is SYSTEM_UID.
3357            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3358            // the |isolated| logic in the ProcessRecord constructor.
3359            info.uid = Process.SYSTEM_UID;
3360            info.processName = processName;
3361            info.className = entryPoint;
3362            info.packageName = "android";
3363            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3364                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3365                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3366                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3367                    crashHandler);
3368            return proc != null ? proc.pid : 0;
3369        }
3370    }
3371
3372    final ProcessRecord startProcessLocked(String processName,
3373            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3374            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3375            boolean isolated, boolean keepIfLarge) {
3376        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3377                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3378                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3379                null /* crashHandler */);
3380    }
3381
3382    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3383            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3384            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3385            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3386        long startTime = SystemClock.elapsedRealtime();
3387        ProcessRecord app;
3388        if (!isolated) {
3389            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3390            checkTime(startTime, "startProcess: after getProcessRecord");
3391
3392            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3393                // If we are in the background, then check to see if this process
3394                // is bad.  If so, we will just silently fail.
3395                if (mAppErrors.isBadProcessLocked(info)) {
3396                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3397                            + "/" + info.processName);
3398                    return null;
3399                }
3400            } else {
3401                // When the user is explicitly starting a process, then clear its
3402                // crash count so that we won't make it bad until they see at
3403                // least one crash dialog again, and make the process good again
3404                // if it had been bad.
3405                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3406                        + "/" + info.processName);
3407                mAppErrors.resetProcessCrashTimeLocked(info);
3408                if (mAppErrors.isBadProcessLocked(info)) {
3409                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3410                            UserHandle.getUserId(info.uid), info.uid,
3411                            info.processName);
3412                    mAppErrors.clearBadProcessLocked(info);
3413                    if (app != null) {
3414                        app.bad = false;
3415                    }
3416                }
3417            }
3418        } else {
3419            // If this is an isolated process, it can't re-use an existing process.
3420            app = null;
3421        }
3422
3423        // app launch boost for big.little configurations
3424        // use cpusets to migrate freshly launched tasks to big cores
3425        synchronized(ActivityManagerService.this) {
3426            nativeMigrateToBoost();
3427            mIsBoosted = true;
3428            mBoostStartTime = SystemClock.uptimeMillis();
3429            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3430            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3431        }
3432
3433        // We don't have to do anything more if:
3434        // (1) There is an existing application record; and
3435        // (2) The caller doesn't think it is dead, OR there is no thread
3436        //     object attached to it so we know it couldn't have crashed; and
3437        // (3) There is a pid assigned to it, so it is either starting or
3438        //     already running.
3439        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3440                + " app=" + app + " knownToBeDead=" + knownToBeDead
3441                + " thread=" + (app != null ? app.thread : null)
3442                + " pid=" + (app != null ? app.pid : -1));
3443        if (app != null && app.pid > 0) {
3444            if (!knownToBeDead || app.thread == null) {
3445                // We already have the app running, or are waiting for it to
3446                // come up (we have a pid but not yet its thread), so keep it.
3447                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3448                // If this is a new package in the process, add the package to the list
3449                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3450                checkTime(startTime, "startProcess: done, added package to proc");
3451                return app;
3452            }
3453
3454            // An application record is attached to a previous process,
3455            // clean it up now.
3456            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3457            checkTime(startTime, "startProcess: bad proc running, killing");
3458            killProcessGroup(app.uid, app.pid);
3459            handleAppDiedLocked(app, true, true);
3460            checkTime(startTime, "startProcess: done killing old proc");
3461        }
3462
3463        String hostingNameStr = hostingName != null
3464                ? hostingName.flattenToShortString() : null;
3465
3466        if (app == null) {
3467            checkTime(startTime, "startProcess: creating new process record");
3468            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3469            if (app == null) {
3470                Slog.w(TAG, "Failed making new process record for "
3471                        + processName + "/" + info.uid + " isolated=" + isolated);
3472                return null;
3473            }
3474            app.crashHandler = crashHandler;
3475            checkTime(startTime, "startProcess: done creating new process record");
3476        } else {
3477            // If this is a new package in the process, add the package to the list
3478            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3479            checkTime(startTime, "startProcess: added package to existing proc");
3480        }
3481
3482        // If the system is not ready yet, then hold off on starting this
3483        // process until it is.
3484        if (!mProcessesReady
3485                && !isAllowedWhileBooting(info)
3486                && !allowWhileBooting) {
3487            if (!mProcessesOnHold.contains(app)) {
3488                mProcessesOnHold.add(app);
3489            }
3490            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3491                    "System not ready, putting on hold: " + app);
3492            checkTime(startTime, "startProcess: returning with proc on hold");
3493            return app;
3494        }
3495
3496        checkTime(startTime, "startProcess: stepping in to startProcess");
3497        startProcessLocked(
3498                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3499        checkTime(startTime, "startProcess: done starting proc!");
3500        return (app.pid != 0) ? app : null;
3501    }
3502
3503    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3504        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3505    }
3506
3507    private final void startProcessLocked(ProcessRecord app,
3508            String hostingType, String hostingNameStr) {
3509        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3510                null /* entryPoint */, null /* entryPointArgs */);
3511    }
3512
3513    private final void startProcessLocked(ProcessRecord app, String hostingType,
3514            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3515        long startTime = SystemClock.elapsedRealtime();
3516        if (app.pid > 0 && app.pid != MY_PID) {
3517            checkTime(startTime, "startProcess: removing from pids map");
3518            synchronized (mPidsSelfLocked) {
3519                mPidsSelfLocked.remove(app.pid);
3520                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3521            }
3522            checkTime(startTime, "startProcess: done removing from pids map");
3523            app.setPid(0);
3524        }
3525
3526        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3527                "startProcessLocked removing on hold: " + app);
3528        mProcessesOnHold.remove(app);
3529
3530        checkTime(startTime, "startProcess: starting to update cpu stats");
3531        updateCpuStats();
3532        checkTime(startTime, "startProcess: done updating cpu stats");
3533
3534        try {
3535            try {
3536                final int userId = UserHandle.getUserId(app.uid);
3537                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3538            } catch (RemoteException e) {
3539                throw e.rethrowAsRuntimeException();
3540            }
3541
3542            int uid = app.uid;
3543            int[] gids = null;
3544            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3545            if (!app.isolated) {
3546                int[] permGids = null;
3547                try {
3548                    checkTime(startTime, "startProcess: getting gids from package manager");
3549                    final IPackageManager pm = AppGlobals.getPackageManager();
3550                    permGids = pm.getPackageGids(app.info.packageName,
3551                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3552                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3553                            MountServiceInternal.class);
3554                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3555                            app.info.packageName);
3556                } catch (RemoteException e) {
3557                    throw e.rethrowAsRuntimeException();
3558                }
3559
3560                /*
3561                 * Add shared application and profile GIDs so applications can share some
3562                 * resources like shared libraries and access user-wide resources
3563                 */
3564                if (ArrayUtils.isEmpty(permGids)) {
3565                    gids = new int[2];
3566                } else {
3567                    gids = new int[permGids.length + 2];
3568                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3569                }
3570                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3571                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3572            }
3573            checkTime(startTime, "startProcess: building args");
3574            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3575                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3576                        && mTopComponent != null
3577                        && app.processName.equals(mTopComponent.getPackageName())) {
3578                    uid = 0;
3579                }
3580                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3581                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3582                    uid = 0;
3583                }
3584            }
3585            int debugFlags = 0;
3586            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3587                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3588                // Also turn on CheckJNI for debuggable apps. It's quite
3589                // awkward to turn on otherwise.
3590                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3591            }
3592            // Run the app in safe mode if its manifest requests so or the
3593            // system is booted in safe mode.
3594            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3595                mSafeMode == true) {
3596                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3597            }
3598            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3599                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3600            }
3601            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3602            if ("true".equals(genDebugInfoProperty)) {
3603                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3604            }
3605            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3606                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3607            }
3608            if ("1".equals(SystemProperties.get("debug.assert"))) {
3609                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3610            }
3611            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3612                // Enable all debug flags required by the native debugger.
3613                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3614                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3615                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3616                mNativeDebuggingApp = null;
3617            }
3618
3619            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3620            if (requiredAbi == null) {
3621                requiredAbi = Build.SUPPORTED_ABIS[0];
3622            }
3623
3624            String instructionSet = null;
3625            if (app.info.primaryCpuAbi != null) {
3626                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3627            }
3628
3629            app.gids = gids;
3630            app.requiredAbi = requiredAbi;
3631            app.instructionSet = instructionSet;
3632
3633            // Start the process.  It will either succeed and return a result containing
3634            // the PID of the new process, or else throw a RuntimeException.
3635            boolean isActivityProcess = (entryPoint == null);
3636            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3637            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3638                    app.processName);
3639            checkTime(startTime, "startProcess: asking zygote to start proc");
3640            Process.ProcessStartResult startResult = Process.start(entryPoint,
3641                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3642                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3643                    app.info.dataDir, entryPointArgs);
3644            checkTime(startTime, "startProcess: returned from zygote!");
3645            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3646
3647            if (app.isolated) {
3648                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3649            }
3650            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3651            checkTime(startTime, "startProcess: done updating battery stats");
3652
3653            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3654                    UserHandle.getUserId(uid), startResult.pid, uid,
3655                    app.processName, hostingType,
3656                    hostingNameStr != null ? hostingNameStr : "");
3657
3658            try {
3659                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3660                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3661            } catch (RemoteException ex) {
3662                // Ignore
3663            }
3664
3665            if (app.persistent) {
3666                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3667            }
3668
3669            if (DEBUG_PROCESSES) {
3670                checkTime(startTime, "startProcess: building log message");
3671                StringBuilder buf = mStringBuilder;
3672                buf.setLength(0);
3673                buf.append("Start proc ");
3674                buf.append(startResult.pid);
3675                buf.append(':');
3676                buf.append(app.processName);
3677                buf.append('/');
3678                UserHandle.formatUid(buf, uid);
3679                if (!isActivityProcess) {
3680                    buf.append(" [");
3681                    buf.append(entryPoint);
3682                    buf.append("]");
3683                }
3684                buf.append(" for ");
3685                buf.append(hostingType);
3686                if (hostingNameStr != null) {
3687                    buf.append(" ");
3688                    buf.append(hostingNameStr);
3689                }
3690                Slog.i(TAG, buf.toString());
3691            }
3692            app.setPid(startResult.pid);
3693            app.usingWrapper = startResult.usingWrapper;
3694            app.removed = false;
3695            app.killed = false;
3696            app.killedByAm = false;
3697            checkTime(startTime, "startProcess: starting to update pids map");
3698            synchronized (mPidsSelfLocked) {
3699                this.mPidsSelfLocked.put(startResult.pid, app);
3700                if (isActivityProcess) {
3701                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3702                    msg.obj = app;
3703                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3704                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3705                }
3706            }
3707            checkTime(startTime, "startProcess: done updating pids map");
3708        } catch (RuntimeException e) {
3709            // XXX do better error recovery.
3710            app.setPid(0);
3711            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3712            if (app.isolated) {
3713                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3714            }
3715            Slog.e(TAG, "Failure starting process " + app.processName, e);
3716        }
3717    }
3718
3719    void updateUsageStats(ActivityRecord component, boolean resumed) {
3720        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3721                "updateUsageStats: comp=" + component + "res=" + resumed);
3722        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3723        if (resumed) {
3724            if (mUsageStatsService != null) {
3725                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3726                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3727            }
3728            synchronized (stats) {
3729                stats.noteActivityResumedLocked(component.app.uid);
3730            }
3731        } else {
3732            if (mUsageStatsService != null) {
3733                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3734                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3735            }
3736            synchronized (stats) {
3737                stats.noteActivityPausedLocked(component.app.uid);
3738            }
3739        }
3740    }
3741
3742    Intent getHomeIntent() {
3743        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3744        intent.setComponent(mTopComponent);
3745        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3746        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3747            intent.addCategory(Intent.CATEGORY_HOME);
3748        }
3749        return intent;
3750    }
3751
3752    boolean startHomeActivityLocked(int userId, String reason) {
3753        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3754                && mTopAction == null) {
3755            // We are running in factory test mode, but unable to find
3756            // the factory test app, so just sit around displaying the
3757            // error message and don't try to start anything.
3758            return false;
3759        }
3760        Intent intent = getHomeIntent();
3761        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3762        if (aInfo != null) {
3763            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3764            // Don't do this if the home app is currently being
3765            // instrumented.
3766            aInfo = new ActivityInfo(aInfo);
3767            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3768            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3769                    aInfo.applicationInfo.uid, true);
3770            if (app == null || app.instrumentationClass == null) {
3771                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3772                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3773            }
3774        }
3775
3776        return true;
3777    }
3778
3779    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3780        ActivityInfo ai = null;
3781        ComponentName comp = intent.getComponent();
3782        try {
3783            if (comp != null) {
3784                // Factory test.
3785                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3786            } else {
3787                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3788                        intent,
3789                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3790                        flags, userId);
3791
3792                if (info != null) {
3793                    ai = info.activityInfo;
3794                }
3795            }
3796        } catch (RemoteException e) {
3797            // ignore
3798        }
3799
3800        return ai;
3801    }
3802
3803    /**
3804     * Starts the "new version setup screen" if appropriate.
3805     */
3806    void startSetupActivityLocked() {
3807        // Only do this once per boot.
3808        if (mCheckedForSetup) {
3809            return;
3810        }
3811
3812        // We will show this screen if the current one is a different
3813        // version than the last one shown, and we are not running in
3814        // low-level factory test mode.
3815        final ContentResolver resolver = mContext.getContentResolver();
3816        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3817                Settings.Global.getInt(resolver,
3818                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3819            mCheckedForSetup = true;
3820
3821            // See if we should be showing the platform update setup UI.
3822            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3823            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3824                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3825            if (!ris.isEmpty()) {
3826                final ResolveInfo ri = ris.get(0);
3827                String vers = ri.activityInfo.metaData != null
3828                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3829                        : null;
3830                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3831                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3832                            Intent.METADATA_SETUP_VERSION);
3833                }
3834                String lastVers = Settings.Secure.getString(
3835                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3836                if (vers != null && !vers.equals(lastVers)) {
3837                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3838                    intent.setComponent(new ComponentName(
3839                            ri.activityInfo.packageName, ri.activityInfo.name));
3840                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3841                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3842                            null, 0, 0, 0, null, false, false, null, null, null);
3843                }
3844            }
3845        }
3846    }
3847
3848    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3849        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3850    }
3851
3852    void enforceNotIsolatedCaller(String caller) {
3853        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3854            throw new SecurityException("Isolated process not allowed to call " + caller);
3855        }
3856    }
3857
3858    void enforceShellRestriction(String restriction, int userHandle) {
3859        if (Binder.getCallingUid() == Process.SHELL_UID) {
3860            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3861                throw new SecurityException("Shell does not have permission to access user "
3862                        + userHandle);
3863            }
3864        }
3865    }
3866
3867    @Override
3868    public int getFrontActivityScreenCompatMode() {
3869        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3870        synchronized (this) {
3871            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3872        }
3873    }
3874
3875    @Override
3876    public void setFrontActivityScreenCompatMode(int mode) {
3877        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3878                "setFrontActivityScreenCompatMode");
3879        synchronized (this) {
3880            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3881        }
3882    }
3883
3884    @Override
3885    public int getPackageScreenCompatMode(String packageName) {
3886        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3887        synchronized (this) {
3888            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3889        }
3890    }
3891
3892    @Override
3893    public void setPackageScreenCompatMode(String packageName, int mode) {
3894        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3895                "setPackageScreenCompatMode");
3896        synchronized (this) {
3897            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3898        }
3899    }
3900
3901    @Override
3902    public boolean getPackageAskScreenCompat(String packageName) {
3903        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3904        synchronized (this) {
3905            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3906        }
3907    }
3908
3909    @Override
3910    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3911        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3912                "setPackageAskScreenCompat");
3913        synchronized (this) {
3914            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3915        }
3916    }
3917
3918    private boolean hasUsageStatsPermission(String callingPackage) {
3919        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3920                Binder.getCallingUid(), callingPackage);
3921        if (mode == AppOpsManager.MODE_DEFAULT) {
3922            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3923                    == PackageManager.PERMISSION_GRANTED;
3924        }
3925        return mode == AppOpsManager.MODE_ALLOWED;
3926    }
3927
3928    @Override
3929    public int getPackageProcessState(String packageName, String callingPackage) {
3930        if (!hasUsageStatsPermission(callingPackage)) {
3931            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3932                    "getPackageProcessState");
3933        }
3934
3935        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3936        synchronized (this) {
3937            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3938                final ProcessRecord proc = mLruProcesses.get(i);
3939                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3940                        || procState > proc.setProcState) {
3941                    boolean found = false;
3942                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3943                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3944                            procState = proc.setProcState;
3945                            found = true;
3946                        }
3947                    }
3948                    if (proc.pkgDeps != null && !found) {
3949                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3950                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3951                                procState = proc.setProcState;
3952                                break;
3953                            }
3954                        }
3955                    }
3956                }
3957            }
3958        }
3959        return procState;
3960    }
3961
3962    @Override
3963    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3964        synchronized (this) {
3965            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3966            if (app == null) {
3967                return false;
3968            }
3969            if (app.trimMemoryLevel < level && app.thread != null &&
3970                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3971                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3972                try {
3973                    app.thread.scheduleTrimMemory(level);
3974                    app.trimMemoryLevel = level;
3975                    return true;
3976                } catch (RemoteException e) {
3977                    // Fallthrough to failure case.
3978                }
3979            }
3980        }
3981        return false;
3982    }
3983
3984    private void dispatchProcessesChanged() {
3985        int N;
3986        synchronized (this) {
3987            N = mPendingProcessChanges.size();
3988            if (mActiveProcessChanges.length < N) {
3989                mActiveProcessChanges = new ProcessChangeItem[N];
3990            }
3991            mPendingProcessChanges.toArray(mActiveProcessChanges);
3992            mPendingProcessChanges.clear();
3993            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3994                    "*** Delivering " + N + " process changes");
3995        }
3996
3997        int i = mProcessObservers.beginBroadcast();
3998        while (i > 0) {
3999            i--;
4000            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4001            if (observer != null) {
4002                try {
4003                    for (int j=0; j<N; j++) {
4004                        ProcessChangeItem item = mActiveProcessChanges[j];
4005                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4006                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4007                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4008                                    + item.uid + ": " + item.foregroundActivities);
4009                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4010                                    item.foregroundActivities);
4011                        }
4012                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4013                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4014                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4015                                    + ": " + item.processState);
4016                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4017                        }
4018                    }
4019                } catch (RemoteException e) {
4020                }
4021            }
4022        }
4023        mProcessObservers.finishBroadcast();
4024
4025        synchronized (this) {
4026            for (int j=0; j<N; j++) {
4027                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4028            }
4029        }
4030    }
4031
4032    private void dispatchProcessDied(int pid, int uid) {
4033        int i = mProcessObservers.beginBroadcast();
4034        while (i > 0) {
4035            i--;
4036            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4037            if (observer != null) {
4038                try {
4039                    observer.onProcessDied(pid, uid);
4040                } catch (RemoteException e) {
4041                }
4042            }
4043        }
4044        mProcessObservers.finishBroadcast();
4045    }
4046
4047    private void dispatchUidsChanged() {
4048        int N;
4049        synchronized (this) {
4050            N = mPendingUidChanges.size();
4051            if (mActiveUidChanges.length < N) {
4052                mActiveUidChanges = new UidRecord.ChangeItem[N];
4053            }
4054            for (int i=0; i<N; i++) {
4055                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4056                mActiveUidChanges[i] = change;
4057                if (change.uidRecord != null) {
4058                    change.uidRecord.pendingChange = null;
4059                    change.uidRecord = null;
4060                }
4061            }
4062            mPendingUidChanges.clear();
4063            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4064                    "*** Delivering " + N + " uid changes");
4065        }
4066
4067        if (mLocalPowerManager != null) {
4068            for (int j=0; j<N; j++) {
4069                UidRecord.ChangeItem item = mActiveUidChanges[j];
4070                if (item.change == UidRecord.CHANGE_GONE
4071                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4072                    mLocalPowerManager.uidGone(item.uid);
4073                } else {
4074                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4075                }
4076            }
4077        }
4078
4079        int i = mUidObservers.beginBroadcast();
4080        while (i > 0) {
4081            i--;
4082            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4083            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4084            if (observer != null) {
4085                try {
4086                    for (int j=0; j<N; j++) {
4087                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4088                        final int change = item.change;
4089                        UidRecord validateUid = null;
4090                        if (VALIDATE_UID_STATES && i == 0) {
4091                            validateUid = mValidateUids.get(item.uid);
4092                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4093                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4094                                validateUid = new UidRecord(item.uid);
4095                                mValidateUids.put(item.uid, validateUid);
4096                            }
4097                        }
4098                        if (change == UidRecord.CHANGE_IDLE
4099                                || change == UidRecord.CHANGE_GONE_IDLE) {
4100                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4101                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4102                                        "UID idle uid=" + item.uid);
4103                                observer.onUidIdle(item.uid);
4104                            }
4105                            if (VALIDATE_UID_STATES && i == 0) {
4106                                if (validateUid != null) {
4107                                    validateUid.idle = true;
4108                                }
4109                            }
4110                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4111                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4112                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4113                                        "UID active uid=" + item.uid);
4114                                observer.onUidActive(item.uid);
4115                            }
4116                            if (VALIDATE_UID_STATES && i == 0) {
4117                                validateUid.idle = false;
4118                            }
4119                        }
4120                        if (change == UidRecord.CHANGE_GONE
4121                                || change == UidRecord.CHANGE_GONE_IDLE) {
4122                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4123                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4124                                        "UID gone uid=" + item.uid);
4125                                observer.onUidGone(item.uid);
4126                            }
4127                            if (VALIDATE_UID_STATES && i == 0) {
4128                                if (validateUid != null) {
4129                                    mValidateUids.remove(item.uid);
4130                                }
4131                            }
4132                        } else {
4133                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4134                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4135                                        "UID CHANGED uid=" + item.uid
4136                                                + ": " + item.processState);
4137                                observer.onUidStateChanged(item.uid, item.processState);
4138                            }
4139                            if (VALIDATE_UID_STATES && i == 0) {
4140                                validateUid.curProcState = validateUid.setProcState
4141                                        = item.processState;
4142                            }
4143                        }
4144                    }
4145                } catch (RemoteException e) {
4146                }
4147            }
4148        }
4149        mUidObservers.finishBroadcast();
4150
4151        synchronized (this) {
4152            for (int j=0; j<N; j++) {
4153                mAvailUidChanges.add(mActiveUidChanges[j]);
4154            }
4155        }
4156    }
4157
4158    @Override
4159    public final int startActivity(IApplicationThread caller, String callingPackage,
4160            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4161            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4162        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4163                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4164                UserHandle.getCallingUserId());
4165    }
4166
4167    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4168        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4169        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4170                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4171                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4172
4173        // TODO: Switch to user app stacks here.
4174        String mimeType = intent.getType();
4175        final Uri data = intent.getData();
4176        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4177            mimeType = getProviderMimeType(data, userId);
4178        }
4179        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4180
4181        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4182        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4183                null, 0, 0, null, null, null, null, false, userId, container, null);
4184    }
4185
4186    @Override
4187    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4188            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4189            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4190        enforceNotIsolatedCaller("startActivity");
4191        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4192                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4193        // TODO: Switch to user app stacks here.
4194        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4195                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4196                profilerInfo, null, null, bOptions, false, userId, null, null);
4197    }
4198
4199    @Override
4200    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4201            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4202            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4203            int userId) {
4204
4205        // This is very dangerous -- it allows you to perform a start activity (including
4206        // permission grants) as any app that may launch one of your own activities.  So
4207        // we will only allow this to be done from activities that are part of the core framework,
4208        // and then only when they are running as the system.
4209        final ActivityRecord sourceRecord;
4210        final int targetUid;
4211        final String targetPackage;
4212        synchronized (this) {
4213            if (resultTo == null) {
4214                throw new SecurityException("Must be called from an activity");
4215            }
4216            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4217            if (sourceRecord == null) {
4218                throw new SecurityException("Called with bad activity token: " + resultTo);
4219            }
4220            if (!sourceRecord.info.packageName.equals("android")) {
4221                throw new SecurityException(
4222                        "Must be called from an activity that is declared in the android package");
4223            }
4224            if (sourceRecord.app == null) {
4225                throw new SecurityException("Called without a process attached to activity");
4226            }
4227            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4228                // This is still okay, as long as this activity is running under the
4229                // uid of the original calling activity.
4230                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4231                    throw new SecurityException(
4232                            "Calling activity in uid " + sourceRecord.app.uid
4233                                    + " must be system uid or original calling uid "
4234                                    + sourceRecord.launchedFromUid);
4235                }
4236            }
4237            if (ignoreTargetSecurity) {
4238                if (intent.getComponent() == null) {
4239                    throw new SecurityException(
4240                            "Component must be specified with ignoreTargetSecurity");
4241                }
4242                if (intent.getSelector() != null) {
4243                    throw new SecurityException(
4244                            "Selector not allowed with ignoreTargetSecurity");
4245                }
4246            }
4247            targetUid = sourceRecord.launchedFromUid;
4248            targetPackage = sourceRecord.launchedFromPackage;
4249        }
4250
4251        if (userId == UserHandle.USER_NULL) {
4252            userId = UserHandle.getUserId(sourceRecord.app.uid);
4253        }
4254
4255        // TODO: Switch to user app stacks here.
4256        try {
4257            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4258                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4259                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4260            return ret;
4261        } catch (SecurityException e) {
4262            // XXX need to figure out how to propagate to original app.
4263            // A SecurityException here is generally actually a fault of the original
4264            // calling activity (such as a fairly granting permissions), so propagate it
4265            // back to them.
4266            /*
4267            StringBuilder msg = new StringBuilder();
4268            msg.append("While launching");
4269            msg.append(intent.toString());
4270            msg.append(": ");
4271            msg.append(e.getMessage());
4272            */
4273            throw e;
4274        }
4275    }
4276
4277    @Override
4278    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4279            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4280            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4281        enforceNotIsolatedCaller("startActivityAndWait");
4282        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4283                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4284        WaitResult res = new WaitResult();
4285        // TODO: Switch to user app stacks here.
4286        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4287                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4288                bOptions, false, userId, null, null);
4289        return res;
4290    }
4291
4292    @Override
4293    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4294            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4295            int startFlags, Configuration config, Bundle bOptions, int userId) {
4296        enforceNotIsolatedCaller("startActivityWithConfig");
4297        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4298                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4299        // TODO: Switch to user app stacks here.
4300        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4301                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4302                null, null, config, bOptions, false, userId, null, null);
4303        return ret;
4304    }
4305
4306    @Override
4307    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4308            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4309            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4310            throws TransactionTooLargeException {
4311        enforceNotIsolatedCaller("startActivityIntentSender");
4312        // Refuse possible leaked file descriptors
4313        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4314            throw new IllegalArgumentException("File descriptors passed in Intent");
4315        }
4316
4317        IIntentSender sender = intent.getTarget();
4318        if (!(sender instanceof PendingIntentRecord)) {
4319            throw new IllegalArgumentException("Bad PendingIntent object");
4320        }
4321
4322        PendingIntentRecord pir = (PendingIntentRecord)sender;
4323
4324        synchronized (this) {
4325            // If this is coming from the currently resumed activity, it is
4326            // effectively saying that app switches are allowed at this point.
4327            final ActivityStack stack = getFocusedStack();
4328            if (stack.mResumedActivity != null &&
4329                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4330                mAppSwitchesAllowedTime = 0;
4331            }
4332        }
4333        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4334                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4335        return ret;
4336    }
4337
4338    @Override
4339    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4340            Intent intent, String resolvedType, IVoiceInteractionSession session,
4341            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4342            Bundle bOptions, int userId) {
4343        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: startVoiceActivity() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352        if (session == null || interactor == null) {
4353            throw new NullPointerException("null session or interactor");
4354        }
4355        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4356                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4357        // TODO: Switch to user app stacks here.
4358        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4359                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4360                null, bOptions, false, userId, null, null);
4361    }
4362
4363    @Override
4364    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4365            throws RemoteException {
4366        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4367        synchronized (this) {
4368            ActivityRecord activity = getFocusedStack().topActivity();
4369            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4370                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4371            }
4372            if (mRunningVoice != null || activity.task.voiceSession != null
4373                    || activity.voiceSession != null) {
4374                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4375                return;
4376            }
4377            if (activity.pendingVoiceInteractionStart) {
4378                Slog.w(TAG, "Pending start of voice interaction already.");
4379                return;
4380            }
4381            activity.pendingVoiceInteractionStart = true;
4382        }
4383        LocalServices.getService(VoiceInteractionManagerInternal.class)
4384                .startLocalVoiceInteraction(callingActivity, options);
4385    }
4386
4387    @Override
4388    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4389        LocalServices.getService(VoiceInteractionManagerInternal.class)
4390                .stopLocalVoiceInteraction(callingActivity);
4391    }
4392
4393    @Override
4394    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4395        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4396                .supportsLocalVoiceInteraction();
4397    }
4398
4399    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4400            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4401        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4402        if (activityToCallback == null) return;
4403        activityToCallback.setVoiceSessionLocked(voiceSession);
4404
4405        // Inform the activity
4406        try {
4407            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4408                    voiceInteractor);
4409            long token = Binder.clearCallingIdentity();
4410            try {
4411                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4412            } finally {
4413                Binder.restoreCallingIdentity(token);
4414            }
4415            // TODO: VI Should we cache the activity so that it's easier to find later
4416            // rather than scan through all the stacks and activities?
4417        } catch (RemoteException re) {
4418            activityToCallback.clearVoiceSessionLocked();
4419            // TODO: VI Should this terminate the voice session?
4420        }
4421    }
4422
4423    @Override
4424    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4425        synchronized (this) {
4426            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4427                if (keepAwake) {
4428                    mVoiceWakeLock.acquire();
4429                } else {
4430                    mVoiceWakeLock.release();
4431                }
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public boolean startNextMatchingActivity(IBinder callingActivity,
4438            Intent intent, Bundle bOptions) {
4439        // Refuse possible leaked file descriptors
4440        if (intent != null && intent.hasFileDescriptors() == true) {
4441            throw new IllegalArgumentException("File descriptors passed in Intent");
4442        }
4443        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4444
4445        synchronized (this) {
4446            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4447            if (r == null) {
4448                ActivityOptions.abort(options);
4449                return false;
4450            }
4451            if (r.app == null || r.app.thread == null) {
4452                // The caller is not running...  d'oh!
4453                ActivityOptions.abort(options);
4454                return false;
4455            }
4456            intent = new Intent(intent);
4457            // The caller is not allowed to change the data.
4458            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4459            // And we are resetting to find the next component...
4460            intent.setComponent(null);
4461
4462            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4463
4464            ActivityInfo aInfo = null;
4465            try {
4466                List<ResolveInfo> resolves =
4467                    AppGlobals.getPackageManager().queryIntentActivities(
4468                            intent, r.resolvedType,
4469                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4470                            UserHandle.getCallingUserId()).getList();
4471
4472                // Look for the original activity in the list...
4473                final int N = resolves != null ? resolves.size() : 0;
4474                for (int i=0; i<N; i++) {
4475                    ResolveInfo rInfo = resolves.get(i);
4476                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4477                            && rInfo.activityInfo.name.equals(r.info.name)) {
4478                        // We found the current one...  the next matching is
4479                        // after it.
4480                        i++;
4481                        if (i<N) {
4482                            aInfo = resolves.get(i).activityInfo;
4483                        }
4484                        if (debug) {
4485                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4486                                    + "/" + r.info.name);
4487                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4488                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4489                        }
4490                        break;
4491                    }
4492                }
4493            } catch (RemoteException e) {
4494            }
4495
4496            if (aInfo == null) {
4497                // Nobody who is next!
4498                ActivityOptions.abort(options);
4499                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4500                return false;
4501            }
4502
4503            intent.setComponent(new ComponentName(
4504                    aInfo.applicationInfo.packageName, aInfo.name));
4505            intent.setFlags(intent.getFlags()&~(
4506                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4507                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4508                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4509                    Intent.FLAG_ACTIVITY_NEW_TASK));
4510
4511            // Okay now we need to start the new activity, replacing the
4512            // currently running activity.  This is a little tricky because
4513            // we want to start the new one as if the current one is finished,
4514            // but not finish the current one first so that there is no flicker.
4515            // And thus...
4516            final boolean wasFinishing = r.finishing;
4517            r.finishing = true;
4518
4519            // Propagate reply information over to the new activity.
4520            final ActivityRecord resultTo = r.resultTo;
4521            final String resultWho = r.resultWho;
4522            final int requestCode = r.requestCode;
4523            r.resultTo = null;
4524            if (resultTo != null) {
4525                resultTo.removeResultsLocked(r, resultWho, requestCode);
4526            }
4527
4528            final long origId = Binder.clearCallingIdentity();
4529            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4530                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4531                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4532                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4533                    false, false, null, null, null);
4534            Binder.restoreCallingIdentity(origId);
4535
4536            r.finishing = wasFinishing;
4537            if (res != ActivityManager.START_SUCCESS) {
4538                return false;
4539            }
4540            return true;
4541        }
4542    }
4543
4544    @Override
4545    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4546        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4547            String msg = "Permission Denial: startActivityFromRecents called without " +
4548                    START_TASKS_FROM_RECENTS;
4549            Slog.w(TAG, msg);
4550            throw new SecurityException(msg);
4551        }
4552        final long origId = Binder.clearCallingIdentity();
4553        try {
4554            synchronized (this) {
4555                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4556            }
4557        } finally {
4558            Binder.restoreCallingIdentity(origId);
4559        }
4560    }
4561
4562    final int startActivityInPackage(int uid, String callingPackage,
4563            Intent intent, String resolvedType, IBinder resultTo,
4564            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4565            IActivityContainer container, TaskRecord inTask) {
4566
4567        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4568                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4569
4570        // TODO: Switch to user app stacks here.
4571        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4572                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4573                null, null, null, bOptions, false, userId, container, inTask);
4574        return ret;
4575    }
4576
4577    @Override
4578    public final int startActivities(IApplicationThread caller, String callingPackage,
4579            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4580            int userId) {
4581        enforceNotIsolatedCaller("startActivities");
4582        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4583                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4584        // TODO: Switch to user app stacks here.
4585        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4586                resolvedTypes, resultTo, bOptions, userId);
4587        return ret;
4588    }
4589
4590    final int startActivitiesInPackage(int uid, String callingPackage,
4591            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4592            Bundle bOptions, int userId) {
4593
4594        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4595                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4596        // TODO: Switch to user app stacks here.
4597        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4598                resultTo, bOptions, userId);
4599        return ret;
4600    }
4601
4602    @Override
4603    public void reportActivityFullyDrawn(IBinder token) {
4604        synchronized (this) {
4605            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4606            if (r == null) {
4607                return;
4608            }
4609            r.reportFullyDrawnLocked();
4610        }
4611    }
4612
4613    @Override
4614    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4615        synchronized (this) {
4616            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4617            if (r == null) {
4618                return;
4619            }
4620            TaskRecord task = r.task;
4621            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4622                // Fixed screen orientation isn't supported when activities aren't in full screen
4623                // mode.
4624                return;
4625            }
4626            final long origId = Binder.clearCallingIdentity();
4627            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4628            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4629                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4630            if (config != null) {
4631                r.frozenBeforeDestroy = true;
4632                if (!updateConfigurationLocked(config, r, false)) {
4633                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4634                }
4635            }
4636            Binder.restoreCallingIdentity(origId);
4637        }
4638    }
4639
4640    @Override
4641    public int getRequestedOrientation(IBinder token) {
4642        synchronized (this) {
4643            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4644            if (r == null) {
4645                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4646            }
4647            return mWindowManager.getAppOrientation(r.appToken);
4648        }
4649    }
4650
4651    /**
4652     * This is the internal entry point for handling Activity.finish().
4653     *
4654     * @param token The Binder token referencing the Activity we want to finish.
4655     * @param resultCode Result code, if any, from this Activity.
4656     * @param resultData Result data (Intent), if any, from this Activity.
4657     * @param finishTask Whether to finish the task associated with this Activity.
4658     *
4659     * @return Returns true if the activity successfully finished, or false if it is still running.
4660     */
4661    @Override
4662    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4663            int finishTask) {
4664        // Refuse possible leaked file descriptors
4665        if (resultData != null && resultData.hasFileDescriptors() == true) {
4666            throw new IllegalArgumentException("File descriptors passed in Intent");
4667        }
4668
4669        synchronized(this) {
4670            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671            if (r == null) {
4672                return true;
4673            }
4674            // Keep track of the root activity of the task before we finish it
4675            TaskRecord tr = r.task;
4676            ActivityRecord rootR = tr.getRootActivity();
4677            if (rootR == null) {
4678                Slog.w(TAG, "Finishing task with all activities already finished");
4679            }
4680            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4681            // finish.
4682            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4683                    mStackSupervisor.isLastLockedTask(tr)) {
4684                Slog.i(TAG, "Not finishing task in lock task mode");
4685                mStackSupervisor.showLockTaskToast();
4686                return false;
4687            }
4688            if (mController != null) {
4689                // Find the first activity that is not finishing.
4690                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4691                if (next != null) {
4692                    // ask watcher if this is allowed
4693                    boolean resumeOK = true;
4694                    try {
4695                        resumeOK = mController.activityResuming(next.packageName);
4696                    } catch (RemoteException e) {
4697                        mController = null;
4698                        Watchdog.getInstance().setActivityController(null);
4699                    }
4700
4701                    if (!resumeOK) {
4702                        Slog.i(TAG, "Not finishing activity because controller resumed");
4703                        return false;
4704                    }
4705                }
4706            }
4707            final long origId = Binder.clearCallingIdentity();
4708            try {
4709                boolean res;
4710                final boolean finishWithRootActivity =
4711                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4712                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4713                        || (finishWithRootActivity && r == rootR)) {
4714                    // If requested, remove the task that is associated to this activity only if it
4715                    // was the root activity in the task. The result code and data is ignored
4716                    // because we don't support returning them across task boundaries. Also, to
4717                    // keep backwards compatibility we remove the task from recents when finishing
4718                    // task with root activity.
4719                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4720                    if (!res) {
4721                        Slog.i(TAG, "Removing task failed to finish activity");
4722                    }
4723                } else {
4724                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4725                            resultData, "app-request", true);
4726                    if (!res) {
4727                        Slog.i(TAG, "Failed to finish by app-request");
4728                    }
4729                }
4730                return res;
4731            } finally {
4732                Binder.restoreCallingIdentity(origId);
4733            }
4734        }
4735    }
4736
4737    @Override
4738    public final void finishHeavyWeightApp() {
4739        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4740                != PackageManager.PERMISSION_GRANTED) {
4741            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4742                    + Binder.getCallingPid()
4743                    + ", uid=" + Binder.getCallingUid()
4744                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4745            Slog.w(TAG, msg);
4746            throw new SecurityException(msg);
4747        }
4748
4749        synchronized(this) {
4750            if (mHeavyWeightProcess == null) {
4751                return;
4752            }
4753
4754            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4755            for (int i = 0; i < activities.size(); i++) {
4756                ActivityRecord r = activities.get(i);
4757                if (!r.finishing && r.isInStackLocked()) {
4758                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4759                            null, "finish-heavy", true);
4760                }
4761            }
4762
4763            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4764                    mHeavyWeightProcess.userId, 0));
4765            mHeavyWeightProcess = null;
4766        }
4767    }
4768
4769    @Override
4770    public void crashApplication(int uid, int initialPid, String packageName,
4771            String message) {
4772        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4773                != PackageManager.PERMISSION_GRANTED) {
4774            String msg = "Permission Denial: crashApplication() from pid="
4775                    + Binder.getCallingPid()
4776                    + ", uid=" + Binder.getCallingUid()
4777                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4778            Slog.w(TAG, msg);
4779            throw new SecurityException(msg);
4780        }
4781
4782        synchronized(this) {
4783            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4784        }
4785    }
4786
4787    @Override
4788    public final void finishSubActivity(IBinder token, String resultWho,
4789            int requestCode) {
4790        synchronized(this) {
4791            final long origId = Binder.clearCallingIdentity();
4792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4793            if (r != null) {
4794                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4795            }
4796            Binder.restoreCallingIdentity(origId);
4797        }
4798    }
4799
4800    @Override
4801    public boolean finishActivityAffinity(IBinder token) {
4802        synchronized(this) {
4803            final long origId = Binder.clearCallingIdentity();
4804            try {
4805                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4806                if (r == null) {
4807                    return false;
4808                }
4809
4810                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4811                // can finish.
4812                final TaskRecord task = r.task;
4813                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4814                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4815                    mStackSupervisor.showLockTaskToast();
4816                    return false;
4817                }
4818                return task.stack.finishActivityAffinityLocked(r);
4819            } finally {
4820                Binder.restoreCallingIdentity(origId);
4821            }
4822        }
4823    }
4824
4825    @Override
4826    public void finishVoiceTask(IVoiceInteractionSession session) {
4827        synchronized (this) {
4828            final long origId = Binder.clearCallingIdentity();
4829            try {
4830                // TODO: VI Consider treating local voice interactions and voice tasks
4831                // differently here
4832                mStackSupervisor.finishVoiceTask(session);
4833            } finally {
4834                Binder.restoreCallingIdentity(origId);
4835            }
4836        }
4837
4838    }
4839
4840    @Override
4841    public boolean releaseActivityInstance(IBinder token) {
4842        synchronized(this) {
4843            final long origId = Binder.clearCallingIdentity();
4844            try {
4845                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4846                if (r == null) {
4847                    return false;
4848                }
4849                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4850            } finally {
4851                Binder.restoreCallingIdentity(origId);
4852            }
4853        }
4854    }
4855
4856    @Override
4857    public void releaseSomeActivities(IApplicationThread appInt) {
4858        synchronized(this) {
4859            final long origId = Binder.clearCallingIdentity();
4860            try {
4861                ProcessRecord app = getRecordForAppLocked(appInt);
4862                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4863            } finally {
4864                Binder.restoreCallingIdentity(origId);
4865            }
4866        }
4867    }
4868
4869    @Override
4870    public boolean willActivityBeVisible(IBinder token) {
4871        synchronized(this) {
4872            ActivityStack stack = ActivityRecord.getStackLocked(token);
4873            if (stack != null) {
4874                return stack.willActivityBeVisibleLocked(token);
4875            }
4876            return false;
4877        }
4878    }
4879
4880    @Override
4881    public void overridePendingTransition(IBinder token, String packageName,
4882            int enterAnim, int exitAnim) {
4883        synchronized(this) {
4884            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4885            if (self == null) {
4886                return;
4887            }
4888
4889            final long origId = Binder.clearCallingIdentity();
4890
4891            if (self.state == ActivityState.RESUMED
4892                    || self.state == ActivityState.PAUSING) {
4893                mWindowManager.overridePendingAppTransition(packageName,
4894                        enterAnim, exitAnim, null);
4895            }
4896
4897            Binder.restoreCallingIdentity(origId);
4898        }
4899    }
4900
4901    /**
4902     * Main function for removing an existing process from the activity manager
4903     * as a result of that process going away.  Clears out all connections
4904     * to the process.
4905     */
4906    private final void handleAppDiedLocked(ProcessRecord app,
4907            boolean restarting, boolean allowRestart) {
4908        int pid = app.pid;
4909        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4910        if (!kept && !restarting) {
4911            removeLruProcessLocked(app);
4912            if (pid > 0) {
4913                ProcessList.remove(pid);
4914            }
4915        }
4916
4917        if (mProfileProc == app) {
4918            clearProfilerLocked();
4919        }
4920
4921        // Remove this application's activities from active lists.
4922        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4923
4924        app.activities.clear();
4925
4926        if (app.instrumentationClass != null) {
4927            Slog.w(TAG, "Crash of app " + app.processName
4928                  + " running instrumentation " + app.instrumentationClass);
4929            Bundle info = new Bundle();
4930            info.putString("shortMsg", "Process crashed.");
4931            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4932        }
4933
4934        if (!restarting && hasVisibleActivities
4935                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4936            // If there was nothing to resume, and we are not already restarting this process, but
4937            // there is a visible activity that is hosted by the process...  then make sure all
4938            // visible activities are running, taking care of restarting this process.
4939            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4940        }
4941    }
4942
4943    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4944        IBinder threadBinder = thread.asBinder();
4945        // Find the application record.
4946        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4947            ProcessRecord rec = mLruProcesses.get(i);
4948            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4949                return i;
4950            }
4951        }
4952        return -1;
4953    }
4954
4955    final ProcessRecord getRecordForAppLocked(
4956            IApplicationThread thread) {
4957        if (thread == null) {
4958            return null;
4959        }
4960
4961        int appIndex = getLRURecordIndexForAppLocked(thread);
4962        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4963    }
4964
4965    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4966        // If there are no longer any background processes running,
4967        // and the app that died was not running instrumentation,
4968        // then tell everyone we are now low on memory.
4969        boolean haveBg = false;
4970        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4971            ProcessRecord rec = mLruProcesses.get(i);
4972            if (rec.thread != null
4973                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4974                haveBg = true;
4975                break;
4976            }
4977        }
4978
4979        if (!haveBg) {
4980            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4981            if (doReport) {
4982                long now = SystemClock.uptimeMillis();
4983                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4984                    doReport = false;
4985                } else {
4986                    mLastMemUsageReportTime = now;
4987                }
4988            }
4989            final ArrayList<ProcessMemInfo> memInfos
4990                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4991            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4992            long now = SystemClock.uptimeMillis();
4993            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4994                ProcessRecord rec = mLruProcesses.get(i);
4995                if (rec == dyingProc || rec.thread == null) {
4996                    continue;
4997                }
4998                if (doReport) {
4999                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5000                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5001                }
5002                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5003                    // The low memory report is overriding any current
5004                    // state for a GC request.  Make sure to do
5005                    // heavy/important/visible/foreground processes first.
5006                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5007                        rec.lastRequestedGc = 0;
5008                    } else {
5009                        rec.lastRequestedGc = rec.lastLowMemory;
5010                    }
5011                    rec.reportLowMemory = true;
5012                    rec.lastLowMemory = now;
5013                    mProcessesToGc.remove(rec);
5014                    addProcessToGcListLocked(rec);
5015                }
5016            }
5017            if (doReport) {
5018                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5019                mHandler.sendMessage(msg);
5020            }
5021            scheduleAppGcsLocked();
5022        }
5023    }
5024
5025    final void appDiedLocked(ProcessRecord app) {
5026       appDiedLocked(app, app.pid, app.thread, false);
5027    }
5028
5029    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5030            boolean fromBinderDied) {
5031        // First check if this ProcessRecord is actually active for the pid.
5032        synchronized (mPidsSelfLocked) {
5033            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5034            if (curProc != app) {
5035                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5036                return;
5037            }
5038        }
5039
5040        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5041        synchronized (stats) {
5042            stats.noteProcessDiedLocked(app.info.uid, pid);
5043        }
5044
5045        if (!app.killed) {
5046            if (!fromBinderDied) {
5047                Process.killProcessQuiet(pid);
5048            }
5049            killProcessGroup(app.uid, pid);
5050            app.killed = true;
5051        }
5052
5053        // Clean up already done if the process has been re-started.
5054        if (app.pid == pid && app.thread != null &&
5055                app.thread.asBinder() == thread.asBinder()) {
5056            boolean doLowMem = app.instrumentationClass == null;
5057            boolean doOomAdj = doLowMem;
5058            if (!app.killedByAm) {
5059                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5060                        + ") has died");
5061                mAllowLowerMemLevel = true;
5062            } else {
5063                // Note that we always want to do oom adj to update our state with the
5064                // new number of procs.
5065                mAllowLowerMemLevel = false;
5066                doLowMem = false;
5067            }
5068            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5069            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5070                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5071            handleAppDiedLocked(app, false, true);
5072
5073            if (doOomAdj) {
5074                updateOomAdjLocked();
5075            }
5076            if (doLowMem) {
5077                doLowMemReportIfNeededLocked(app);
5078            }
5079        } else if (app.pid != pid) {
5080            // A new process has already been started.
5081            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5082                    + ") has died and restarted (pid " + app.pid + ").");
5083            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5084        } else if (DEBUG_PROCESSES) {
5085            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5086                    + thread.asBinder());
5087        }
5088    }
5089
5090    /**
5091     * If a stack trace dump file is configured, dump process stack traces.
5092     * @param clearTraces causes the dump file to be erased prior to the new
5093     *    traces being written, if true; when false, the new traces will be
5094     *    appended to any existing file content.
5095     * @param firstPids of dalvik VM processes to dump stack traces for first
5096     * @param lastPids of dalvik VM processes to dump stack traces for last
5097     * @param nativeProcs optional list of native process names to dump stack crawls
5098     * @return file containing stack traces, or null if no dump file is configured
5099     */
5100    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5101            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5102        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5103        if (tracesPath == null || tracesPath.length() == 0) {
5104            return null;
5105        }
5106
5107        File tracesFile = new File(tracesPath);
5108        try {
5109            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5110            tracesFile.createNewFile();
5111            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5112        } catch (IOException e) {
5113            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5114            return null;
5115        }
5116
5117        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5118        return tracesFile;
5119    }
5120
5121    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5122            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5123        // Use a FileObserver to detect when traces finish writing.
5124        // The order of traces is considered important to maintain for legibility.
5125        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5126            @Override
5127            public synchronized void onEvent(int event, String path) { notify(); }
5128        };
5129
5130        try {
5131            observer.startWatching();
5132
5133            // First collect all of the stacks of the most important pids.
5134            if (firstPids != null) {
5135                try {
5136                    int num = firstPids.size();
5137                    for (int i = 0; i < num; i++) {
5138                        synchronized (observer) {
5139                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5140                                    + firstPids.get(i));
5141                            final long sime = SystemClock.elapsedRealtime();
5142                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5143                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5144                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5145                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5146                        }
5147                    }
5148                } catch (InterruptedException e) {
5149                    Slog.wtf(TAG, e);
5150                }
5151            }
5152
5153            // Next collect the stacks of the native pids
5154            if (nativeProcs != null) {
5155                int[] pids = Process.getPidsForCommands(nativeProcs);
5156                if (pids != null) {
5157                    for (int pid : pids) {
5158                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5159                        final long sime = SystemClock.elapsedRealtime();
5160                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5161                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5162                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5163                    }
5164                }
5165            }
5166
5167            // Lastly, measure CPU usage.
5168            if (processCpuTracker != null) {
5169                processCpuTracker.init();
5170                System.gc();
5171                processCpuTracker.update();
5172                try {
5173                    synchronized (processCpuTracker) {
5174                        processCpuTracker.wait(500); // measure over 1/2 second.
5175                    }
5176                } catch (InterruptedException e) {
5177                }
5178                processCpuTracker.update();
5179
5180                // We'll take the stack crawls of just the top apps using CPU.
5181                final int N = processCpuTracker.countWorkingStats();
5182                int numProcs = 0;
5183                for (int i=0; i<N && numProcs<5; i++) {
5184                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5185                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5186                        numProcs++;
5187                        try {
5188                            synchronized (observer) {
5189                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5190                                        + stats.pid);
5191                                final long stime = SystemClock.elapsedRealtime();
5192                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5193                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5194                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5195                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5196                            }
5197                        } catch (InterruptedException e) {
5198                            Slog.wtf(TAG, e);
5199                        }
5200                    } else if (DEBUG_ANR) {
5201                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5202                                + stats.pid);
5203                    }
5204                }
5205            }
5206        } finally {
5207            observer.stopWatching();
5208        }
5209    }
5210
5211    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5212        if (true || IS_USER_BUILD) {
5213            return;
5214        }
5215        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5216        if (tracesPath == null || tracesPath.length() == 0) {
5217            return;
5218        }
5219
5220        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5221        StrictMode.allowThreadDiskWrites();
5222        try {
5223            final File tracesFile = new File(tracesPath);
5224            final File tracesDir = tracesFile.getParentFile();
5225            final File tracesTmp = new File(tracesDir, "__tmp__");
5226            try {
5227                if (tracesFile.exists()) {
5228                    tracesTmp.delete();
5229                    tracesFile.renameTo(tracesTmp);
5230                }
5231                StringBuilder sb = new StringBuilder();
5232                Time tobj = new Time();
5233                tobj.set(System.currentTimeMillis());
5234                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5235                sb.append(": ");
5236                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5237                sb.append(" since ");
5238                sb.append(msg);
5239                FileOutputStream fos = new FileOutputStream(tracesFile);
5240                fos.write(sb.toString().getBytes());
5241                if (app == null) {
5242                    fos.write("\n*** No application process!".getBytes());
5243                }
5244                fos.close();
5245                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5246            } catch (IOException e) {
5247                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5248                return;
5249            }
5250
5251            if (app != null) {
5252                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5253                firstPids.add(app.pid);
5254                dumpStackTraces(tracesPath, firstPids, null, null, null);
5255            }
5256
5257            File lastTracesFile = null;
5258            File curTracesFile = null;
5259            for (int i=9; i>=0; i--) {
5260                String name = String.format(Locale.US, "slow%02d.txt", i);
5261                curTracesFile = new File(tracesDir, name);
5262                if (curTracesFile.exists()) {
5263                    if (lastTracesFile != null) {
5264                        curTracesFile.renameTo(lastTracesFile);
5265                    } else {
5266                        curTracesFile.delete();
5267                    }
5268                }
5269                lastTracesFile = curTracesFile;
5270            }
5271            tracesFile.renameTo(curTracesFile);
5272            if (tracesTmp.exists()) {
5273                tracesTmp.renameTo(tracesFile);
5274            }
5275        } finally {
5276            StrictMode.setThreadPolicy(oldPolicy);
5277        }
5278    }
5279
5280    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5281        if (!mLaunchWarningShown) {
5282            mLaunchWarningShown = true;
5283            mUiHandler.post(new Runnable() {
5284                @Override
5285                public void run() {
5286                    synchronized (ActivityManagerService.this) {
5287                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5288                        d.show();
5289                        mUiHandler.postDelayed(new Runnable() {
5290                            @Override
5291                            public void run() {
5292                                synchronized (ActivityManagerService.this) {
5293                                    d.dismiss();
5294                                    mLaunchWarningShown = false;
5295                                }
5296                            }
5297                        }, 4000);
5298                    }
5299                }
5300            });
5301        }
5302    }
5303
5304    @Override
5305    public boolean clearApplicationUserData(final String packageName,
5306            final IPackageDataObserver observer, int userId) {
5307        enforceNotIsolatedCaller("clearApplicationUserData");
5308        int uid = Binder.getCallingUid();
5309        int pid = Binder.getCallingPid();
5310        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5311                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5312
5313        final DevicePolicyManagerInternal dpmi = LocalServices
5314                .getService(DevicePolicyManagerInternal.class);
5315        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5316            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5317        }
5318
5319        long callingId = Binder.clearCallingIdentity();
5320        try {
5321            IPackageManager pm = AppGlobals.getPackageManager();
5322            int pkgUid = -1;
5323            synchronized(this) {
5324                try {
5325                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5326                } catch (RemoteException e) {
5327                }
5328                if (pkgUid == -1) {
5329                    Slog.w(TAG, "Invalid packageName: " + packageName);
5330                    if (observer != null) {
5331                        try {
5332                            observer.onRemoveCompleted(packageName, false);
5333                        } catch (RemoteException e) {
5334                            Slog.i(TAG, "Observer no longer exists.");
5335                        }
5336                    }
5337                    return false;
5338                }
5339                if (uid == pkgUid || checkComponentPermission(
5340                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5341                        pid, uid, -1, true)
5342                        == PackageManager.PERMISSION_GRANTED) {
5343                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5344                } else {
5345                    throw new SecurityException("PID " + pid + " does not have permission "
5346                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5347                                    + " of package " + packageName);
5348                }
5349
5350                // Remove all tasks match the cleared application package and user
5351                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5352                    final TaskRecord tr = mRecentTasks.get(i);
5353                    final String taskPackageName =
5354                            tr.getBaseIntent().getComponent().getPackageName();
5355                    if (tr.userId != userId) continue;
5356                    if (!taskPackageName.equals(packageName)) continue;
5357                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5358                }
5359            }
5360
5361            try {
5362                // Clear application user data
5363                pm.clearApplicationUserData(packageName, observer, userId);
5364
5365                synchronized(this) {
5366                    // Remove all permissions granted from/to this package
5367                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5368                }
5369
5370                // Remove all zen rules created by this package; revoke it's zen access.
5371                INotificationManager inm = NotificationManager.getService();
5372                inm.removeAutomaticZenRules(packageName);
5373                inm.setNotificationPolicyAccessGranted(packageName, false);
5374
5375                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5376                        Uri.fromParts("package", packageName, null));
5377                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5378                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5379                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5380                        null, null, 0, null, null, null, null, false, false, userId);
5381            } catch (RemoteException e) {
5382            }
5383        } finally {
5384            Binder.restoreCallingIdentity(callingId);
5385        }
5386        return true;
5387    }
5388
5389    @Override
5390    public void killBackgroundProcesses(final String packageName, int userId) {
5391        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5392                != PackageManager.PERMISSION_GRANTED &&
5393                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5394                        != PackageManager.PERMISSION_GRANTED) {
5395            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5396                    + Binder.getCallingPid()
5397                    + ", uid=" + Binder.getCallingUid()
5398                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5399            Slog.w(TAG, msg);
5400            throw new SecurityException(msg);
5401        }
5402
5403        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5404                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5405        long callingId = Binder.clearCallingIdentity();
5406        try {
5407            IPackageManager pm = AppGlobals.getPackageManager();
5408            synchronized(this) {
5409                int appId = -1;
5410                try {
5411                    appId = UserHandle.getAppId(
5412                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5413                } catch (RemoteException e) {
5414                }
5415                if (appId == -1) {
5416                    Slog.w(TAG, "Invalid packageName: " + packageName);
5417                    return;
5418                }
5419                killPackageProcessesLocked(packageName, appId, userId,
5420                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5421            }
5422        } finally {
5423            Binder.restoreCallingIdentity(callingId);
5424        }
5425    }
5426
5427    @Override
5428    public void killAllBackgroundProcesses() {
5429        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5430                != PackageManager.PERMISSION_GRANTED) {
5431            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5432                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5433                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5434            Slog.w(TAG, msg);
5435            throw new SecurityException(msg);
5436        }
5437
5438        final long callingId = Binder.clearCallingIdentity();
5439        try {
5440            synchronized (this) {
5441                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5442                final int NP = mProcessNames.getMap().size();
5443                for (int ip = 0; ip < NP; ip++) {
5444                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5445                    final int NA = apps.size();
5446                    for (int ia = 0; ia < NA; ia++) {
5447                        final ProcessRecord app = apps.valueAt(ia);
5448                        if (app.persistent) {
5449                            // We don't kill persistent processes.
5450                            continue;
5451                        }
5452                        if (app.removed) {
5453                            procs.add(app);
5454                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5455                            app.removed = true;
5456                            procs.add(app);
5457                        }
5458                    }
5459                }
5460
5461                final int N = procs.size();
5462                for (int i = 0; i < N; i++) {
5463                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5464                }
5465
5466                mAllowLowerMemLevel = true;
5467
5468                updateOomAdjLocked();
5469                doLowMemReportIfNeededLocked(null);
5470            }
5471        } finally {
5472            Binder.restoreCallingIdentity(callingId);
5473        }
5474    }
5475
5476    /**
5477     * Kills all background processes, except those matching any of the
5478     * specified properties.
5479     *
5480     * @param minTargetSdk the target SDK version at or above which to preserve
5481     *                     processes, or {@code -1} to ignore the target SDK
5482     * @param maxProcState the process state at or below which to preserve
5483     *                     processes, or {@code -1} to ignore the process state
5484     */
5485    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5486        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5487                != PackageManager.PERMISSION_GRANTED) {
5488            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5489                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5490                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5491            Slog.w(TAG, msg);
5492            throw new SecurityException(msg);
5493        }
5494
5495        final long callingId = Binder.clearCallingIdentity();
5496        try {
5497            synchronized (this) {
5498                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5499                final int NP = mProcessNames.getMap().size();
5500                for (int ip = 0; ip < NP; ip++) {
5501                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5502                    final int NA = apps.size();
5503                    for (int ia = 0; ia < NA; ia++) {
5504                        final ProcessRecord app = apps.valueAt(ia);
5505                        if (app.removed) {
5506                            procs.add(app);
5507                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5508                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5509                            app.removed = true;
5510                            procs.add(app);
5511                        }
5512                    }
5513                }
5514
5515                final int N = procs.size();
5516                for (int i = 0; i < N; i++) {
5517                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5518                }
5519            }
5520        } finally {
5521            Binder.restoreCallingIdentity(callingId);
5522        }
5523    }
5524
5525    @Override
5526    public void forceStopPackage(final String packageName, int userId) {
5527        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5528                != PackageManager.PERMISSION_GRANTED) {
5529            String msg = "Permission Denial: forceStopPackage() from pid="
5530                    + Binder.getCallingPid()
5531                    + ", uid=" + Binder.getCallingUid()
5532                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5533            Slog.w(TAG, msg);
5534            throw new SecurityException(msg);
5535        }
5536        final int callingPid = Binder.getCallingPid();
5537        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5538                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5539        long callingId = Binder.clearCallingIdentity();
5540        try {
5541            IPackageManager pm = AppGlobals.getPackageManager();
5542            synchronized(this) {
5543                int[] users = userId == UserHandle.USER_ALL
5544                        ? mUserController.getUsers() : new int[] { userId };
5545                for (int user : users) {
5546                    int pkgUid = -1;
5547                    try {
5548                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5549                                user);
5550                    } catch (RemoteException e) {
5551                    }
5552                    if (pkgUid == -1) {
5553                        Slog.w(TAG, "Invalid packageName: " + packageName);
5554                        continue;
5555                    }
5556                    try {
5557                        pm.setPackageStoppedState(packageName, true, user);
5558                    } catch (RemoteException e) {
5559                    } catch (IllegalArgumentException e) {
5560                        Slog.w(TAG, "Failed trying to unstop package "
5561                                + packageName + ": " + e);
5562                    }
5563                    if (mUserController.isUserRunningLocked(user, 0)) {
5564                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5565                    }
5566                }
5567            }
5568        } finally {
5569            Binder.restoreCallingIdentity(callingId);
5570        }
5571    }
5572
5573    @Override
5574    public void addPackageDependency(String packageName) {
5575        synchronized (this) {
5576            int callingPid = Binder.getCallingPid();
5577            if (callingPid == Process.myPid()) {
5578                //  Yeah, um, no.
5579                return;
5580            }
5581            ProcessRecord proc;
5582            synchronized (mPidsSelfLocked) {
5583                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5584            }
5585            if (proc != null) {
5586                if (proc.pkgDeps == null) {
5587                    proc.pkgDeps = new ArraySet<String>(1);
5588                }
5589                proc.pkgDeps.add(packageName);
5590            }
5591        }
5592    }
5593
5594    /*
5595     * The pkg name and app id have to be specified.
5596     */
5597    @Override
5598    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5599        if (pkg == null) {
5600            return;
5601        }
5602        // Make sure the uid is valid.
5603        if (appid < 0) {
5604            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5605            return;
5606        }
5607        int callerUid = Binder.getCallingUid();
5608        // Only the system server can kill an application
5609        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5610            // Post an aysnc message to kill the application
5611            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5612            msg.arg1 = appid;
5613            msg.arg2 = 0;
5614            Bundle bundle = new Bundle();
5615            bundle.putString("pkg", pkg);
5616            bundle.putString("reason", reason);
5617            msg.obj = bundle;
5618            mHandler.sendMessage(msg);
5619        } else {
5620            throw new SecurityException(callerUid + " cannot kill pkg: " +
5621                    pkg);
5622        }
5623    }
5624
5625    @Override
5626    public void closeSystemDialogs(String reason) {
5627        enforceNotIsolatedCaller("closeSystemDialogs");
5628
5629        final int pid = Binder.getCallingPid();
5630        final int uid = Binder.getCallingUid();
5631        final long origId = Binder.clearCallingIdentity();
5632        try {
5633            synchronized (this) {
5634                // Only allow this from foreground processes, so that background
5635                // applications can't abuse it to prevent system UI from being shown.
5636                if (uid >= Process.FIRST_APPLICATION_UID) {
5637                    ProcessRecord proc;
5638                    synchronized (mPidsSelfLocked) {
5639                        proc = mPidsSelfLocked.get(pid);
5640                    }
5641                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5642                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5643                                + " from background process " + proc);
5644                        return;
5645                    }
5646                }
5647                closeSystemDialogsLocked(reason);
5648            }
5649        } finally {
5650            Binder.restoreCallingIdentity(origId);
5651        }
5652    }
5653
5654    void closeSystemDialogsLocked(String reason) {
5655        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5656        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5657                | Intent.FLAG_RECEIVER_FOREGROUND);
5658        if (reason != null) {
5659            intent.putExtra("reason", reason);
5660        }
5661        mWindowManager.closeSystemDialogs(reason);
5662
5663        mStackSupervisor.closeSystemDialogsLocked();
5664
5665        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5666                AppOpsManager.OP_NONE, null, false, false,
5667                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5668    }
5669
5670    @Override
5671    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5672        enforceNotIsolatedCaller("getProcessMemoryInfo");
5673        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5674        for (int i=pids.length-1; i>=0; i--) {
5675            ProcessRecord proc;
5676            int oomAdj;
5677            synchronized (this) {
5678                synchronized (mPidsSelfLocked) {
5679                    proc = mPidsSelfLocked.get(pids[i]);
5680                    oomAdj = proc != null ? proc.setAdj : 0;
5681                }
5682            }
5683            infos[i] = new Debug.MemoryInfo();
5684            Debug.getMemoryInfo(pids[i], infos[i]);
5685            if (proc != null) {
5686                synchronized (this) {
5687                    if (proc.thread != null && proc.setAdj == oomAdj) {
5688                        // Record this for posterity if the process has been stable.
5689                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5690                                infos[i].getTotalUss(), false, proc.pkgList);
5691                    }
5692                }
5693            }
5694        }
5695        return infos;
5696    }
5697
5698    @Override
5699    public long[] getProcessPss(int[] pids) {
5700        enforceNotIsolatedCaller("getProcessPss");
5701        long[] pss = new long[pids.length];
5702        for (int i=pids.length-1; i>=0; i--) {
5703            ProcessRecord proc;
5704            int oomAdj;
5705            synchronized (this) {
5706                synchronized (mPidsSelfLocked) {
5707                    proc = mPidsSelfLocked.get(pids[i]);
5708                    oomAdj = proc != null ? proc.setAdj : 0;
5709                }
5710            }
5711            long[] tmpUss = new long[1];
5712            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5713            if (proc != null) {
5714                synchronized (this) {
5715                    if (proc.thread != null && proc.setAdj == oomAdj) {
5716                        // Record this for posterity if the process has been stable.
5717                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5718                    }
5719                }
5720            }
5721        }
5722        return pss;
5723    }
5724
5725    @Override
5726    public void killApplicationProcess(String processName, int uid) {
5727        if (processName == null) {
5728            return;
5729        }
5730
5731        int callerUid = Binder.getCallingUid();
5732        // Only the system server can kill an application
5733        if (callerUid == Process.SYSTEM_UID) {
5734            synchronized (this) {
5735                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5736                if (app != null && app.thread != null) {
5737                    try {
5738                        app.thread.scheduleSuicide();
5739                    } catch (RemoteException e) {
5740                        // If the other end already died, then our work here is done.
5741                    }
5742                } else {
5743                    Slog.w(TAG, "Process/uid not found attempting kill of "
5744                            + processName + " / " + uid);
5745                }
5746            }
5747        } else {
5748            throw new SecurityException(callerUid + " cannot kill app process: " +
5749                    processName);
5750        }
5751    }
5752
5753    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5754        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5755                false, true, false, false, UserHandle.getUserId(uid), reason);
5756        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5757                Uri.fromParts("package", packageName, null));
5758        if (!mProcessesReady) {
5759            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5760                    | Intent.FLAG_RECEIVER_FOREGROUND);
5761        }
5762        intent.putExtra(Intent.EXTRA_UID, uid);
5763        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5764        broadcastIntentLocked(null, null, intent,
5765                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5766                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5767    }
5768
5769
5770    private final boolean killPackageProcessesLocked(String packageName, int appId,
5771            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5772            boolean doit, boolean evenPersistent, String reason) {
5773        ArrayList<ProcessRecord> procs = new ArrayList<>();
5774
5775        // Remove all processes this package may have touched: all with the
5776        // same UID (except for the system or root user), and all whose name
5777        // matches the package name.
5778        final int NP = mProcessNames.getMap().size();
5779        for (int ip=0; ip<NP; ip++) {
5780            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5781            final int NA = apps.size();
5782            for (int ia=0; ia<NA; ia++) {
5783                ProcessRecord app = apps.valueAt(ia);
5784                if (app.persistent && !evenPersistent) {
5785                    // we don't kill persistent processes
5786                    continue;
5787                }
5788                if (app.removed) {
5789                    if (doit) {
5790                        procs.add(app);
5791                    }
5792                    continue;
5793                }
5794
5795                // Skip process if it doesn't meet our oom adj requirement.
5796                if (app.setAdj < minOomAdj) {
5797                    continue;
5798                }
5799
5800                // If no package is specified, we call all processes under the
5801                // give user id.
5802                if (packageName == null) {
5803                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5804                        continue;
5805                    }
5806                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5807                        continue;
5808                    }
5809                // Package has been specified, we want to hit all processes
5810                // that match it.  We need to qualify this by the processes
5811                // that are running under the specified app and user ID.
5812                } else {
5813                    final boolean isDep = app.pkgDeps != null
5814                            && app.pkgDeps.contains(packageName);
5815                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5816                        continue;
5817                    }
5818                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5819                        continue;
5820                    }
5821                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5822                        continue;
5823                    }
5824                }
5825
5826                // Process has passed all conditions, kill it!
5827                if (!doit) {
5828                    return true;
5829                }
5830                app.removed = true;
5831                procs.add(app);
5832            }
5833        }
5834
5835        int N = procs.size();
5836        for (int i=0; i<N; i++) {
5837            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5838        }
5839        updateOomAdjLocked();
5840        return N > 0;
5841    }
5842
5843    private void cleanupDisabledPackageComponentsLocked(
5844            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5845
5846        Set<String> disabledClasses = null;
5847        boolean packageDisabled = false;
5848        IPackageManager pm = AppGlobals.getPackageManager();
5849
5850        if (changedClasses == null) {
5851            // Nothing changed...
5852            return;
5853        }
5854
5855        // Determine enable/disable state of the package and its components.
5856        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5857        for (int i = changedClasses.length - 1; i >= 0; i--) {
5858            final String changedClass = changedClasses[i];
5859
5860            if (changedClass.equals(packageName)) {
5861                try {
5862                    // Entire package setting changed
5863                    enabled = pm.getApplicationEnabledSetting(packageName,
5864                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5865                } catch (Exception e) {
5866                    // No such package/component; probably racing with uninstall.  In any
5867                    // event it means we have nothing further to do here.
5868                    return;
5869                }
5870                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5871                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5872                if (packageDisabled) {
5873                    // Entire package is disabled.
5874                    // No need to continue to check component states.
5875                    disabledClasses = null;
5876                    break;
5877                }
5878            } else {
5879                try {
5880                    enabled = pm.getComponentEnabledSetting(
5881                            new ComponentName(packageName, changedClass),
5882                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5883                } catch (Exception e) {
5884                    // As above, probably racing with uninstall.
5885                    return;
5886                }
5887                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5888                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5889                    if (disabledClasses == null) {
5890                        disabledClasses = new ArraySet<>(changedClasses.length);
5891                    }
5892                    disabledClasses.add(changedClass);
5893                }
5894            }
5895        }
5896
5897        if (!packageDisabled && disabledClasses == null) {
5898            // Nothing to do here...
5899            return;
5900        }
5901
5902        // Clean-up disabled activities.
5903        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5904                packageName, disabledClasses, true, false, userId) && mBooted) {
5905            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5906            mStackSupervisor.scheduleIdleLocked();
5907        }
5908
5909        // Clean-up disabled tasks
5910        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5911
5912        // Clean-up disabled services.
5913        mServices.bringDownDisabledPackageServicesLocked(
5914                packageName, disabledClasses, userId, false, killProcess, true);
5915
5916        // Clean-up disabled providers.
5917        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5918        mProviderMap.collectPackageProvidersLocked(
5919                packageName, disabledClasses, true, false, userId, providers);
5920        for (int i = providers.size() - 1; i >= 0; i--) {
5921            removeDyingProviderLocked(null, providers.get(i), true);
5922        }
5923
5924        // Clean-up disabled broadcast receivers.
5925        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5926            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5927                    packageName, disabledClasses, userId, true);
5928        }
5929
5930    }
5931
5932    final boolean forceStopPackageLocked(String packageName, int appId,
5933            boolean callerWillRestart, boolean purgeCache, boolean doit,
5934            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5935        int i;
5936
5937        if (userId == UserHandle.USER_ALL && packageName == null) {
5938            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5939        }
5940
5941        if (appId < 0 && packageName != null) {
5942            try {
5943                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5944                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5945            } catch (RemoteException e) {
5946            }
5947        }
5948
5949        if (doit) {
5950            if (packageName != null) {
5951                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5952                        + " user=" + userId + ": " + reason);
5953            } else {
5954                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5955            }
5956
5957            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5958        }
5959
5960        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5961                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5962                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5963
5964        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5965                packageName, null, doit, evenPersistent, userId)) {
5966            if (!doit) {
5967                return true;
5968            }
5969            didSomething = true;
5970        }
5971
5972        if (mServices.bringDownDisabledPackageServicesLocked(
5973                packageName, null, userId, evenPersistent, true, doit)) {
5974            if (!doit) {
5975                return true;
5976            }
5977            didSomething = true;
5978        }
5979
5980        if (packageName == null) {
5981            // Remove all sticky broadcasts from this user.
5982            mStickyBroadcasts.remove(userId);
5983        }
5984
5985        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5986        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5987                userId, providers)) {
5988            if (!doit) {
5989                return true;
5990            }
5991            didSomething = true;
5992        }
5993        for (i = providers.size() - 1; i >= 0; i--) {
5994            removeDyingProviderLocked(null, providers.get(i), true);
5995        }
5996
5997        // Remove transient permissions granted from/to this package/user
5998        removeUriPermissionsForPackageLocked(packageName, userId, false);
5999
6000        if (doit) {
6001            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6002                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6003                        packageName, null, userId, doit);
6004            }
6005        }
6006
6007        if (packageName == null || uninstalling) {
6008            // Remove pending intents.  For now we only do this when force
6009            // stopping users, because we have some problems when doing this
6010            // for packages -- app widgets are not currently cleaned up for
6011            // such packages, so they can be left with bad pending intents.
6012            if (mIntentSenderRecords.size() > 0) {
6013                Iterator<WeakReference<PendingIntentRecord>> it
6014                        = mIntentSenderRecords.values().iterator();
6015                while (it.hasNext()) {
6016                    WeakReference<PendingIntentRecord> wpir = it.next();
6017                    if (wpir == null) {
6018                        it.remove();
6019                        continue;
6020                    }
6021                    PendingIntentRecord pir = wpir.get();
6022                    if (pir == null) {
6023                        it.remove();
6024                        continue;
6025                    }
6026                    if (packageName == null) {
6027                        // Stopping user, remove all objects for the user.
6028                        if (pir.key.userId != userId) {
6029                            // Not the same user, skip it.
6030                            continue;
6031                        }
6032                    } else {
6033                        if (UserHandle.getAppId(pir.uid) != appId) {
6034                            // Different app id, skip it.
6035                            continue;
6036                        }
6037                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6038                            // Different user, skip it.
6039                            continue;
6040                        }
6041                        if (!pir.key.packageName.equals(packageName)) {
6042                            // Different package, skip it.
6043                            continue;
6044                        }
6045                    }
6046                    if (!doit) {
6047                        return true;
6048                    }
6049                    didSomething = true;
6050                    it.remove();
6051                    pir.canceled = true;
6052                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6053                        pir.key.activity.pendingResults.remove(pir.ref);
6054                    }
6055                }
6056            }
6057        }
6058
6059        if (doit) {
6060            if (purgeCache && packageName != null) {
6061                AttributeCache ac = AttributeCache.instance();
6062                if (ac != null) {
6063                    ac.removePackage(packageName);
6064                }
6065            }
6066            if (mBooted) {
6067                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6068                mStackSupervisor.scheduleIdleLocked();
6069            }
6070        }
6071
6072        return didSomething;
6073    }
6074
6075    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6076        ProcessRecord old = mProcessNames.remove(name, uid);
6077        if (old != null) {
6078            old.uidRecord.numProcs--;
6079            if (old.uidRecord.numProcs == 0) {
6080                // No more processes using this uid, tell clients it is gone.
6081                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6082                        "No more processes in " + old.uidRecord);
6083                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6084                mActiveUids.remove(uid);
6085                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6086            }
6087            old.uidRecord = null;
6088        }
6089        mIsolatedProcesses.remove(uid);
6090        return old;
6091    }
6092
6093    private final void addProcessNameLocked(ProcessRecord proc) {
6094        // We shouldn't already have a process under this name, but just in case we
6095        // need to clean up whatever may be there now.
6096        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6097        if (old == proc && proc.persistent) {
6098            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6099            Slog.w(TAG, "Re-adding persistent process " + proc);
6100        } else if (old != null) {
6101            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6102        }
6103        UidRecord uidRec = mActiveUids.get(proc.uid);
6104        if (uidRec == null) {
6105            uidRec = new UidRecord(proc.uid);
6106            // This is the first appearance of the uid, report it now!
6107            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6108                    "Creating new process uid: " + uidRec);
6109            mActiveUids.put(proc.uid, uidRec);
6110            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6111            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6112        }
6113        proc.uidRecord = uidRec;
6114        uidRec.numProcs++;
6115        mProcessNames.put(proc.processName, proc.uid, proc);
6116        if (proc.isolated) {
6117            mIsolatedProcesses.put(proc.uid, proc);
6118        }
6119    }
6120
6121    boolean removeProcessLocked(ProcessRecord app,
6122            boolean callerWillRestart, boolean allowRestart, String reason) {
6123        final String name = app.processName;
6124        final int uid = app.uid;
6125        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6126            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6127
6128        removeProcessNameLocked(name, uid);
6129        if (mHeavyWeightProcess == app) {
6130            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6131                    mHeavyWeightProcess.userId, 0));
6132            mHeavyWeightProcess = null;
6133        }
6134        boolean needRestart = false;
6135        if (app.pid > 0 && app.pid != MY_PID) {
6136            int pid = app.pid;
6137            synchronized (mPidsSelfLocked) {
6138                mPidsSelfLocked.remove(pid);
6139                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6140            }
6141            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6142            if (app.isolated) {
6143                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6144            }
6145            boolean willRestart = false;
6146            if (app.persistent && !app.isolated) {
6147                if (!callerWillRestart) {
6148                    willRestart = true;
6149                } else {
6150                    needRestart = true;
6151                }
6152            }
6153            app.kill(reason, true);
6154            handleAppDiedLocked(app, willRestart, allowRestart);
6155            if (willRestart) {
6156                removeLruProcessLocked(app);
6157                addAppLocked(app.info, false, null /* ABI override */);
6158            }
6159        } else {
6160            mRemovedProcesses.add(app);
6161        }
6162
6163        return needRestart;
6164    }
6165
6166    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6167        cleanupAppInLaunchingProvidersLocked(app, true);
6168        removeProcessLocked(app, false, true, "timeout publishing content providers");
6169    }
6170
6171    private final void processStartTimedOutLocked(ProcessRecord app) {
6172        final int pid = app.pid;
6173        boolean gone = false;
6174        synchronized (mPidsSelfLocked) {
6175            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6176            if (knownApp != null && knownApp.thread == null) {
6177                mPidsSelfLocked.remove(pid);
6178                gone = true;
6179            }
6180        }
6181
6182        if (gone) {
6183            Slog.w(TAG, "Process " + app + " failed to attach");
6184            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6185                    pid, app.uid, app.processName);
6186            removeProcessNameLocked(app.processName, app.uid);
6187            if (mHeavyWeightProcess == app) {
6188                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6189                        mHeavyWeightProcess.userId, 0));
6190                mHeavyWeightProcess = null;
6191            }
6192            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6193            if (app.isolated) {
6194                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6195            }
6196            // Take care of any launching providers waiting for this process.
6197            cleanupAppInLaunchingProvidersLocked(app, true);
6198            // Take care of any services that are waiting for the process.
6199            mServices.processStartTimedOutLocked(app);
6200            app.kill("start timeout", true);
6201            removeLruProcessLocked(app);
6202            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6203                Slog.w(TAG, "Unattached app died before backup, skipping");
6204                try {
6205                    IBackupManager bm = IBackupManager.Stub.asInterface(
6206                            ServiceManager.getService(Context.BACKUP_SERVICE));
6207                    bm.agentDisconnected(app.info.packageName);
6208                } catch (RemoteException e) {
6209                    // Can't happen; the backup manager is local
6210                }
6211            }
6212            if (isPendingBroadcastProcessLocked(pid)) {
6213                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6214                skipPendingBroadcastLocked(pid);
6215            }
6216        } else {
6217            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6218        }
6219    }
6220
6221    private final boolean attachApplicationLocked(IApplicationThread thread,
6222            int pid) {
6223
6224        // Find the application record that is being attached...  either via
6225        // the pid if we are running in multiple processes, or just pull the
6226        // next app record if we are emulating process with anonymous threads.
6227        ProcessRecord app;
6228        if (pid != MY_PID && pid >= 0) {
6229            synchronized (mPidsSelfLocked) {
6230                app = mPidsSelfLocked.get(pid);
6231            }
6232        } else {
6233            app = null;
6234        }
6235
6236        if (app == null) {
6237            Slog.w(TAG, "No pending application record for pid " + pid
6238                    + " (IApplicationThread " + thread + "); dropping process");
6239            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6240            if (pid > 0 && pid != MY_PID) {
6241                Process.killProcessQuiet(pid);
6242                //TODO: killProcessGroup(app.info.uid, pid);
6243            } else {
6244                try {
6245                    thread.scheduleExit();
6246                } catch (Exception e) {
6247                    // Ignore exceptions.
6248                }
6249            }
6250            return false;
6251        }
6252
6253        // If this application record is still attached to a previous
6254        // process, clean it up now.
6255        if (app.thread != null) {
6256            handleAppDiedLocked(app, true, true);
6257        }
6258
6259        // Tell the process all about itself.
6260
6261        if (DEBUG_ALL) Slog.v(
6262                TAG, "Binding process pid " + pid + " to record " + app);
6263
6264        final String processName = app.processName;
6265        try {
6266            AppDeathRecipient adr = new AppDeathRecipient(
6267                    app, pid, thread);
6268            thread.asBinder().linkToDeath(adr, 0);
6269            app.deathRecipient = adr;
6270        } catch (RemoteException e) {
6271            app.resetPackageList(mProcessStats);
6272            startProcessLocked(app, "link fail", processName);
6273            return false;
6274        }
6275
6276        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6277
6278        app.makeActive(thread, mProcessStats);
6279        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6280        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6281        app.forcingToForeground = null;
6282        updateProcessForegroundLocked(app, false, false);
6283        app.hasShownUi = false;
6284        app.debugging = false;
6285        app.cached = false;
6286        app.killedByAm = false;
6287        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6288
6289        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6290
6291        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6292        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6293
6294        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6295            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6296            msg.obj = app;
6297            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6298        }
6299
6300        if (!normalMode) {
6301            Slog.i(TAG, "Launching preboot mode app: " + app);
6302        }
6303
6304        if (DEBUG_ALL) Slog.v(
6305            TAG, "New app record " + app
6306            + " thread=" + thread.asBinder() + " pid=" + pid);
6307        try {
6308            int testMode = IApplicationThread.DEBUG_OFF;
6309            if (mDebugApp != null && mDebugApp.equals(processName)) {
6310                testMode = mWaitForDebugger
6311                    ? IApplicationThread.DEBUG_WAIT
6312                    : IApplicationThread.DEBUG_ON;
6313                app.debugging = true;
6314                if (mDebugTransient) {
6315                    mDebugApp = mOrigDebugApp;
6316                    mWaitForDebugger = mOrigWaitForDebugger;
6317                }
6318            }
6319            String profileFile = app.instrumentationProfileFile;
6320            ParcelFileDescriptor profileFd = null;
6321            int samplingInterval = 0;
6322            boolean profileAutoStop = false;
6323            if (mProfileApp != null && mProfileApp.equals(processName)) {
6324                mProfileProc = app;
6325                profileFile = mProfileFile;
6326                profileFd = mProfileFd;
6327                samplingInterval = mSamplingInterval;
6328                profileAutoStop = mAutoStopProfiler;
6329            }
6330            boolean enableTrackAllocation = false;
6331            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6332                enableTrackAllocation = true;
6333                mTrackAllocationApp = null;
6334            }
6335
6336            // If the app is being launched for restore or full backup, set it up specially
6337            boolean isRestrictedBackupMode = false;
6338            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6339                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6340                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6341                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6342                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6343            }
6344
6345            notifyPackageUse(app.instrumentationInfo != null
6346                    ? app.instrumentationInfo.packageName
6347                    : app.info.packageName);
6348            if (app.instrumentationClass != null) {
6349                notifyPackageUse(app.instrumentationClass.getPackageName());
6350            }
6351            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6352                    + processName + " with config " + mConfiguration);
6353            ApplicationInfo appInfo = app.instrumentationInfo != null
6354                    ? app.instrumentationInfo : app.info;
6355            app.compat = compatibilityInfoForPackageLocked(appInfo);
6356            if (profileFd != null) {
6357                profileFd = profileFd.dup();
6358            }
6359            ProfilerInfo profilerInfo = profileFile == null ? null
6360                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6361            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6362                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6363                    app.instrumentationUiAutomationConnection, testMode,
6364                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6365                    isRestrictedBackupMode || !normalMode, app.persistent,
6366                    new Configuration(mConfiguration), app.compat,
6367                    getCommonServicesLocked(app.isolated),
6368                    mCoreSettingsObserver.getCoreSettingsLocked());
6369            updateLruProcessLocked(app, false, null);
6370            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6371        } catch (Exception e) {
6372            // todo: Yikes!  What should we do?  For now we will try to
6373            // start another process, but that could easily get us in
6374            // an infinite loop of restarting processes...
6375            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6376
6377            app.resetPackageList(mProcessStats);
6378            app.unlinkDeathRecipient();
6379            startProcessLocked(app, "bind fail", processName);
6380            return false;
6381        }
6382
6383        // Remove this record from the list of starting applications.
6384        mPersistentStartingProcesses.remove(app);
6385        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6386                "Attach application locked removing on hold: " + app);
6387        mProcessesOnHold.remove(app);
6388
6389        boolean badApp = false;
6390        boolean didSomething = false;
6391
6392        // See if the top visible activity is waiting to run in this process...
6393        if (normalMode) {
6394            try {
6395                if (mStackSupervisor.attachApplicationLocked(app)) {
6396                    didSomething = true;
6397                }
6398            } catch (Exception e) {
6399                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6400                badApp = true;
6401            }
6402        }
6403
6404        // Find any services that should be running in this process...
6405        if (!badApp) {
6406            try {
6407                didSomething |= mServices.attachApplicationLocked(app, processName);
6408            } catch (Exception e) {
6409                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6410                badApp = true;
6411            }
6412        }
6413
6414        // Check if a next-broadcast receiver is in this process...
6415        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6416            try {
6417                didSomething |= sendPendingBroadcastsLocked(app);
6418            } catch (Exception e) {
6419                // If the app died trying to launch the receiver we declare it 'bad'
6420                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6421                badApp = true;
6422            }
6423        }
6424
6425        // Check whether the next backup agent is in this process...
6426        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6427            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6428                    "New app is backup target, launching agent for " + app);
6429            notifyPackageUse(mBackupTarget.appInfo.packageName);
6430            try {
6431                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6432                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6433                        mBackupTarget.backupMode);
6434            } catch (Exception e) {
6435                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6436                badApp = true;
6437            }
6438        }
6439
6440        if (badApp) {
6441            app.kill("error during init", true);
6442            handleAppDiedLocked(app, false, true);
6443            return false;
6444        }
6445
6446        if (!didSomething) {
6447            updateOomAdjLocked();
6448        }
6449
6450        return true;
6451    }
6452
6453    @Override
6454    public final void attachApplication(IApplicationThread thread) {
6455        synchronized (this) {
6456            int callingPid = Binder.getCallingPid();
6457            final long origId = Binder.clearCallingIdentity();
6458            attachApplicationLocked(thread, callingPid);
6459            Binder.restoreCallingIdentity(origId);
6460        }
6461    }
6462
6463    @Override
6464    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6465        final long origId = Binder.clearCallingIdentity();
6466        synchronized (this) {
6467            ActivityStack stack = ActivityRecord.getStackLocked(token);
6468            if (stack != null) {
6469                ActivityRecord r =
6470                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6471                if (stopProfiling) {
6472                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6473                        try {
6474                            mProfileFd.close();
6475                        } catch (IOException e) {
6476                        }
6477                        clearProfilerLocked();
6478                    }
6479                }
6480            }
6481        }
6482        Binder.restoreCallingIdentity(origId);
6483    }
6484
6485    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6486        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6487                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6488    }
6489
6490    void enableScreenAfterBoot() {
6491        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6492                SystemClock.uptimeMillis());
6493        mWindowManager.enableScreenAfterBoot();
6494
6495        synchronized (this) {
6496            updateEventDispatchingLocked();
6497        }
6498    }
6499
6500    @Override
6501    public void showBootMessage(final CharSequence msg, final boolean always) {
6502        if (Binder.getCallingUid() != Process.myUid()) {
6503            // These days only the core system can call this, so apps can't get in
6504            // the way of what we show about running them.
6505        }
6506        mWindowManager.showBootMessage(msg, always);
6507    }
6508
6509    @Override
6510    public void keyguardWaitingForActivityDrawn() {
6511        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6512        final long token = Binder.clearCallingIdentity();
6513        try {
6514            synchronized (this) {
6515                if (DEBUG_LOCKSCREEN) logLockScreen("");
6516                mWindowManager.keyguardWaitingForActivityDrawn();
6517                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6518                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6519                    updateSleepIfNeededLocked();
6520                }
6521            }
6522        } finally {
6523            Binder.restoreCallingIdentity(token);
6524        }
6525    }
6526
6527    @Override
6528    public void keyguardGoingAway(int flags) {
6529        enforceNotIsolatedCaller("keyguardGoingAway");
6530        final long token = Binder.clearCallingIdentity();
6531        try {
6532            synchronized (this) {
6533                if (DEBUG_LOCKSCREEN) logLockScreen("");
6534                mWindowManager.keyguardGoingAway(flags);
6535                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6536                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6537                    updateSleepIfNeededLocked();
6538
6539                    // Some stack visibility might change (e.g. docked stack)
6540                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6541                }
6542            }
6543        } finally {
6544            Binder.restoreCallingIdentity(token);
6545        }
6546    }
6547
6548    final void finishBooting() {
6549        synchronized (this) {
6550            if (!mBootAnimationComplete) {
6551                mCallFinishBooting = true;
6552                return;
6553            }
6554            mCallFinishBooting = false;
6555        }
6556
6557        ArraySet<String> completedIsas = new ArraySet<String>();
6558        for (String abi : Build.SUPPORTED_ABIS) {
6559            Process.establishZygoteConnectionForAbi(abi);
6560            final String instructionSet = VMRuntime.getInstructionSet(abi);
6561            if (!completedIsas.contains(instructionSet)) {
6562                try {
6563                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6564                } catch (InstallerException e) {
6565                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6566                }
6567                completedIsas.add(instructionSet);
6568            }
6569        }
6570
6571        IntentFilter pkgFilter = new IntentFilter();
6572        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6573        pkgFilter.addDataScheme("package");
6574        mContext.registerReceiver(new BroadcastReceiver() {
6575            @Override
6576            public void onReceive(Context context, Intent intent) {
6577                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6578                if (pkgs != null) {
6579                    for (String pkg : pkgs) {
6580                        synchronized (ActivityManagerService.this) {
6581                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6582                                    0, "query restart")) {
6583                                setResultCode(Activity.RESULT_OK);
6584                                return;
6585                            }
6586                        }
6587                    }
6588                }
6589            }
6590        }, pkgFilter);
6591
6592        IntentFilter dumpheapFilter = new IntentFilter();
6593        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6594        mContext.registerReceiver(new BroadcastReceiver() {
6595            @Override
6596            public void onReceive(Context context, Intent intent) {
6597                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6598                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6599                } else {
6600                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6601                }
6602            }
6603        }, dumpheapFilter);
6604
6605        // Let system services know.
6606        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6607
6608        synchronized (this) {
6609            // Ensure that any processes we had put on hold are now started
6610            // up.
6611            final int NP = mProcessesOnHold.size();
6612            if (NP > 0) {
6613                ArrayList<ProcessRecord> procs =
6614                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6615                for (int ip=0; ip<NP; ip++) {
6616                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6617                            + procs.get(ip));
6618                    startProcessLocked(procs.get(ip), "on-hold", null);
6619                }
6620            }
6621
6622            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6623                // Start looking for apps that are abusing wake locks.
6624                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6625                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6626                // Tell anyone interested that we are done booting!
6627                SystemProperties.set("sys.boot_completed", "1");
6628
6629                // And trigger dev.bootcomplete if we are not showing encryption progress
6630                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6631                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6632                    SystemProperties.set("dev.bootcomplete", "1");
6633                }
6634                mUserController.sendBootCompletedLocked(
6635                        new IIntentReceiver.Stub() {
6636                            @Override
6637                            public void performReceive(Intent intent, int resultCode,
6638                                    String data, Bundle extras, boolean ordered,
6639                                    boolean sticky, int sendingUser) {
6640                                synchronized (ActivityManagerService.this) {
6641                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6642                                            true, false);
6643                                }
6644                            }
6645                        });
6646                scheduleStartProfilesLocked();
6647            }
6648        }
6649    }
6650
6651    @Override
6652    public void bootAnimationComplete() {
6653        final boolean callFinishBooting;
6654        synchronized (this) {
6655            callFinishBooting = mCallFinishBooting;
6656            mBootAnimationComplete = true;
6657        }
6658        if (callFinishBooting) {
6659            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6660            finishBooting();
6661            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6662        }
6663    }
6664
6665    final void ensureBootCompleted() {
6666        boolean booting;
6667        boolean enableScreen;
6668        synchronized (this) {
6669            booting = mBooting;
6670            mBooting = false;
6671            enableScreen = !mBooted;
6672            mBooted = true;
6673        }
6674
6675        if (booting) {
6676            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6677            finishBooting();
6678            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6679        }
6680
6681        if (enableScreen) {
6682            enableScreenAfterBoot();
6683        }
6684    }
6685
6686    @Override
6687    public final void activityResumed(IBinder token) {
6688        final long origId = Binder.clearCallingIdentity();
6689        synchronized(this) {
6690            ActivityStack stack = ActivityRecord.getStackLocked(token);
6691            if (stack != null) {
6692                stack.activityResumedLocked(token);
6693            }
6694        }
6695        Binder.restoreCallingIdentity(origId);
6696    }
6697
6698    @Override
6699    public final void activityPaused(IBinder token) {
6700        final long origId = Binder.clearCallingIdentity();
6701        synchronized(this) {
6702            ActivityStack stack = ActivityRecord.getStackLocked(token);
6703            if (stack != null) {
6704                stack.activityPausedLocked(token, false);
6705            }
6706        }
6707        Binder.restoreCallingIdentity(origId);
6708    }
6709
6710    @Override
6711    public final void activityStopped(IBinder token, Bundle icicle,
6712            PersistableBundle persistentState, CharSequence description) {
6713        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6714
6715        // Refuse possible leaked file descriptors
6716        if (icicle != null && icicle.hasFileDescriptors()) {
6717            throw new IllegalArgumentException("File descriptors passed in Bundle");
6718        }
6719
6720        final long origId = Binder.clearCallingIdentity();
6721
6722        synchronized (this) {
6723            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6724            if (r != null) {
6725                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6726            }
6727        }
6728
6729        trimApplications();
6730
6731        Binder.restoreCallingIdentity(origId);
6732    }
6733
6734    @Override
6735    public final void activityDestroyed(IBinder token) {
6736        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6737        synchronized (this) {
6738            ActivityStack stack = ActivityRecord.getStackLocked(token);
6739            if (stack != null) {
6740                stack.activityDestroyedLocked(token, "activityDestroyed");
6741            }
6742        }
6743    }
6744
6745    @Override
6746    public final void activityRelaunched(IBinder token) {
6747        final long origId = Binder.clearCallingIdentity();
6748        synchronized (this) {
6749            mStackSupervisor.activityRelaunchedLocked(token);
6750        }
6751        Binder.restoreCallingIdentity(origId);
6752    }
6753
6754    @Override
6755    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6756            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6757        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6758                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6759        synchronized (this) {
6760            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6761            if (record == null) {
6762                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6763                        + "found for: " + token);
6764            }
6765            record.setSizeConfigurations(horizontalSizeConfiguration,
6766                    verticalSizeConfigurations, smallestSizeConfigurations);
6767        }
6768    }
6769
6770    @Override
6771    public final void backgroundResourcesReleased(IBinder token) {
6772        final long origId = Binder.clearCallingIdentity();
6773        try {
6774            synchronized (this) {
6775                ActivityStack stack = ActivityRecord.getStackLocked(token);
6776                if (stack != null) {
6777                    stack.backgroundResourcesReleased();
6778                }
6779            }
6780        } finally {
6781            Binder.restoreCallingIdentity(origId);
6782        }
6783    }
6784
6785    @Override
6786    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6787        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6788    }
6789
6790    @Override
6791    public final void notifyEnterAnimationComplete(IBinder token) {
6792        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6793    }
6794
6795    @Override
6796    public String getCallingPackage(IBinder token) {
6797        synchronized (this) {
6798            ActivityRecord r = getCallingRecordLocked(token);
6799            return r != null ? r.info.packageName : null;
6800        }
6801    }
6802
6803    @Override
6804    public ComponentName getCallingActivity(IBinder token) {
6805        synchronized (this) {
6806            ActivityRecord r = getCallingRecordLocked(token);
6807            return r != null ? r.intent.getComponent() : null;
6808        }
6809    }
6810
6811    private ActivityRecord getCallingRecordLocked(IBinder token) {
6812        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6813        if (r == null) {
6814            return null;
6815        }
6816        return r.resultTo;
6817    }
6818
6819    @Override
6820    public ComponentName getActivityClassForToken(IBinder token) {
6821        synchronized(this) {
6822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6823            if (r == null) {
6824                return null;
6825            }
6826            return r.intent.getComponent();
6827        }
6828    }
6829
6830    @Override
6831    public String getPackageForToken(IBinder token) {
6832        synchronized(this) {
6833            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6834            if (r == null) {
6835                return null;
6836            }
6837            return r.packageName;
6838        }
6839    }
6840
6841    @Override
6842    public boolean isRootVoiceInteraction(IBinder token) {
6843        synchronized(this) {
6844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6845            if (r == null) {
6846                return false;
6847            }
6848            return r.rootVoiceInteraction;
6849        }
6850    }
6851
6852    @Override
6853    public IIntentSender getIntentSender(int type,
6854            String packageName, IBinder token, String resultWho,
6855            int requestCode, Intent[] intents, String[] resolvedTypes,
6856            int flags, Bundle bOptions, int userId) {
6857        enforceNotIsolatedCaller("getIntentSender");
6858        // Refuse possible leaked file descriptors
6859        if (intents != null) {
6860            if (intents.length < 1) {
6861                throw new IllegalArgumentException("Intents array length must be >= 1");
6862            }
6863            for (int i=0; i<intents.length; i++) {
6864                Intent intent = intents[i];
6865                if (intent != null) {
6866                    if (intent.hasFileDescriptors()) {
6867                        throw new IllegalArgumentException("File descriptors passed in Intent");
6868                    }
6869                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6870                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6871                        throw new IllegalArgumentException(
6872                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6873                    }
6874                    intents[i] = new Intent(intent);
6875                }
6876            }
6877            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6878                throw new IllegalArgumentException(
6879                        "Intent array length does not match resolvedTypes length");
6880            }
6881        }
6882        if (bOptions != null) {
6883            if (bOptions.hasFileDescriptors()) {
6884                throw new IllegalArgumentException("File descriptors passed in options");
6885            }
6886        }
6887
6888        synchronized(this) {
6889            int callingUid = Binder.getCallingUid();
6890            int origUserId = userId;
6891            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6892                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6893                    ALLOW_NON_FULL, "getIntentSender", null);
6894            if (origUserId == UserHandle.USER_CURRENT) {
6895                // We don't want to evaluate this until the pending intent is
6896                // actually executed.  However, we do want to always do the
6897                // security checking for it above.
6898                userId = UserHandle.USER_CURRENT;
6899            }
6900            try {
6901                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6902                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6903                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6904                    if (!UserHandle.isSameApp(callingUid, uid)) {
6905                        String msg = "Permission Denial: getIntentSender() from pid="
6906                            + Binder.getCallingPid()
6907                            + ", uid=" + Binder.getCallingUid()
6908                            + ", (need uid=" + uid + ")"
6909                            + " is not allowed to send as package " + packageName;
6910                        Slog.w(TAG, msg);
6911                        throw new SecurityException(msg);
6912                    }
6913                }
6914
6915                return getIntentSenderLocked(type, packageName, callingUid, userId,
6916                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6917
6918            } catch (RemoteException e) {
6919                throw new SecurityException(e);
6920            }
6921        }
6922    }
6923
6924    IIntentSender getIntentSenderLocked(int type, String packageName,
6925            int callingUid, int userId, IBinder token, String resultWho,
6926            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6927            Bundle bOptions) {
6928        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6929        ActivityRecord activity = null;
6930        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6931            activity = ActivityRecord.isInStackLocked(token);
6932            if (activity == null) {
6933                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6934                return null;
6935            }
6936            if (activity.finishing) {
6937                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6938                return null;
6939            }
6940        }
6941
6942        // We're going to be splicing together extras before sending, so we're
6943        // okay poking into any contained extras.
6944        if (intents != null) {
6945            for (int i = 0; i < intents.length; i++) {
6946                intents[i].setDefusable(true);
6947            }
6948        }
6949        Bundle.setDefusable(bOptions, true);
6950
6951        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6952        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6953        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6954        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6955                |PendingIntent.FLAG_UPDATE_CURRENT);
6956
6957        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6958                type, packageName, activity, resultWho,
6959                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6960        WeakReference<PendingIntentRecord> ref;
6961        ref = mIntentSenderRecords.get(key);
6962        PendingIntentRecord rec = ref != null ? ref.get() : null;
6963        if (rec != null) {
6964            if (!cancelCurrent) {
6965                if (updateCurrent) {
6966                    if (rec.key.requestIntent != null) {
6967                        rec.key.requestIntent.replaceExtras(intents != null ?
6968                                intents[intents.length - 1] : null);
6969                    }
6970                    if (intents != null) {
6971                        intents[intents.length-1] = rec.key.requestIntent;
6972                        rec.key.allIntents = intents;
6973                        rec.key.allResolvedTypes = resolvedTypes;
6974                    } else {
6975                        rec.key.allIntents = null;
6976                        rec.key.allResolvedTypes = null;
6977                    }
6978                }
6979                return rec;
6980            }
6981            rec.canceled = true;
6982            mIntentSenderRecords.remove(key);
6983        }
6984        if (noCreate) {
6985            return rec;
6986        }
6987        rec = new PendingIntentRecord(this, key, callingUid);
6988        mIntentSenderRecords.put(key, rec.ref);
6989        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6990            if (activity.pendingResults == null) {
6991                activity.pendingResults
6992                        = new HashSet<WeakReference<PendingIntentRecord>>();
6993            }
6994            activity.pendingResults.add(rec.ref);
6995        }
6996        return rec;
6997    }
6998
6999    @Override
7000    public void cancelIntentSender(IIntentSender sender) {
7001        if (!(sender instanceof PendingIntentRecord)) {
7002            return;
7003        }
7004        synchronized(this) {
7005            PendingIntentRecord rec = (PendingIntentRecord)sender;
7006            try {
7007                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7008                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7009                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7010                    String msg = "Permission Denial: cancelIntentSender() from pid="
7011                        + Binder.getCallingPid()
7012                        + ", uid=" + Binder.getCallingUid()
7013                        + " is not allowed to cancel packges "
7014                        + rec.key.packageName;
7015                    Slog.w(TAG, msg);
7016                    throw new SecurityException(msg);
7017                }
7018            } catch (RemoteException e) {
7019                throw new SecurityException(e);
7020            }
7021            cancelIntentSenderLocked(rec, true);
7022        }
7023    }
7024
7025    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7026        rec.canceled = true;
7027        mIntentSenderRecords.remove(rec.key);
7028        if (cleanActivity && rec.key.activity != null) {
7029            rec.key.activity.pendingResults.remove(rec.ref);
7030        }
7031    }
7032
7033    @Override
7034    public String getPackageForIntentSender(IIntentSender pendingResult) {
7035        if (!(pendingResult instanceof PendingIntentRecord)) {
7036            return null;
7037        }
7038        try {
7039            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7040            return res.key.packageName;
7041        } catch (ClassCastException e) {
7042        }
7043        return null;
7044    }
7045
7046    @Override
7047    public int getUidForIntentSender(IIntentSender sender) {
7048        if (sender instanceof PendingIntentRecord) {
7049            try {
7050                PendingIntentRecord res = (PendingIntentRecord)sender;
7051                return res.uid;
7052            } catch (ClassCastException e) {
7053            }
7054        }
7055        return -1;
7056    }
7057
7058    @Override
7059    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7060        if (!(pendingResult instanceof PendingIntentRecord)) {
7061            return false;
7062        }
7063        try {
7064            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7065            if (res.key.allIntents == null) {
7066                return false;
7067            }
7068            for (int i=0; i<res.key.allIntents.length; i++) {
7069                Intent intent = res.key.allIntents[i];
7070                if (intent.getPackage() != null && intent.getComponent() != null) {
7071                    return false;
7072                }
7073            }
7074            return true;
7075        } catch (ClassCastException e) {
7076        }
7077        return false;
7078    }
7079
7080    @Override
7081    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7082        if (!(pendingResult instanceof PendingIntentRecord)) {
7083            return false;
7084        }
7085        try {
7086            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7087            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7088                return true;
7089            }
7090            return false;
7091        } catch (ClassCastException e) {
7092        }
7093        return false;
7094    }
7095
7096    @Override
7097    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7098        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7099                "getIntentForIntentSender()");
7100        if (!(pendingResult instanceof PendingIntentRecord)) {
7101            return null;
7102        }
7103        try {
7104            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7105            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7106        } catch (ClassCastException e) {
7107        }
7108        return null;
7109    }
7110
7111    @Override
7112    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7113        if (!(pendingResult instanceof PendingIntentRecord)) {
7114            return null;
7115        }
7116        try {
7117            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7118            synchronized (this) {
7119                return getTagForIntentSenderLocked(res, prefix);
7120            }
7121        } catch (ClassCastException e) {
7122        }
7123        return null;
7124    }
7125
7126    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7127        final Intent intent = res.key.requestIntent;
7128        if (intent != null) {
7129            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7130                    || res.lastTagPrefix.equals(prefix))) {
7131                return res.lastTag;
7132            }
7133            res.lastTagPrefix = prefix;
7134            final StringBuilder sb = new StringBuilder(128);
7135            if (prefix != null) {
7136                sb.append(prefix);
7137            }
7138            if (intent.getAction() != null) {
7139                sb.append(intent.getAction());
7140            } else if (intent.getComponent() != null) {
7141                intent.getComponent().appendShortString(sb);
7142            } else {
7143                sb.append("?");
7144            }
7145            return res.lastTag = sb.toString();
7146        }
7147        return null;
7148    }
7149
7150    @Override
7151    public void setProcessLimit(int max) {
7152        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7153                "setProcessLimit()");
7154        synchronized (this) {
7155            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7156            mProcessLimitOverride = max;
7157        }
7158        trimApplications();
7159    }
7160
7161    @Override
7162    public int getProcessLimit() {
7163        synchronized (this) {
7164            return mProcessLimitOverride;
7165        }
7166    }
7167
7168    void foregroundTokenDied(ForegroundToken token) {
7169        synchronized (ActivityManagerService.this) {
7170            synchronized (mPidsSelfLocked) {
7171                ForegroundToken cur
7172                    = mForegroundProcesses.get(token.pid);
7173                if (cur != token) {
7174                    return;
7175                }
7176                mForegroundProcesses.remove(token.pid);
7177                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7178                if (pr == null) {
7179                    return;
7180                }
7181                pr.forcingToForeground = null;
7182                updateProcessForegroundLocked(pr, false, false);
7183            }
7184            updateOomAdjLocked();
7185        }
7186    }
7187
7188    @Override
7189    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7190        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7191                "setProcessForeground()");
7192        synchronized(this) {
7193            boolean changed = false;
7194
7195            synchronized (mPidsSelfLocked) {
7196                ProcessRecord pr = mPidsSelfLocked.get(pid);
7197                if (pr == null && isForeground) {
7198                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7199                    return;
7200                }
7201                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7202                if (oldToken != null) {
7203                    oldToken.token.unlinkToDeath(oldToken, 0);
7204                    mForegroundProcesses.remove(pid);
7205                    if (pr != null) {
7206                        pr.forcingToForeground = null;
7207                    }
7208                    changed = true;
7209                }
7210                if (isForeground && token != null) {
7211                    ForegroundToken newToken = new ForegroundToken() {
7212                        @Override
7213                        public void binderDied() {
7214                            foregroundTokenDied(this);
7215                        }
7216                    };
7217                    newToken.pid = pid;
7218                    newToken.token = token;
7219                    try {
7220                        token.linkToDeath(newToken, 0);
7221                        mForegroundProcesses.put(pid, newToken);
7222                        pr.forcingToForeground = token;
7223                        changed = true;
7224                    } catch (RemoteException e) {
7225                        // If the process died while doing this, we will later
7226                        // do the cleanup with the process death link.
7227                    }
7228                }
7229            }
7230
7231            if (changed) {
7232                updateOomAdjLocked();
7233            }
7234        }
7235    }
7236
7237    @Override
7238    public boolean isAppForeground(int uid) throws RemoteException {
7239        synchronized (this) {
7240            UidRecord uidRec = mActiveUids.get(uid);
7241            if (uidRec == null || uidRec.idle) {
7242                return false;
7243            }
7244            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7245        }
7246    }
7247
7248    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7249    // be guarded by permission checking.
7250    int getUidState(int uid) {
7251        synchronized (this) {
7252            UidRecord uidRec = mActiveUids.get(uid);
7253            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7254        }
7255    }
7256
7257    @Override
7258    public boolean isInMultiWindowMode(IBinder token) {
7259        final long origId = Binder.clearCallingIdentity();
7260        try {
7261            synchronized(this) {
7262                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7263                if (r == null) {
7264                    return false;
7265                }
7266                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7267                return !r.task.mFullscreen;
7268            }
7269        } finally {
7270            Binder.restoreCallingIdentity(origId);
7271        }
7272    }
7273
7274    @Override
7275    public boolean isInPictureInPictureMode(IBinder token) {
7276        final long origId = Binder.clearCallingIdentity();
7277        try {
7278            synchronized(this) {
7279                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7280                if (stack == null) {
7281                    return false;
7282                }
7283                return stack.mStackId == PINNED_STACK_ID;
7284            }
7285        } finally {
7286            Binder.restoreCallingIdentity(origId);
7287        }
7288    }
7289
7290    @Override
7291    public void enterPictureInPictureMode(IBinder token) {
7292        final long origId = Binder.clearCallingIdentity();
7293        try {
7294            synchronized(this) {
7295                if (!mSupportsPictureInPicture) {
7296                    throw new IllegalStateException("enterPictureInPictureMode: "
7297                            + "Device doesn't support picture-in-picture mode.");
7298                }
7299
7300                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7301
7302                if (r == null) {
7303                    throw new IllegalStateException("enterPictureInPictureMode: "
7304                            + "Can't find activity for token=" + token);
7305                }
7306
7307                if (!r.supportsPictureInPicture()) {
7308                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7309                            + "Picture-In-Picture not supported for r=" + r);
7310                }
7311
7312                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7313                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7314                        ? mDefaultPinnedStackBounds : null;
7315
7316                mStackSupervisor.moveActivityToPinnedStackLocked(
7317                        r, "enterPictureInPictureMode", bounds);
7318            }
7319        } finally {
7320            Binder.restoreCallingIdentity(origId);
7321        }
7322    }
7323
7324    // =========================================================
7325    // PROCESS INFO
7326    // =========================================================
7327
7328    static class ProcessInfoService extends IProcessInfoService.Stub {
7329        final ActivityManagerService mActivityManagerService;
7330        ProcessInfoService(ActivityManagerService activityManagerService) {
7331            mActivityManagerService = activityManagerService;
7332        }
7333
7334        @Override
7335        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7336            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7337                    /*in*/ pids, /*out*/ states, null);
7338        }
7339
7340        @Override
7341        public void getProcessStatesAndOomScoresFromPids(
7342                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7343            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7344                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7345        }
7346    }
7347
7348    /**
7349     * For each PID in the given input array, write the current process state
7350     * for that process into the states array, or -1 to indicate that no
7351     * process with the given PID exists. If scores array is provided, write
7352     * the oom score for the process into the scores array, with INVALID_ADJ
7353     * indicating the PID doesn't exist.
7354     */
7355    public void getProcessStatesAndOomScoresForPIDs(
7356            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7357        if (scores != null) {
7358            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7359                    "getProcessStatesAndOomScoresForPIDs()");
7360        }
7361
7362        if (pids == null) {
7363            throw new NullPointerException("pids");
7364        } else if (states == null) {
7365            throw new NullPointerException("states");
7366        } else if (pids.length != states.length) {
7367            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7368        } else if (scores != null && pids.length != scores.length) {
7369            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7370        }
7371
7372        synchronized (mPidsSelfLocked) {
7373            for (int i = 0; i < pids.length; i++) {
7374                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7375                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7376                        pr.curProcState;
7377                if (scores != null) {
7378                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7379                }
7380            }
7381        }
7382    }
7383
7384    // =========================================================
7385    // PERMISSIONS
7386    // =========================================================
7387
7388    static class PermissionController extends IPermissionController.Stub {
7389        ActivityManagerService mActivityManagerService;
7390        PermissionController(ActivityManagerService activityManagerService) {
7391            mActivityManagerService = activityManagerService;
7392        }
7393
7394        @Override
7395        public boolean checkPermission(String permission, int pid, int uid) {
7396            return mActivityManagerService.checkPermission(permission, pid,
7397                    uid) == PackageManager.PERMISSION_GRANTED;
7398        }
7399
7400        @Override
7401        public String[] getPackagesForUid(int uid) {
7402            return mActivityManagerService.mContext.getPackageManager()
7403                    .getPackagesForUid(uid);
7404        }
7405
7406        @Override
7407        public boolean isRuntimePermission(String permission) {
7408            try {
7409                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7410                        .getPermissionInfo(permission, 0);
7411                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7412            } catch (NameNotFoundException nnfe) {
7413                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7414            }
7415            return false;
7416        }
7417    }
7418
7419    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7420        @Override
7421        public int checkComponentPermission(String permission, int pid, int uid,
7422                int owningUid, boolean exported) {
7423            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7424                    owningUid, exported);
7425        }
7426
7427        @Override
7428        public Object getAMSLock() {
7429            return ActivityManagerService.this;
7430        }
7431    }
7432
7433    /**
7434     * This can be called with or without the global lock held.
7435     */
7436    int checkComponentPermission(String permission, int pid, int uid,
7437            int owningUid, boolean exported) {
7438        if (pid == MY_PID) {
7439            return PackageManager.PERMISSION_GRANTED;
7440        }
7441        return ActivityManager.checkComponentPermission(permission, uid,
7442                owningUid, exported);
7443    }
7444
7445    /**
7446     * As the only public entry point for permissions checking, this method
7447     * can enforce the semantic that requesting a check on a null global
7448     * permission is automatically denied.  (Internally a null permission
7449     * string is used when calling {@link #checkComponentPermission} in cases
7450     * when only uid-based security is needed.)
7451     *
7452     * This can be called with or without the global lock held.
7453     */
7454    @Override
7455    public int checkPermission(String permission, int pid, int uid) {
7456        if (permission == null) {
7457            return PackageManager.PERMISSION_DENIED;
7458        }
7459        return checkComponentPermission(permission, pid, uid, -1, true);
7460    }
7461
7462    @Override
7463    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7464        if (permission == null) {
7465            return PackageManager.PERMISSION_DENIED;
7466        }
7467
7468        // We might be performing an operation on behalf of an indirect binder
7469        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7470        // client identity accordingly before proceeding.
7471        Identity tlsIdentity = sCallerIdentity.get();
7472        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7473            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7474                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7475            uid = tlsIdentity.uid;
7476            pid = tlsIdentity.pid;
7477        }
7478
7479        return checkComponentPermission(permission, pid, uid, -1, true);
7480    }
7481
7482    /**
7483     * Binder IPC calls go through the public entry point.
7484     * This can be called with or without the global lock held.
7485     */
7486    int checkCallingPermission(String permission) {
7487        return checkPermission(permission,
7488                Binder.getCallingPid(),
7489                UserHandle.getAppId(Binder.getCallingUid()));
7490    }
7491
7492    /**
7493     * This can be called with or without the global lock held.
7494     */
7495    void enforceCallingPermission(String permission, String func) {
7496        if (checkCallingPermission(permission)
7497                == PackageManager.PERMISSION_GRANTED) {
7498            return;
7499        }
7500
7501        String msg = "Permission Denial: " + func + " from pid="
7502                + Binder.getCallingPid()
7503                + ", uid=" + Binder.getCallingUid()
7504                + " requires " + permission;
7505        Slog.w(TAG, msg);
7506        throw new SecurityException(msg);
7507    }
7508
7509    /**
7510     * Determine if UID is holding permissions required to access {@link Uri} in
7511     * the given {@link ProviderInfo}. Final permission checking is always done
7512     * in {@link ContentProvider}.
7513     */
7514    private final boolean checkHoldingPermissionsLocked(
7515            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7516        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7517                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7518        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7519            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7520                    != PERMISSION_GRANTED) {
7521                return false;
7522            }
7523        }
7524        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7525    }
7526
7527    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7528            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7529        if (pi.applicationInfo.uid == uid) {
7530            return true;
7531        } else if (!pi.exported) {
7532            return false;
7533        }
7534
7535        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7536        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7537        try {
7538            // check if target holds top-level <provider> permissions
7539            if (!readMet && pi.readPermission != null && considerUidPermissions
7540                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7541                readMet = true;
7542            }
7543            if (!writeMet && pi.writePermission != null && considerUidPermissions
7544                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7545                writeMet = true;
7546            }
7547
7548            // track if unprotected read/write is allowed; any denied
7549            // <path-permission> below removes this ability
7550            boolean allowDefaultRead = pi.readPermission == null;
7551            boolean allowDefaultWrite = pi.writePermission == null;
7552
7553            // check if target holds any <path-permission> that match uri
7554            final PathPermission[] pps = pi.pathPermissions;
7555            if (pps != null) {
7556                final String path = grantUri.uri.getPath();
7557                int i = pps.length;
7558                while (i > 0 && (!readMet || !writeMet)) {
7559                    i--;
7560                    PathPermission pp = pps[i];
7561                    if (pp.match(path)) {
7562                        if (!readMet) {
7563                            final String pprperm = pp.getReadPermission();
7564                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7565                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7566                                    + ": match=" + pp.match(path)
7567                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7568                            if (pprperm != null) {
7569                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7570                                        == PERMISSION_GRANTED) {
7571                                    readMet = true;
7572                                } else {
7573                                    allowDefaultRead = false;
7574                                }
7575                            }
7576                        }
7577                        if (!writeMet) {
7578                            final String ppwperm = pp.getWritePermission();
7579                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7580                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7581                                    + ": match=" + pp.match(path)
7582                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7583                            if (ppwperm != null) {
7584                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7585                                        == PERMISSION_GRANTED) {
7586                                    writeMet = true;
7587                                } else {
7588                                    allowDefaultWrite = false;
7589                                }
7590                            }
7591                        }
7592                    }
7593                }
7594            }
7595
7596            // grant unprotected <provider> read/write, if not blocked by
7597            // <path-permission> above
7598            if (allowDefaultRead) readMet = true;
7599            if (allowDefaultWrite) writeMet = true;
7600
7601        } catch (RemoteException e) {
7602            return false;
7603        }
7604
7605        return readMet && writeMet;
7606    }
7607
7608    public int getAppStartMode(int uid, String packageName) {
7609        synchronized (this) {
7610            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7611        }
7612    }
7613
7614    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7615            boolean allowWhenForeground) {
7616        UidRecord uidRec = mActiveUids.get(uid);
7617        if (!mLenientBackgroundCheck) {
7618            if (!allowWhenForeground || uidRec == null
7619                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7620                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7621                        packageName) != AppOpsManager.MODE_ALLOWED) {
7622                    return ActivityManager.APP_START_MODE_DELAYED;
7623                }
7624            }
7625
7626        } else if (uidRec == null || uidRec.idle) {
7627            if (callingPid >= 0) {
7628                ProcessRecord proc;
7629                synchronized (mPidsSelfLocked) {
7630                    proc = mPidsSelfLocked.get(callingPid);
7631                }
7632                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7633                    // Whoever is instigating this is in the foreground, so we will allow it
7634                    // to go through.
7635                    return ActivityManager.APP_START_MODE_NORMAL;
7636                }
7637            }
7638            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7639                    != AppOpsManager.MODE_ALLOWED) {
7640                return ActivityManager.APP_START_MODE_DELAYED;
7641            }
7642        }
7643        return ActivityManager.APP_START_MODE_NORMAL;
7644    }
7645
7646    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7647        ProviderInfo pi = null;
7648        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7649        if (cpr != null) {
7650            pi = cpr.info;
7651        } else {
7652            try {
7653                pi = AppGlobals.getPackageManager().resolveContentProvider(
7654                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7655            } catch (RemoteException ex) {
7656            }
7657        }
7658        return pi;
7659    }
7660
7661    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7662        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7663        if (targetUris != null) {
7664            return targetUris.get(grantUri);
7665        }
7666        return null;
7667    }
7668
7669    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7670            String targetPkg, int targetUid, GrantUri grantUri) {
7671        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7672        if (targetUris == null) {
7673            targetUris = Maps.newArrayMap();
7674            mGrantedUriPermissions.put(targetUid, targetUris);
7675        }
7676
7677        UriPermission perm = targetUris.get(grantUri);
7678        if (perm == null) {
7679            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7680            targetUris.put(grantUri, perm);
7681        }
7682
7683        return perm;
7684    }
7685
7686    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7687            final int modeFlags) {
7688        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7689        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7690                : UriPermission.STRENGTH_OWNED;
7691
7692        // Root gets to do everything.
7693        if (uid == 0) {
7694            return true;
7695        }
7696
7697        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7698        if (perms == null) return false;
7699
7700        // First look for exact match
7701        final UriPermission exactPerm = perms.get(grantUri);
7702        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7703            return true;
7704        }
7705
7706        // No exact match, look for prefixes
7707        final int N = perms.size();
7708        for (int i = 0; i < N; i++) {
7709            final UriPermission perm = perms.valueAt(i);
7710            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7711                    && perm.getStrength(modeFlags) >= minStrength) {
7712                return true;
7713            }
7714        }
7715
7716        return false;
7717    }
7718
7719    /**
7720     * @param uri This uri must NOT contain an embedded userId.
7721     * @param userId The userId in which the uri is to be resolved.
7722     */
7723    @Override
7724    public int checkUriPermission(Uri uri, int pid, int uid,
7725            final int modeFlags, int userId, IBinder callerToken) {
7726        enforceNotIsolatedCaller("checkUriPermission");
7727
7728        // Another redirected-binder-call permissions check as in
7729        // {@link checkPermissionWithToken}.
7730        Identity tlsIdentity = sCallerIdentity.get();
7731        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7732            uid = tlsIdentity.uid;
7733            pid = tlsIdentity.pid;
7734        }
7735
7736        // Our own process gets to do everything.
7737        if (pid == MY_PID) {
7738            return PackageManager.PERMISSION_GRANTED;
7739        }
7740        synchronized (this) {
7741            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7742                    ? PackageManager.PERMISSION_GRANTED
7743                    : PackageManager.PERMISSION_DENIED;
7744        }
7745    }
7746
7747    /**
7748     * Check if the targetPkg can be granted permission to access uri by
7749     * the callingUid using the given modeFlags.  Throws a security exception
7750     * if callingUid is not allowed to do this.  Returns the uid of the target
7751     * if the URI permission grant should be performed; returns -1 if it is not
7752     * needed (for example targetPkg already has permission to access the URI).
7753     * If you already know the uid of the target, you can supply it in
7754     * lastTargetUid else set that to -1.
7755     */
7756    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7757            final int modeFlags, int lastTargetUid) {
7758        if (!Intent.isAccessUriMode(modeFlags)) {
7759            return -1;
7760        }
7761
7762        if (targetPkg != null) {
7763            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7764                    "Checking grant " + targetPkg + " permission to " + grantUri);
7765        }
7766
7767        final IPackageManager pm = AppGlobals.getPackageManager();
7768
7769        // If this is not a content: uri, we can't do anything with it.
7770        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7771            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7772                    "Can't grant URI permission for non-content URI: " + grantUri);
7773            return -1;
7774        }
7775
7776        final String authority = grantUri.uri.getAuthority();
7777        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7778        if (pi == null) {
7779            Slog.w(TAG, "No content provider found for permission check: " +
7780                    grantUri.uri.toSafeString());
7781            return -1;
7782        }
7783
7784        int targetUid = lastTargetUid;
7785        if (targetUid < 0 && targetPkg != null) {
7786            try {
7787                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7788                        UserHandle.getUserId(callingUid));
7789                if (targetUid < 0) {
7790                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7791                            "Can't grant URI permission no uid for: " + targetPkg);
7792                    return -1;
7793                }
7794            } catch (RemoteException ex) {
7795                return -1;
7796            }
7797        }
7798
7799        if (targetUid >= 0) {
7800            // First...  does the target actually need this permission?
7801            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7802                // No need to grant the target this permission.
7803                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7804                        "Target " + targetPkg + " already has full permission to " + grantUri);
7805                return -1;
7806            }
7807        } else {
7808            // First...  there is no target package, so can anyone access it?
7809            boolean allowed = pi.exported;
7810            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7811                if (pi.readPermission != null) {
7812                    allowed = false;
7813                }
7814            }
7815            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7816                if (pi.writePermission != null) {
7817                    allowed = false;
7818                }
7819            }
7820            if (allowed) {
7821                return -1;
7822            }
7823        }
7824
7825        /* There is a special cross user grant if:
7826         * - The target is on another user.
7827         * - Apps on the current user can access the uri without any uid permissions.
7828         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7829         * grant uri permissions.
7830         */
7831        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7832                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7833                modeFlags, false /*without considering the uid permissions*/);
7834
7835        // Second...  is the provider allowing granting of URI permissions?
7836        if (!specialCrossUserGrant) {
7837            if (!pi.grantUriPermissions) {
7838                throw new SecurityException("Provider " + pi.packageName
7839                        + "/" + pi.name
7840                        + " does not allow granting of Uri permissions (uri "
7841                        + grantUri + ")");
7842            }
7843            if (pi.uriPermissionPatterns != null) {
7844                final int N = pi.uriPermissionPatterns.length;
7845                boolean allowed = false;
7846                for (int i=0; i<N; i++) {
7847                    if (pi.uriPermissionPatterns[i] != null
7848                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7849                        allowed = true;
7850                        break;
7851                    }
7852                }
7853                if (!allowed) {
7854                    throw new SecurityException("Provider " + pi.packageName
7855                            + "/" + pi.name
7856                            + " does not allow granting of permission to path of Uri "
7857                            + grantUri);
7858                }
7859            }
7860        }
7861
7862        // Third...  does the caller itself have permission to access
7863        // this uri?
7864        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7865            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7866                // Require they hold a strong enough Uri permission
7867                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7868                    throw new SecurityException("Uid " + callingUid
7869                            + " does not have permission to uri " + grantUri);
7870                }
7871            }
7872        }
7873        return targetUid;
7874    }
7875
7876    /**
7877     * @param uri This uri must NOT contain an embedded userId.
7878     * @param userId The userId in which the uri is to be resolved.
7879     */
7880    @Override
7881    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7882            final int modeFlags, int userId) {
7883        enforceNotIsolatedCaller("checkGrantUriPermission");
7884        synchronized(this) {
7885            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7886                    new GrantUri(userId, uri, false), modeFlags, -1);
7887        }
7888    }
7889
7890    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7891            final int modeFlags, UriPermissionOwner owner) {
7892        if (!Intent.isAccessUriMode(modeFlags)) {
7893            return;
7894        }
7895
7896        // So here we are: the caller has the assumed permission
7897        // to the uri, and the target doesn't.  Let's now give this to
7898        // the target.
7899
7900        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7901                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7902
7903        final String authority = grantUri.uri.getAuthority();
7904        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7905        if (pi == null) {
7906            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7907            return;
7908        }
7909
7910        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7911            grantUri.prefix = true;
7912        }
7913        final UriPermission perm = findOrCreateUriPermissionLocked(
7914                pi.packageName, targetPkg, targetUid, grantUri);
7915        perm.grantModes(modeFlags, owner);
7916    }
7917
7918    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7919            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7920        if (targetPkg == null) {
7921            throw new NullPointerException("targetPkg");
7922        }
7923        int targetUid;
7924        final IPackageManager pm = AppGlobals.getPackageManager();
7925        try {
7926            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7927        } catch (RemoteException ex) {
7928            return;
7929        }
7930
7931        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7932                targetUid);
7933        if (targetUid < 0) {
7934            return;
7935        }
7936
7937        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7938                owner);
7939    }
7940
7941    static class NeededUriGrants extends ArrayList<GrantUri> {
7942        final String targetPkg;
7943        final int targetUid;
7944        final int flags;
7945
7946        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7947            this.targetPkg = targetPkg;
7948            this.targetUid = targetUid;
7949            this.flags = flags;
7950        }
7951    }
7952
7953    /**
7954     * Like checkGrantUriPermissionLocked, but takes an Intent.
7955     */
7956    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7957            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7958        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7959                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7960                + " clip=" + (intent != null ? intent.getClipData() : null)
7961                + " from " + intent + "; flags=0x"
7962                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7963
7964        if (targetPkg == null) {
7965            throw new NullPointerException("targetPkg");
7966        }
7967
7968        if (intent == null) {
7969            return null;
7970        }
7971        Uri data = intent.getData();
7972        ClipData clip = intent.getClipData();
7973        if (data == null && clip == null) {
7974            return null;
7975        }
7976        // Default userId for uris in the intent (if they don't specify it themselves)
7977        int contentUserHint = intent.getContentUserHint();
7978        if (contentUserHint == UserHandle.USER_CURRENT) {
7979            contentUserHint = UserHandle.getUserId(callingUid);
7980        }
7981        final IPackageManager pm = AppGlobals.getPackageManager();
7982        int targetUid;
7983        if (needed != null) {
7984            targetUid = needed.targetUid;
7985        } else {
7986            try {
7987                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7988                        targetUserId);
7989            } catch (RemoteException ex) {
7990                return null;
7991            }
7992            if (targetUid < 0) {
7993                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7994                        "Can't grant URI permission no uid for: " + targetPkg
7995                        + " on user " + targetUserId);
7996                return null;
7997            }
7998        }
7999        if (data != null) {
8000            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8001            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8002                    targetUid);
8003            if (targetUid > 0) {
8004                if (needed == null) {
8005                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8006                }
8007                needed.add(grantUri);
8008            }
8009        }
8010        if (clip != null) {
8011            for (int i=0; i<clip.getItemCount(); i++) {
8012                Uri uri = clip.getItemAt(i).getUri();
8013                if (uri != null) {
8014                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8015                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8016                            targetUid);
8017                    if (targetUid > 0) {
8018                        if (needed == null) {
8019                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8020                        }
8021                        needed.add(grantUri);
8022                    }
8023                } else {
8024                    Intent clipIntent = clip.getItemAt(i).getIntent();
8025                    if (clipIntent != null) {
8026                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8027                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8028                        if (newNeeded != null) {
8029                            needed = newNeeded;
8030                        }
8031                    }
8032                }
8033            }
8034        }
8035
8036        return needed;
8037    }
8038
8039    /**
8040     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8041     */
8042    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8043            UriPermissionOwner owner) {
8044        if (needed != null) {
8045            for (int i=0; i<needed.size(); i++) {
8046                GrantUri grantUri = needed.get(i);
8047                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8048                        grantUri, needed.flags, owner);
8049            }
8050        }
8051    }
8052
8053    void grantUriPermissionFromIntentLocked(int callingUid,
8054            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8055        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8056                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8057        if (needed == null) {
8058            return;
8059        }
8060
8061        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8062    }
8063
8064    /**
8065     * @param uri This uri must NOT contain an embedded userId.
8066     * @param userId The userId in which the uri is to be resolved.
8067     */
8068    @Override
8069    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8070            final int modeFlags, int userId) {
8071        enforceNotIsolatedCaller("grantUriPermission");
8072        GrantUri grantUri = new GrantUri(userId, uri, false);
8073        synchronized(this) {
8074            final ProcessRecord r = getRecordForAppLocked(caller);
8075            if (r == null) {
8076                throw new SecurityException("Unable to find app for caller "
8077                        + caller
8078                        + " when granting permission to uri " + grantUri);
8079            }
8080            if (targetPkg == null) {
8081                throw new IllegalArgumentException("null target");
8082            }
8083            if (grantUri == null) {
8084                throw new IllegalArgumentException("null uri");
8085            }
8086
8087            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8088                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8089                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8090                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8091
8092            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8093                    UserHandle.getUserId(r.uid));
8094        }
8095    }
8096
8097    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8098        if (perm.modeFlags == 0) {
8099            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8100                    perm.targetUid);
8101            if (perms != null) {
8102                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8103                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8104
8105                perms.remove(perm.uri);
8106                if (perms.isEmpty()) {
8107                    mGrantedUriPermissions.remove(perm.targetUid);
8108                }
8109            }
8110        }
8111    }
8112
8113    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8114        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8115                "Revoking all granted permissions to " + grantUri);
8116
8117        final IPackageManager pm = AppGlobals.getPackageManager();
8118        final String authority = grantUri.uri.getAuthority();
8119        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8120        if (pi == null) {
8121            Slog.w(TAG, "No content provider found for permission revoke: "
8122                    + grantUri.toSafeString());
8123            return;
8124        }
8125
8126        // Does the caller have this permission on the URI?
8127        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8128            // If they don't have direct access to the URI, then revoke any
8129            // ownerless URI permissions that have been granted to them.
8130            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8131            if (perms != null) {
8132                boolean persistChanged = false;
8133                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8134                    final UriPermission perm = it.next();
8135                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8136                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8137                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8138                                "Revoking non-owned " + perm.targetUid
8139                                + " permission to " + perm.uri);
8140                        persistChanged |= perm.revokeModes(
8141                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8142                        if (perm.modeFlags == 0) {
8143                            it.remove();
8144                        }
8145                    }
8146                }
8147                if (perms.isEmpty()) {
8148                    mGrantedUriPermissions.remove(callingUid);
8149                }
8150                if (persistChanged) {
8151                    schedulePersistUriGrants();
8152                }
8153            }
8154            return;
8155        }
8156
8157        boolean persistChanged = false;
8158
8159        // Go through all of the permissions and remove any that match.
8160        int N = mGrantedUriPermissions.size();
8161        for (int i = 0; i < N; i++) {
8162            final int targetUid = mGrantedUriPermissions.keyAt(i);
8163            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8164
8165            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8166                final UriPermission perm = it.next();
8167                if (perm.uri.sourceUserId == grantUri.sourceUserId
8168                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8169                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8170                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8171                    persistChanged |= perm.revokeModes(
8172                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8173                    if (perm.modeFlags == 0) {
8174                        it.remove();
8175                    }
8176                }
8177            }
8178
8179            if (perms.isEmpty()) {
8180                mGrantedUriPermissions.remove(targetUid);
8181                N--;
8182                i--;
8183            }
8184        }
8185
8186        if (persistChanged) {
8187            schedulePersistUriGrants();
8188        }
8189    }
8190
8191    /**
8192     * @param uri This uri must NOT contain an embedded userId.
8193     * @param userId The userId in which the uri is to be resolved.
8194     */
8195    @Override
8196    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8197            int userId) {
8198        enforceNotIsolatedCaller("revokeUriPermission");
8199        synchronized(this) {
8200            final ProcessRecord r = getRecordForAppLocked(caller);
8201            if (r == null) {
8202                throw new SecurityException("Unable to find app for caller "
8203                        + caller
8204                        + " when revoking permission to uri " + uri);
8205            }
8206            if (uri == null) {
8207                Slog.w(TAG, "revokeUriPermission: null uri");
8208                return;
8209            }
8210
8211            if (!Intent.isAccessUriMode(modeFlags)) {
8212                return;
8213            }
8214
8215            final String authority = uri.getAuthority();
8216            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8217            if (pi == null) {
8218                Slog.w(TAG, "No content provider found for permission revoke: "
8219                        + uri.toSafeString());
8220                return;
8221            }
8222
8223            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8224        }
8225    }
8226
8227    /**
8228     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8229     * given package.
8230     *
8231     * @param packageName Package name to match, or {@code null} to apply to all
8232     *            packages.
8233     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8234     *            to all users.
8235     * @param persistable If persistable grants should be removed.
8236     */
8237    private void removeUriPermissionsForPackageLocked(
8238            String packageName, int userHandle, boolean persistable) {
8239        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8240            throw new IllegalArgumentException("Must narrow by either package or user");
8241        }
8242
8243        boolean persistChanged = false;
8244
8245        int N = mGrantedUriPermissions.size();
8246        for (int i = 0; i < N; i++) {
8247            final int targetUid = mGrantedUriPermissions.keyAt(i);
8248            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8249
8250            // Only inspect grants matching user
8251            if (userHandle == UserHandle.USER_ALL
8252                    || userHandle == UserHandle.getUserId(targetUid)) {
8253                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8254                    final UriPermission perm = it.next();
8255
8256                    // Only inspect grants matching package
8257                    if (packageName == null || perm.sourcePkg.equals(packageName)
8258                            || perm.targetPkg.equals(packageName)) {
8259                        persistChanged |= perm.revokeModes(persistable
8260                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8261
8262                        // Only remove when no modes remain; any persisted grants
8263                        // will keep this alive.
8264                        if (perm.modeFlags == 0) {
8265                            it.remove();
8266                        }
8267                    }
8268                }
8269
8270                if (perms.isEmpty()) {
8271                    mGrantedUriPermissions.remove(targetUid);
8272                    N--;
8273                    i--;
8274                }
8275            }
8276        }
8277
8278        if (persistChanged) {
8279            schedulePersistUriGrants();
8280        }
8281    }
8282
8283    @Override
8284    public IBinder newUriPermissionOwner(String name) {
8285        enforceNotIsolatedCaller("newUriPermissionOwner");
8286        synchronized(this) {
8287            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8288            return owner.getExternalTokenLocked();
8289        }
8290    }
8291
8292    @Override
8293    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8294        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8295        synchronized(this) {
8296            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8297            if (r == null) {
8298                throw new IllegalArgumentException("Activity does not exist; token="
8299                        + activityToken);
8300            }
8301            return r.getUriPermissionsLocked().getExternalTokenLocked();
8302        }
8303    }
8304    /**
8305     * @param uri This uri must NOT contain an embedded userId.
8306     * @param sourceUserId The userId in which the uri is to be resolved.
8307     * @param targetUserId The userId of the app that receives the grant.
8308     */
8309    @Override
8310    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8311            final int modeFlags, int sourceUserId, int targetUserId) {
8312        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8313                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8314                "grantUriPermissionFromOwner", null);
8315        synchronized(this) {
8316            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8317            if (owner == null) {
8318                throw new IllegalArgumentException("Unknown owner: " + token);
8319            }
8320            if (fromUid != Binder.getCallingUid()) {
8321                if (Binder.getCallingUid() != Process.myUid()) {
8322                    // Only system code can grant URI permissions on behalf
8323                    // of other users.
8324                    throw new SecurityException("nice try");
8325                }
8326            }
8327            if (targetPkg == null) {
8328                throw new IllegalArgumentException("null target");
8329            }
8330            if (uri == null) {
8331                throw new IllegalArgumentException("null uri");
8332            }
8333
8334            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8335                    modeFlags, owner, targetUserId);
8336        }
8337    }
8338
8339    /**
8340     * @param uri This uri must NOT contain an embedded userId.
8341     * @param userId The userId in which the uri is to be resolved.
8342     */
8343    @Override
8344    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8345        synchronized(this) {
8346            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8347            if (owner == null) {
8348                throw new IllegalArgumentException("Unknown owner: " + token);
8349            }
8350
8351            if (uri == null) {
8352                owner.removeUriPermissionsLocked(mode);
8353            } else {
8354                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8355            }
8356        }
8357    }
8358
8359    private void schedulePersistUriGrants() {
8360        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8361            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8362                    10 * DateUtils.SECOND_IN_MILLIS);
8363        }
8364    }
8365
8366    private void writeGrantedUriPermissions() {
8367        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8368
8369        // Snapshot permissions so we can persist without lock
8370        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8371        synchronized (this) {
8372            final int size = mGrantedUriPermissions.size();
8373            for (int i = 0; i < size; i++) {
8374                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8375                for (UriPermission perm : perms.values()) {
8376                    if (perm.persistedModeFlags != 0) {
8377                        persist.add(perm.snapshot());
8378                    }
8379                }
8380            }
8381        }
8382
8383        FileOutputStream fos = null;
8384        try {
8385            fos = mGrantFile.startWrite();
8386
8387            XmlSerializer out = new FastXmlSerializer();
8388            out.setOutput(fos, StandardCharsets.UTF_8.name());
8389            out.startDocument(null, true);
8390            out.startTag(null, TAG_URI_GRANTS);
8391            for (UriPermission.Snapshot perm : persist) {
8392                out.startTag(null, TAG_URI_GRANT);
8393                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8394                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8395                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8396                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8397                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8398                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8399                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8400                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8401                out.endTag(null, TAG_URI_GRANT);
8402            }
8403            out.endTag(null, TAG_URI_GRANTS);
8404            out.endDocument();
8405
8406            mGrantFile.finishWrite(fos);
8407        } catch (IOException e) {
8408            if (fos != null) {
8409                mGrantFile.failWrite(fos);
8410            }
8411        }
8412    }
8413
8414    private void readGrantedUriPermissionsLocked() {
8415        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8416
8417        final long now = System.currentTimeMillis();
8418
8419        FileInputStream fis = null;
8420        try {
8421            fis = mGrantFile.openRead();
8422            final XmlPullParser in = Xml.newPullParser();
8423            in.setInput(fis, StandardCharsets.UTF_8.name());
8424
8425            int type;
8426            while ((type = in.next()) != END_DOCUMENT) {
8427                final String tag = in.getName();
8428                if (type == START_TAG) {
8429                    if (TAG_URI_GRANT.equals(tag)) {
8430                        final int sourceUserId;
8431                        final int targetUserId;
8432                        final int userHandle = readIntAttribute(in,
8433                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8434                        if (userHandle != UserHandle.USER_NULL) {
8435                            // For backwards compatibility.
8436                            sourceUserId = userHandle;
8437                            targetUserId = userHandle;
8438                        } else {
8439                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8440                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8441                        }
8442                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8443                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8444                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8445                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8446                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8447                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8448
8449                        // Sanity check that provider still belongs to source package
8450                        final ProviderInfo pi = getProviderInfoLocked(
8451                                uri.getAuthority(), sourceUserId);
8452                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8453                            int targetUid = -1;
8454                            try {
8455                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8456                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8457                            } catch (RemoteException e) {
8458                            }
8459                            if (targetUid != -1) {
8460                                final UriPermission perm = findOrCreateUriPermissionLocked(
8461                                        sourcePkg, targetPkg, targetUid,
8462                                        new GrantUri(sourceUserId, uri, prefix));
8463                                perm.initPersistedModes(modeFlags, createdTime);
8464                            }
8465                        } else {
8466                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8467                                    + " but instead found " + pi);
8468                        }
8469                    }
8470                }
8471            }
8472        } catch (FileNotFoundException e) {
8473            // Missing grants is okay
8474        } catch (IOException e) {
8475            Slog.wtf(TAG, "Failed reading Uri grants", e);
8476        } catch (XmlPullParserException e) {
8477            Slog.wtf(TAG, "Failed reading Uri grants", e);
8478        } finally {
8479            IoUtils.closeQuietly(fis);
8480        }
8481    }
8482
8483    /**
8484     * @param uri This uri must NOT contain an embedded userId.
8485     * @param userId The userId in which the uri is to be resolved.
8486     */
8487    @Override
8488    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8489        enforceNotIsolatedCaller("takePersistableUriPermission");
8490
8491        Preconditions.checkFlagsArgument(modeFlags,
8492                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8493
8494        synchronized (this) {
8495            final int callingUid = Binder.getCallingUid();
8496            boolean persistChanged = false;
8497            GrantUri grantUri = new GrantUri(userId, uri, false);
8498
8499            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8500                    new GrantUri(userId, uri, false));
8501            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8502                    new GrantUri(userId, uri, true));
8503
8504            final boolean exactValid = (exactPerm != null)
8505                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8506            final boolean prefixValid = (prefixPerm != null)
8507                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8508
8509            if (!(exactValid || prefixValid)) {
8510                throw new SecurityException("No persistable permission grants found for UID "
8511                        + callingUid + " and Uri " + grantUri.toSafeString());
8512            }
8513
8514            if (exactValid) {
8515                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8516            }
8517            if (prefixValid) {
8518                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8519            }
8520
8521            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8522
8523            if (persistChanged) {
8524                schedulePersistUriGrants();
8525            }
8526        }
8527    }
8528
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param userId The userId in which the uri is to be resolved.
8532     */
8533    @Override
8534    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8535        enforceNotIsolatedCaller("releasePersistableUriPermission");
8536
8537        Preconditions.checkFlagsArgument(modeFlags,
8538                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8539
8540        synchronized (this) {
8541            final int callingUid = Binder.getCallingUid();
8542            boolean persistChanged = false;
8543
8544            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8545                    new GrantUri(userId, uri, false));
8546            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8547                    new GrantUri(userId, uri, true));
8548            if (exactPerm == null && prefixPerm == null) {
8549                throw new SecurityException("No permission grants found for UID " + callingUid
8550                        + " and Uri " + uri.toSafeString());
8551            }
8552
8553            if (exactPerm != null) {
8554                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8555                removeUriPermissionIfNeededLocked(exactPerm);
8556            }
8557            if (prefixPerm != null) {
8558                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8559                removeUriPermissionIfNeededLocked(prefixPerm);
8560            }
8561
8562            if (persistChanged) {
8563                schedulePersistUriGrants();
8564            }
8565        }
8566    }
8567
8568    /**
8569     * Prune any older {@link UriPermission} for the given UID until outstanding
8570     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8571     *
8572     * @return if any mutations occured that require persisting.
8573     */
8574    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8575        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8576        if (perms == null) return false;
8577        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8578
8579        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8580        for (UriPermission perm : perms.values()) {
8581            if (perm.persistedModeFlags != 0) {
8582                persisted.add(perm);
8583            }
8584        }
8585
8586        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8587        if (trimCount <= 0) return false;
8588
8589        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8590        for (int i = 0; i < trimCount; i++) {
8591            final UriPermission perm = persisted.get(i);
8592
8593            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8594                    "Trimming grant created at " + perm.persistedCreateTime);
8595
8596            perm.releasePersistableModes(~0);
8597            removeUriPermissionIfNeededLocked(perm);
8598        }
8599
8600        return true;
8601    }
8602
8603    @Override
8604    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8605            String packageName, boolean incoming) {
8606        enforceNotIsolatedCaller("getPersistedUriPermissions");
8607        Preconditions.checkNotNull(packageName, "packageName");
8608
8609        final int callingUid = Binder.getCallingUid();
8610        final IPackageManager pm = AppGlobals.getPackageManager();
8611        try {
8612            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8613                    UserHandle.getUserId(callingUid));
8614            if (packageUid != callingUid) {
8615                throw new SecurityException(
8616                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8617            }
8618        } catch (RemoteException e) {
8619            throw new SecurityException("Failed to verify package name ownership");
8620        }
8621
8622        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8623        synchronized (this) {
8624            if (incoming) {
8625                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8626                        callingUid);
8627                if (perms == null) {
8628                    Slog.w(TAG, "No permission grants found for " + packageName);
8629                } else {
8630                    for (UriPermission perm : perms.values()) {
8631                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8632                            result.add(perm.buildPersistedPublicApiObject());
8633                        }
8634                    }
8635                }
8636            } else {
8637                final int size = mGrantedUriPermissions.size();
8638                for (int i = 0; i < size; i++) {
8639                    final ArrayMap<GrantUri, UriPermission> perms =
8640                            mGrantedUriPermissions.valueAt(i);
8641                    for (UriPermission perm : perms.values()) {
8642                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8643                            result.add(perm.buildPersistedPublicApiObject());
8644                        }
8645                    }
8646                }
8647            }
8648        }
8649        return new ParceledListSlice<android.content.UriPermission>(result);
8650    }
8651
8652    @Override
8653    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8654            String packageName, int userId) {
8655        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8656                "getGrantedUriPermissions");
8657
8658        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8659        synchronized (this) {
8660            final int size = mGrantedUriPermissions.size();
8661            for (int i = 0; i < size; i++) {
8662                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8663                for (UriPermission perm : perms.values()) {
8664                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8665                            && perm.persistedModeFlags != 0) {
8666                        result.add(perm.buildPersistedPublicApiObject());
8667                    }
8668                }
8669            }
8670        }
8671        return new ParceledListSlice<android.content.UriPermission>(result);
8672    }
8673
8674    @Override
8675    public void clearGrantedUriPermissions(String packageName, int userId) {
8676        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8677                "clearGrantedUriPermissions");
8678        removeUriPermissionsForPackageLocked(packageName, userId, true);
8679    }
8680
8681    @Override
8682    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8683        synchronized (this) {
8684            ProcessRecord app =
8685                who != null ? getRecordForAppLocked(who) : null;
8686            if (app == null) return;
8687
8688            Message msg = Message.obtain();
8689            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8690            msg.obj = app;
8691            msg.arg1 = waiting ? 1 : 0;
8692            mUiHandler.sendMessage(msg);
8693        }
8694    }
8695
8696    @Override
8697    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8698        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8699        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8700        outInfo.availMem = Process.getFreeMemory();
8701        outInfo.totalMem = Process.getTotalMemory();
8702        outInfo.threshold = homeAppMem;
8703        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8704        outInfo.hiddenAppThreshold = cachedAppMem;
8705        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8706                ProcessList.SERVICE_ADJ);
8707        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8708                ProcessList.VISIBLE_APP_ADJ);
8709        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8710                ProcessList.FOREGROUND_APP_ADJ);
8711    }
8712
8713    // =========================================================
8714    // TASK MANAGEMENT
8715    // =========================================================
8716
8717    @Override
8718    public List<IAppTask> getAppTasks(String callingPackage) {
8719        int callingUid = Binder.getCallingUid();
8720        long ident = Binder.clearCallingIdentity();
8721
8722        synchronized(this) {
8723            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8724            try {
8725                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8726
8727                final int N = mRecentTasks.size();
8728                for (int i = 0; i < N; i++) {
8729                    TaskRecord tr = mRecentTasks.get(i);
8730                    // Skip tasks that do not match the caller.  We don't need to verify
8731                    // callingPackage, because we are also limiting to callingUid and know
8732                    // that will limit to the correct security sandbox.
8733                    if (tr.effectiveUid != callingUid) {
8734                        continue;
8735                    }
8736                    Intent intent = tr.getBaseIntent();
8737                    if (intent == null ||
8738                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8739                        continue;
8740                    }
8741                    ActivityManager.RecentTaskInfo taskInfo =
8742                            createRecentTaskInfoFromTaskRecord(tr);
8743                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8744                    list.add(taskImpl);
8745                }
8746            } finally {
8747                Binder.restoreCallingIdentity(ident);
8748            }
8749            return list;
8750        }
8751    }
8752
8753    @Override
8754    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8755        final int callingUid = Binder.getCallingUid();
8756        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8757
8758        synchronized(this) {
8759            if (DEBUG_ALL) Slog.v(
8760                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8761
8762            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8763                    callingUid);
8764
8765            // TODO: Improve with MRU list from all ActivityStacks.
8766            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8767        }
8768
8769        return list;
8770    }
8771
8772    /**
8773     * Creates a new RecentTaskInfo from a TaskRecord.
8774     */
8775    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8776        // Update the task description to reflect any changes in the task stack
8777        tr.updateTaskDescription();
8778
8779        // Compose the recent task info
8780        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8781        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8782        rti.persistentId = tr.taskId;
8783        rti.baseIntent = new Intent(tr.getBaseIntent());
8784        rti.origActivity = tr.origActivity;
8785        rti.realActivity = tr.realActivity;
8786        rti.description = tr.lastDescription;
8787        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8788        rti.userId = tr.userId;
8789        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8790        rti.firstActiveTime = tr.firstActiveTime;
8791        rti.lastActiveTime = tr.lastActiveTime;
8792        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8793        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8794        rti.numActivities = 0;
8795        if (tr.mBounds != null) {
8796            rti.bounds = new Rect(tr.mBounds);
8797        }
8798        rti.isDockable = tr.canGoInDockedStack();
8799        rti.resizeMode = tr.mResizeMode;
8800
8801        ActivityRecord base = null;
8802        ActivityRecord top = null;
8803        ActivityRecord tmp;
8804
8805        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8806            tmp = tr.mActivities.get(i);
8807            if (tmp.finishing) {
8808                continue;
8809            }
8810            base = tmp;
8811            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8812                top = base;
8813            }
8814            rti.numActivities++;
8815        }
8816
8817        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8818        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8819
8820        return rti;
8821    }
8822
8823    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8824        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8825                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8826        if (!allowed) {
8827            if (checkPermission(android.Manifest.permission.GET_TASKS,
8828                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8829                // Temporary compatibility: some existing apps on the system image may
8830                // still be requesting the old permission and not switched to the new
8831                // one; if so, we'll still allow them full access.  This means we need
8832                // to see if they are holding the old permission and are a system app.
8833                try {
8834                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8835                        allowed = true;
8836                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8837                                + " is using old GET_TASKS but privileged; allowing");
8838                    }
8839                } catch (RemoteException e) {
8840                }
8841            }
8842        }
8843        if (!allowed) {
8844            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8845                    + " does not hold REAL_GET_TASKS; limiting output");
8846        }
8847        return allowed;
8848    }
8849
8850    @Override
8851    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8852        final int callingUid = Binder.getCallingUid();
8853        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8854                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8855
8856        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8857        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8858        synchronized (this) {
8859            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8860                    callingUid);
8861            final boolean detailed = checkCallingPermission(
8862                    android.Manifest.permission.GET_DETAILED_TASKS)
8863                    == PackageManager.PERMISSION_GRANTED;
8864
8865            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8866                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8867                return Collections.emptyList();
8868            }
8869            mRecentTasks.loadUserRecentsLocked(userId);
8870
8871            final int recentsCount = mRecentTasks.size();
8872            ArrayList<ActivityManager.RecentTaskInfo> res =
8873                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8874
8875            final Set<Integer> includedUsers;
8876            if (includeProfiles) {
8877                includedUsers = mUserController.getProfileIds(userId);
8878            } else {
8879                includedUsers = new HashSet<>();
8880            }
8881            includedUsers.add(Integer.valueOf(userId));
8882
8883            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8884                TaskRecord tr = mRecentTasks.get(i);
8885                // Only add calling user or related users recent tasks
8886                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8887                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8888                    continue;
8889                }
8890
8891                if (tr.realActivitySuspended) {
8892                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8893                    continue;
8894                }
8895
8896                // Return the entry if desired by the caller.  We always return
8897                // the first entry, because callers always expect this to be the
8898                // foreground app.  We may filter others if the caller has
8899                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8900                // we should exclude the entry.
8901
8902                if (i == 0
8903                        || withExcluded
8904                        || (tr.intent == null)
8905                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8906                                == 0)) {
8907                    if (!allowed) {
8908                        // If the caller doesn't have the GET_TASKS permission, then only
8909                        // allow them to see a small subset of tasks -- their own and home.
8910                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8911                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8912                            continue;
8913                        }
8914                    }
8915                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8916                        if (tr.stack != null && tr.stack.isHomeStack()) {
8917                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8918                                    "Skipping, home stack task: " + tr);
8919                            continue;
8920                        }
8921                    }
8922                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8923                        final ActivityStack stack = tr.stack;
8924                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8925                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8926                                    "Skipping, top task in docked stack: " + tr);
8927                            continue;
8928                        }
8929                    }
8930                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8931                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8932                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8933                                    "Skipping, pinned stack task: " + tr);
8934                            continue;
8935                        }
8936                    }
8937                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8938                        // Don't include auto remove tasks that are finished or finishing.
8939                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8940                                "Skipping, auto-remove without activity: " + tr);
8941                        continue;
8942                    }
8943                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8944                            && !tr.isAvailable) {
8945                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8946                                "Skipping, unavail real act: " + tr);
8947                        continue;
8948                    }
8949
8950                    if (!tr.mUserSetupComplete) {
8951                        // Don't include task launched while user is not done setting-up.
8952                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8953                                "Skipping, user setup not complete: " + tr);
8954                        continue;
8955                    }
8956
8957                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8958                    if (!detailed) {
8959                        rti.baseIntent.replaceExtras((Bundle)null);
8960                    }
8961
8962                    res.add(rti);
8963                    maxNum--;
8964                }
8965            }
8966            return res;
8967        }
8968    }
8969
8970    @Override
8971    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8972        synchronized (this) {
8973            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8974                    "getTaskThumbnail()");
8975            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8976                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8977            if (tr != null) {
8978                return tr.getTaskThumbnailLocked();
8979            }
8980        }
8981        return null;
8982    }
8983
8984    @Override
8985    public int addAppTask(IBinder activityToken, Intent intent,
8986            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8987        final int callingUid = Binder.getCallingUid();
8988        final long callingIdent = Binder.clearCallingIdentity();
8989
8990        try {
8991            synchronized (this) {
8992                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8993                if (r == null) {
8994                    throw new IllegalArgumentException("Activity does not exist; token="
8995                            + activityToken);
8996                }
8997                ComponentName comp = intent.getComponent();
8998                if (comp == null) {
8999                    throw new IllegalArgumentException("Intent " + intent
9000                            + " must specify explicit component");
9001                }
9002                if (thumbnail.getWidth() != mThumbnailWidth
9003                        || thumbnail.getHeight() != mThumbnailHeight) {
9004                    throw new IllegalArgumentException("Bad thumbnail size: got "
9005                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9006                            + mThumbnailWidth + "x" + mThumbnailHeight);
9007                }
9008                if (intent.getSelector() != null) {
9009                    intent.setSelector(null);
9010                }
9011                if (intent.getSourceBounds() != null) {
9012                    intent.setSourceBounds(null);
9013                }
9014                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9015                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9016                        // The caller has added this as an auto-remove task...  that makes no
9017                        // sense, so turn off auto-remove.
9018                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9019                    }
9020                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9021                    // Must be a new task.
9022                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9023                }
9024                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9025                    mLastAddedTaskActivity = null;
9026                }
9027                ActivityInfo ainfo = mLastAddedTaskActivity;
9028                if (ainfo == null) {
9029                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9030                            comp, 0, UserHandle.getUserId(callingUid));
9031                    if (ainfo.applicationInfo.uid != callingUid) {
9032                        throw new SecurityException(
9033                                "Can't add task for another application: target uid="
9034                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9035                    }
9036                }
9037
9038                // Use the full screen as the context for the task thumbnail
9039                final Point displaySize = new Point();
9040                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9041                r.task.stack.getDisplaySize(displaySize);
9042                thumbnailInfo.taskWidth = displaySize.x;
9043                thumbnailInfo.taskHeight = displaySize.y;
9044                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9045
9046                TaskRecord task = new TaskRecord(this,
9047                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9048                        ainfo, intent, description, thumbnailInfo);
9049
9050                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9051                if (trimIdx >= 0) {
9052                    // If this would have caused a trim, then we'll abort because that
9053                    // means it would be added at the end of the list but then just removed.
9054                    return INVALID_TASK_ID;
9055                }
9056
9057                final int N = mRecentTasks.size();
9058                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9059                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9060                    tr.removedFromRecents();
9061                }
9062
9063                task.inRecents = true;
9064                mRecentTasks.add(task);
9065                r.task.stack.addTask(task, false, "addAppTask");
9066
9067                task.setLastThumbnailLocked(thumbnail);
9068                task.freeLastThumbnail();
9069
9070                return task.taskId;
9071            }
9072        } finally {
9073            Binder.restoreCallingIdentity(callingIdent);
9074        }
9075    }
9076
9077    @Override
9078    public Point getAppTaskThumbnailSize() {
9079        synchronized (this) {
9080            return new Point(mThumbnailWidth,  mThumbnailHeight);
9081        }
9082    }
9083
9084    @Override
9085    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9086        synchronized (this) {
9087            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9088            if (r != null) {
9089                r.setTaskDescription(td);
9090                r.task.updateTaskDescription();
9091            }
9092        }
9093    }
9094
9095    @Override
9096    public void setTaskResizeable(int taskId, int resizeableMode) {
9097        synchronized (this) {
9098            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9099                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9100            if (task == null) {
9101                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9102                return;
9103            }
9104            if (task.mResizeMode != resizeableMode) {
9105                task.mResizeMode = resizeableMode;
9106                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9107                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9108                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9109            }
9110        }
9111    }
9112
9113    @Override
9114    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9115        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9116        long ident = Binder.clearCallingIdentity();
9117        try {
9118            synchronized (this) {
9119                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9120                if (task == null) {
9121                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9122                    return;
9123                }
9124                int stackId = task.stack.mStackId;
9125                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9126                // in crop windows resize mode or if the task size is affected by the docked stack
9127                // changing size. No need to update configuration.
9128                if (bounds != null && task.inCropWindowsResizeMode()
9129                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9130                    mWindowManager.scrollTask(task.taskId, bounds);
9131                    return;
9132                }
9133
9134                // Place the task in the right stack if it isn't there already based on
9135                // the requested bounds.
9136                // The stack transition logic is:
9137                // - a null bounds on a freeform task moves that task to fullscreen
9138                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9139                //   that task to freeform
9140                // - otherwise the task is not moved
9141                if (!StackId.isTaskResizeAllowed(stackId)) {
9142                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9143                }
9144                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9145                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9146                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9147                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9148                }
9149                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9150                if (stackId != task.stack.mStackId) {
9151                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9152                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9153                    preserveWindow = false;
9154                }
9155
9156                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9157                        false /* deferResume */);
9158            }
9159        } finally {
9160            Binder.restoreCallingIdentity(ident);
9161        }
9162    }
9163
9164    @Override
9165    public Rect getTaskBounds(int taskId) {
9166        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9167        long ident = Binder.clearCallingIdentity();
9168        Rect rect = new Rect();
9169        try {
9170            synchronized (this) {
9171                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9172                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9173                if (task == null) {
9174                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9175                    return rect;
9176                }
9177                if (task.stack != null) {
9178                    // Return the bounds from window manager since it will be adjusted for various
9179                    // things like the presense of a docked stack for tasks that aren't resizeable.
9180                    mWindowManager.getTaskBounds(task.taskId, rect);
9181                } else {
9182                    // Task isn't in window manager yet since it isn't associated with a stack.
9183                    // Return the persist value from activity manager
9184                    if (task.mBounds != null) {
9185                        rect.set(task.mBounds);
9186                    } else if (task.mLastNonFullscreenBounds != null) {
9187                        rect.set(task.mLastNonFullscreenBounds);
9188                    }
9189                }
9190            }
9191        } finally {
9192            Binder.restoreCallingIdentity(ident);
9193        }
9194        return rect;
9195    }
9196
9197    @Override
9198    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9199        if (userId != UserHandle.getCallingUserId()) {
9200            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9201                    "getTaskDescriptionIcon");
9202        }
9203        final File passedIconFile = new File(filePath);
9204        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9205                passedIconFile.getName());
9206        if (!legitIconFile.getPath().equals(filePath)
9207                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9208            throw new IllegalArgumentException("Bad file path: " + filePath
9209                    + " passed for userId " + userId);
9210        }
9211        return mRecentTasks.getTaskDescriptionIcon(filePath);
9212    }
9213
9214    @Override
9215    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9216            throws RemoteException {
9217        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9218                opts.getCustomInPlaceResId() == 0) {
9219            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9220                    "with valid animation");
9221        }
9222        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9223        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9224                opts.getCustomInPlaceResId());
9225        mWindowManager.executeAppTransition();
9226    }
9227
9228    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9229            boolean removeFromRecents) {
9230        if (removeFromRecents) {
9231            mRecentTasks.remove(tr);
9232            tr.removedFromRecents();
9233        }
9234        ComponentName component = tr.getBaseIntent().getComponent();
9235        if (component == null) {
9236            Slog.w(TAG, "No component for base intent of task: " + tr);
9237            return;
9238        }
9239
9240        // Find any running services associated with this app and stop if needed.
9241        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9242
9243        if (!killProcess) {
9244            return;
9245        }
9246
9247        // Determine if the process(es) for this task should be killed.
9248        final String pkg = component.getPackageName();
9249        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9250        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9251        for (int i = 0; i < pmap.size(); i++) {
9252
9253            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9254            for (int j = 0; j < uids.size(); j++) {
9255                ProcessRecord proc = uids.valueAt(j);
9256                if (proc.userId != tr.userId) {
9257                    // Don't kill process for a different user.
9258                    continue;
9259                }
9260                if (proc == mHomeProcess) {
9261                    // Don't kill the home process along with tasks from the same package.
9262                    continue;
9263                }
9264                if (!proc.pkgList.containsKey(pkg)) {
9265                    // Don't kill process that is not associated with this task.
9266                    continue;
9267                }
9268
9269                for (int k = 0; k < proc.activities.size(); k++) {
9270                    TaskRecord otherTask = proc.activities.get(k).task;
9271                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9272                        // Don't kill process(es) that has an activity in a different task that is
9273                        // also in recents.
9274                        return;
9275                    }
9276                }
9277
9278                if (proc.foregroundServices) {
9279                    // Don't kill process(es) with foreground service.
9280                    return;
9281                }
9282
9283                // Add process to kill list.
9284                procsToKill.add(proc);
9285            }
9286        }
9287
9288        // Kill the running processes.
9289        for (int i = 0; i < procsToKill.size(); i++) {
9290            ProcessRecord pr = procsToKill.get(i);
9291            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9292                    && pr.curReceiver == null) {
9293                pr.kill("remove task", true);
9294            } else {
9295                // We delay killing processes that are not in the background or running a receiver.
9296                pr.waitingToKill = "remove task";
9297            }
9298        }
9299    }
9300
9301    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9302        // Remove all tasks with activities in the specified package from the list of recent tasks
9303        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9304            TaskRecord tr = mRecentTasks.get(i);
9305            if (tr.userId != userId) continue;
9306
9307            ComponentName cn = tr.intent.getComponent();
9308            if (cn != null && cn.getPackageName().equals(packageName)) {
9309                // If the package name matches, remove the task.
9310                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9311            }
9312        }
9313    }
9314
9315    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9316            int userId) {
9317
9318        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9319            TaskRecord tr = mRecentTasks.get(i);
9320            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9321                continue;
9322            }
9323
9324            ComponentName cn = tr.intent.getComponent();
9325            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9326                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9327            if (sameComponent) {
9328                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9329            }
9330        }
9331    }
9332
9333    /**
9334     * Removes the task with the specified task id.
9335     *
9336     * @param taskId Identifier of the task to be removed.
9337     * @param killProcess Kill any process associated with the task if possible.
9338     * @param removeFromRecents Whether to also remove the task from recents.
9339     * @return Returns true if the given task was found and removed.
9340     */
9341    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9342            boolean removeFromRecents) {
9343        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9344                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9345        if (tr != null) {
9346            tr.removeTaskActivitiesLocked();
9347            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9348            if (tr.isPersistable) {
9349                notifyTaskPersisterLocked(null, true);
9350            }
9351            return true;
9352        }
9353        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9354        return false;
9355    }
9356
9357    @Override
9358    public void removeStack(int stackId) {
9359        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9360        if (stackId == HOME_STACK_ID) {
9361            throw new IllegalArgumentException("Removing home stack is not allowed.");
9362        }
9363
9364        synchronized (this) {
9365            final long ident = Binder.clearCallingIdentity();
9366            try {
9367                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9368                if (stack == null) {
9369                    return;
9370                }
9371                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9372                for (int i = tasks.size() - 1; i >= 0; i--) {
9373                    removeTaskByIdLocked(
9374                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9375                }
9376            } finally {
9377                Binder.restoreCallingIdentity(ident);
9378            }
9379        }
9380    }
9381
9382    @Override
9383    public boolean removeTask(int taskId) {
9384        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9385        synchronized (this) {
9386            final long ident = Binder.clearCallingIdentity();
9387            try {
9388                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9389            } finally {
9390                Binder.restoreCallingIdentity(ident);
9391            }
9392        }
9393    }
9394
9395    /**
9396     * TODO: Add mController hook
9397     */
9398    @Override
9399    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9400        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9401
9402        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9403        synchronized(this) {
9404            moveTaskToFrontLocked(taskId, flags, bOptions);
9405        }
9406    }
9407
9408    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9409        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9410
9411        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9412                Binder.getCallingUid(), -1, -1, "Task to front")) {
9413            ActivityOptions.abort(options);
9414            return;
9415        }
9416        final long origId = Binder.clearCallingIdentity();
9417        try {
9418            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9419            if (task == null) {
9420                Slog.d(TAG, "Could not find task for id: "+ taskId);
9421                return;
9422            }
9423            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9424                mStackSupervisor.showLockTaskToast();
9425                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9426                return;
9427            }
9428            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9429            if (prev != null && prev.isRecentsActivity()) {
9430                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9431            }
9432            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9433                    false /* forceNonResizable */);
9434        } finally {
9435            Binder.restoreCallingIdentity(origId);
9436        }
9437        ActivityOptions.abort(options);
9438    }
9439
9440    /**
9441     * Moves an activity, and all of the other activities within the same task, to the bottom
9442     * of the history stack.  The activity's order within the task is unchanged.
9443     *
9444     * @param token A reference to the activity we wish to move
9445     * @param nonRoot If false then this only works if the activity is the root
9446     *                of a task; if true it will work for any activity in a task.
9447     * @return Returns true if the move completed, false if not.
9448     */
9449    @Override
9450    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9451        enforceNotIsolatedCaller("moveActivityTaskToBack");
9452        synchronized(this) {
9453            final long origId = Binder.clearCallingIdentity();
9454            try {
9455                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9456                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9457                if (task != null) {
9458                    if (mStackSupervisor.isLockedTask(task)) {
9459                        mStackSupervisor.showLockTaskToast();
9460                        return false;
9461                    }
9462                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9463                }
9464            } finally {
9465                Binder.restoreCallingIdentity(origId);
9466            }
9467        }
9468        return false;
9469    }
9470
9471    @Override
9472    public void moveTaskBackwards(int task) {
9473        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9474                "moveTaskBackwards()");
9475
9476        synchronized(this) {
9477            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9478                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9479                return;
9480            }
9481            final long origId = Binder.clearCallingIdentity();
9482            moveTaskBackwardsLocked(task);
9483            Binder.restoreCallingIdentity(origId);
9484        }
9485    }
9486
9487    private final void moveTaskBackwardsLocked(int task) {
9488        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9489    }
9490
9491    @Override
9492    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9493            IActivityContainerCallback callback) throws RemoteException {
9494        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9495        synchronized (this) {
9496            if (parentActivityToken == null) {
9497                throw new IllegalArgumentException("parent token must not be null");
9498            }
9499            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9500            if (r == null) {
9501                return null;
9502            }
9503            if (callback == null) {
9504                throw new IllegalArgumentException("callback must not be null");
9505            }
9506            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9507        }
9508    }
9509
9510    @Override
9511    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9512        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9513        synchronized (this) {
9514            mStackSupervisor.deleteActivityContainer(container);
9515        }
9516    }
9517
9518    @Override
9519    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9520        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9521        synchronized (this) {
9522            final int stackId = mStackSupervisor.getNextStackId();
9523            final ActivityStack stack =
9524                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9525            if (stack == null) {
9526                return null;
9527            }
9528            return stack.mActivityContainer;
9529        }
9530    }
9531
9532    @Override
9533    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9534        synchronized (this) {
9535            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9536            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9537                return stack.mActivityContainer.getDisplayId();
9538            }
9539            return Display.DEFAULT_DISPLAY;
9540        }
9541    }
9542
9543    @Override
9544    public int getActivityStackId(IBinder token) throws RemoteException {
9545        synchronized (this) {
9546            ActivityStack stack = ActivityRecord.getStackLocked(token);
9547            if (stack == null) {
9548                return INVALID_STACK_ID;
9549            }
9550            return stack.mStackId;
9551        }
9552    }
9553
9554    @Override
9555    public void exitFreeformMode(IBinder token) throws RemoteException {
9556        synchronized (this) {
9557            long ident = Binder.clearCallingIdentity();
9558            try {
9559                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9560                if (r == null) {
9561                    throw new IllegalArgumentException(
9562                            "exitFreeformMode: No activity record matching token=" + token);
9563                }
9564                final ActivityStack stack = r.getStackLocked(token);
9565                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9566                    throw new IllegalStateException(
9567                            "exitFreeformMode: You can only go fullscreen from freeform.");
9568                }
9569                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9570                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9571                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9572            } finally {
9573                Binder.restoreCallingIdentity(ident);
9574            }
9575        }
9576    }
9577
9578    @Override
9579    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9580        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9581        if (stackId == HOME_STACK_ID) {
9582            throw new IllegalArgumentException(
9583                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9584        }
9585        synchronized (this) {
9586            long ident = Binder.clearCallingIdentity();
9587            try {
9588                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9589                        + " to stackId=" + stackId + " toTop=" + toTop);
9590                if (stackId == DOCKED_STACK_ID) {
9591                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9592                            null /* initialBounds */);
9593                }
9594                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9595                        "moveTaskToStack", ANIMATE);
9596            } finally {
9597                Binder.restoreCallingIdentity(ident);
9598            }
9599        }
9600    }
9601
9602    @Override
9603    public void swapDockedAndFullscreenStack() throws RemoteException {
9604        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9605        synchronized (this) {
9606            long ident = Binder.clearCallingIdentity();
9607            try {
9608                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9609                        FULLSCREEN_WORKSPACE_STACK_ID);
9610                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9611                        : null;
9612                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9613                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9614                        : null;
9615                if (topTask == null || tasks == null || tasks.size() == 0) {
9616                    Slog.w(TAG,
9617                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9618                    return;
9619                }
9620
9621                // TODO: App transition
9622                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9623
9624                // Defer the resume so resume/pausing while moving stacks is dangerous.
9625                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9626                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9627                        ANIMATE, true /* deferResume */);
9628                final int size = tasks.size();
9629                for (int i = 0; i < size; i++) {
9630                    final int id = tasks.get(i).taskId;
9631                    if (id == topTask.taskId) {
9632                        continue;
9633                    }
9634                    mStackSupervisor.moveTaskToStackLocked(id,
9635                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9636                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9637                }
9638
9639                // Because we deferred the resume, to avoid conflicts with stack switches while
9640                // resuming, we need to do it after all the tasks are moved.
9641                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9642                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9643
9644                mWindowManager.executeAppTransition();
9645            } finally {
9646                Binder.restoreCallingIdentity(ident);
9647            }
9648        }
9649    }
9650
9651    /**
9652     * Moves the input task to the docked stack.
9653     *
9654     * @param taskId Id of task to move.
9655     * @param createMode The mode the docked stack should be created in if it doesn't exist
9656     *                   already. See
9657     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9658     *                   and
9659     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9660     * @param toTop If the task and stack should be moved to the top.
9661     * @param animate Whether we should play an animation for the moving the task
9662     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9663     *                      docked stack. Pass {@code null} to use default bounds.
9664     */
9665    @Override
9666    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9667            Rect initialBounds) {
9668        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9669        synchronized (this) {
9670            long ident = Binder.clearCallingIdentity();
9671            try {
9672                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9673                        + " to createMode=" + createMode + " toTop=" + toTop);
9674                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9675                return mStackSupervisor.moveTaskToStackLocked(
9676                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9677                        "moveTaskToDockedStack", animate);
9678            } finally {
9679                Binder.restoreCallingIdentity(ident);
9680            }
9681        }
9682    }
9683
9684    /**
9685     * Moves the top activity in the input stackId to the pinned stack.
9686     *
9687     * @param stackId Id of stack to move the top activity to pinned stack.
9688     * @param bounds Bounds to use for pinned stack.
9689     *
9690     * @return True if the top activity of the input stack was successfully moved to the pinned
9691     *          stack.
9692     */
9693    @Override
9694    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9695        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9696        synchronized (this) {
9697            if (!mSupportsPictureInPicture) {
9698                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9699                        + "Device doesn't support picture-in-pciture mode");
9700            }
9701
9702            long ident = Binder.clearCallingIdentity();
9703            try {
9704                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9705            } finally {
9706                Binder.restoreCallingIdentity(ident);
9707            }
9708        }
9709    }
9710
9711    @Override
9712    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9713            boolean preserveWindows, boolean animate, int animationDuration) {
9714        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9715        long ident = Binder.clearCallingIdentity();
9716        try {
9717            synchronized (this) {
9718                if (animate) {
9719                    if (stackId == PINNED_STACK_ID) {
9720                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9721                    } else {
9722                        throw new IllegalArgumentException("Stack: " + stackId
9723                                + " doesn't support animated resize.");
9724                    }
9725                } else {
9726                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9727                            null /* tempTaskInsetBounds */, preserveWindows,
9728                            allowResizeInDockedMode, !DEFER_RESUME);
9729                }
9730            }
9731        } finally {
9732            Binder.restoreCallingIdentity(ident);
9733        }
9734    }
9735
9736    @Override
9737    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9738            Rect tempDockedTaskInsetBounds,
9739            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9740        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9741                "resizeDockedStack()");
9742        long ident = Binder.clearCallingIdentity();
9743        try {
9744            synchronized (this) {
9745                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9746                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9747                        PRESERVE_WINDOWS);
9748            }
9749        } finally {
9750            Binder.restoreCallingIdentity(ident);
9751        }
9752    }
9753
9754    @Override
9755    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9756        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9757                "resizePinnedStack()");
9758        final long ident = Binder.clearCallingIdentity();
9759        try {
9760            synchronized (this) {
9761                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9762            }
9763        } finally {
9764            Binder.restoreCallingIdentity(ident);
9765        }
9766    }
9767
9768    @Override
9769    public void positionTaskInStack(int taskId, int stackId, int position) {
9770        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9771        if (stackId == HOME_STACK_ID) {
9772            throw new IllegalArgumentException(
9773                    "positionTaskInStack: Attempt to change the position of task "
9774                    + taskId + " in/to home stack");
9775        }
9776        synchronized (this) {
9777            long ident = Binder.clearCallingIdentity();
9778            try {
9779                if (DEBUG_STACK) Slog.d(TAG_STACK,
9780                        "positionTaskInStack: positioning task=" + taskId
9781                        + " in stackId=" + stackId + " at position=" + position);
9782                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9783            } finally {
9784                Binder.restoreCallingIdentity(ident);
9785            }
9786        }
9787    }
9788
9789    @Override
9790    public List<StackInfo> getAllStackInfos() {
9791        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9792        long ident = Binder.clearCallingIdentity();
9793        try {
9794            synchronized (this) {
9795                return mStackSupervisor.getAllStackInfosLocked();
9796            }
9797        } finally {
9798            Binder.restoreCallingIdentity(ident);
9799        }
9800    }
9801
9802    @Override
9803    public StackInfo getStackInfo(int stackId) {
9804        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9805        long ident = Binder.clearCallingIdentity();
9806        try {
9807            synchronized (this) {
9808                return mStackSupervisor.getStackInfoLocked(stackId);
9809            }
9810        } finally {
9811            Binder.restoreCallingIdentity(ident);
9812        }
9813    }
9814
9815    @Override
9816    public boolean isInHomeStack(int taskId) {
9817        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9818        long ident = Binder.clearCallingIdentity();
9819        try {
9820            synchronized (this) {
9821                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9822                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9823                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9824            }
9825        } finally {
9826            Binder.restoreCallingIdentity(ident);
9827        }
9828    }
9829
9830    @Override
9831    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9832        synchronized(this) {
9833            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9834        }
9835    }
9836
9837    @Override
9838    public void updateDeviceOwner(String packageName) {
9839        final int callingUid = Binder.getCallingUid();
9840        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9841            throw new SecurityException("updateDeviceOwner called from non-system process");
9842        }
9843        synchronized (this) {
9844            mDeviceOwnerName = packageName;
9845        }
9846    }
9847
9848    @Override
9849    public void updateLockTaskPackages(int userId, String[] packages) {
9850        final int callingUid = Binder.getCallingUid();
9851        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9852            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9853                    "updateLockTaskPackages()");
9854        }
9855        synchronized (this) {
9856            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9857                    Arrays.toString(packages));
9858            mLockTaskPackages.put(userId, packages);
9859            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9860        }
9861    }
9862
9863
9864    void startLockTaskModeLocked(TaskRecord task) {
9865        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9866        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9867            return;
9868        }
9869
9870        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9871        // is initiated by system after the pinning request was shown and locked mode is initiated
9872        // by an authorized app directly
9873        final int callingUid = Binder.getCallingUid();
9874        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9875        long ident = Binder.clearCallingIdentity();
9876        try {
9877            if (!isSystemInitiated) {
9878                task.mLockTaskUid = callingUid;
9879                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9880                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9881                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9882                    StatusBarManagerInternal statusBarManager =
9883                            LocalServices.getService(StatusBarManagerInternal.class);
9884                    if (statusBarManager != null) {
9885                        statusBarManager.showScreenPinningRequest(task.taskId);
9886                    }
9887                    return;
9888                }
9889
9890                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9891                if (stack == null || task != stack.topTask()) {
9892                    throw new IllegalArgumentException("Invalid task, not in foreground");
9893                }
9894            }
9895            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9896                    "Locking fully");
9897            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9898                    ActivityManager.LOCK_TASK_MODE_PINNED :
9899                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9900                    "startLockTask", true);
9901        } finally {
9902            Binder.restoreCallingIdentity(ident);
9903        }
9904    }
9905
9906    @Override
9907    public void startLockTaskMode(int taskId) {
9908        synchronized (this) {
9909            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9910            if (task != null) {
9911                startLockTaskModeLocked(task);
9912            }
9913        }
9914    }
9915
9916    @Override
9917    public void startLockTaskMode(IBinder token) {
9918        synchronized (this) {
9919            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9920            if (r == null) {
9921                return;
9922            }
9923            final TaskRecord task = r.task;
9924            if (task != null) {
9925                startLockTaskModeLocked(task);
9926            }
9927        }
9928    }
9929
9930    @Override
9931    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9932        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9933        // This makes inner call to look as if it was initiated by system.
9934        long ident = Binder.clearCallingIdentity();
9935        try {
9936            synchronized (this) {
9937                startLockTaskMode(taskId);
9938            }
9939        } finally {
9940            Binder.restoreCallingIdentity(ident);
9941        }
9942    }
9943
9944    @Override
9945    public void stopLockTaskMode() {
9946        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9947        if (lockTask == null) {
9948            // Our work here is done.
9949            return;
9950        }
9951
9952        final int callingUid = Binder.getCallingUid();
9953        final int lockTaskUid = lockTask.mLockTaskUid;
9954        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9955        // It is possible lockTaskMode was started by the system process because
9956        // android:lockTaskMode is set to a locking value in the application manifest instead of
9957        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9958        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9959        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9960                callingUid != lockTaskUid
9961                && (lockTaskUid != 0
9962                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9963            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9964                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9965        }
9966
9967        long ident = Binder.clearCallingIdentity();
9968        try {
9969            Log.d(TAG, "stopLockTaskMode");
9970            // Stop lock task
9971            synchronized (this) {
9972                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9973                        "stopLockTask", true);
9974            }
9975        } finally {
9976            Binder.restoreCallingIdentity(ident);
9977        }
9978    }
9979
9980    @Override
9981    public void stopSystemLockTaskMode() throws RemoteException {
9982        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
9983        // This makes inner call to look as if it was initiated by system.
9984        long ident = Binder.clearCallingIdentity();
9985        try {
9986            stopLockTaskMode();
9987        } finally {
9988            Binder.restoreCallingIdentity(ident);
9989        }
9990    }
9991
9992    @Override
9993    public boolean isInLockTaskMode() {
9994        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9995    }
9996
9997    @Override
9998    public int getLockTaskModeState() {
9999        synchronized (this) {
10000            return mStackSupervisor.getLockTaskModeState();
10001        }
10002    }
10003
10004    @Override
10005    public void showLockTaskEscapeMessage(IBinder token) {
10006        synchronized (this) {
10007            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10008            if (r == null) {
10009                return;
10010            }
10011            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10012        }
10013    }
10014
10015    // =========================================================
10016    // CONTENT PROVIDERS
10017    // =========================================================
10018
10019    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10020        List<ProviderInfo> providers = null;
10021        try {
10022            providers = AppGlobals.getPackageManager()
10023                    .queryContentProviders(app.processName, app.uid,
10024                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10025                                    | MATCH_DEBUG_TRIAGED_MISSING)
10026                    .getList();
10027        } catch (RemoteException ex) {
10028        }
10029        if (DEBUG_MU) Slog.v(TAG_MU,
10030                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10031        int userId = app.userId;
10032        if (providers != null) {
10033            int N = providers.size();
10034            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10035            for (int i=0; i<N; i++) {
10036                ProviderInfo cpi =
10037                    (ProviderInfo)providers.get(i);
10038                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10039                        cpi.name, cpi.flags);
10040                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10041                    // This is a singleton provider, but a user besides the
10042                    // default user is asking to initialize a process it runs
10043                    // in...  well, no, it doesn't actually run in this process,
10044                    // it runs in the process of the default user.  Get rid of it.
10045                    providers.remove(i);
10046                    N--;
10047                    i--;
10048                    continue;
10049                }
10050
10051                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10052                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10053                if (cpr == null) {
10054                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10055                    mProviderMap.putProviderByClass(comp, cpr);
10056                }
10057                if (DEBUG_MU) Slog.v(TAG_MU,
10058                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10059                app.pubProviders.put(cpi.name, cpr);
10060                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10061                    // Don't add this if it is a platform component that is marked
10062                    // to run in multiple processes, because this is actually
10063                    // part of the framework so doesn't make sense to track as a
10064                    // separate apk in the process.
10065                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10066                            mProcessStats);
10067                }
10068                notifyPackageUse(cpi.applicationInfo.packageName);
10069            }
10070        }
10071        return providers;
10072    }
10073
10074    /**
10075     * Check if {@link ProcessRecord} has a possible chance at accessing the
10076     * given {@link ProviderInfo}. Final permission checking is always done
10077     * in {@link ContentProvider}.
10078     */
10079    private final String checkContentProviderPermissionLocked(
10080            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10081        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10082        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10083        boolean checkedGrants = false;
10084        if (checkUser) {
10085            // Looking for cross-user grants before enforcing the typical cross-users permissions
10086            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10087            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10088                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10089                    return null;
10090                }
10091                checkedGrants = true;
10092            }
10093            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10094                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10095            if (userId != tmpTargetUserId) {
10096                // When we actually went to determine the final targer user ID, this ended
10097                // up different than our initial check for the authority.  This is because
10098                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10099                // SELF.  So we need to re-check the grants again.
10100                checkedGrants = false;
10101            }
10102        }
10103        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10104                cpi.applicationInfo.uid, cpi.exported)
10105                == PackageManager.PERMISSION_GRANTED) {
10106            return null;
10107        }
10108        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10109                cpi.applicationInfo.uid, cpi.exported)
10110                == PackageManager.PERMISSION_GRANTED) {
10111            return null;
10112        }
10113
10114        PathPermission[] pps = cpi.pathPermissions;
10115        if (pps != null) {
10116            int i = pps.length;
10117            while (i > 0) {
10118                i--;
10119                PathPermission pp = pps[i];
10120                String pprperm = pp.getReadPermission();
10121                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10122                        cpi.applicationInfo.uid, cpi.exported)
10123                        == PackageManager.PERMISSION_GRANTED) {
10124                    return null;
10125                }
10126                String ppwperm = pp.getWritePermission();
10127                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10128                        cpi.applicationInfo.uid, cpi.exported)
10129                        == PackageManager.PERMISSION_GRANTED) {
10130                    return null;
10131                }
10132            }
10133        }
10134        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10135            return null;
10136        }
10137
10138        String msg;
10139        if (!cpi.exported) {
10140            msg = "Permission Denial: opening provider " + cpi.name
10141                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10142                    + ", uid=" + callingUid + ") that is not exported from uid "
10143                    + cpi.applicationInfo.uid;
10144        } else {
10145            msg = "Permission Denial: opening provider " + cpi.name
10146                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10147                    + ", uid=" + callingUid + ") requires "
10148                    + cpi.readPermission + " or " + cpi.writePermission;
10149        }
10150        Slog.w(TAG, msg);
10151        return msg;
10152    }
10153
10154    /**
10155     * Returns if the ContentProvider has granted a uri to callingUid
10156     */
10157    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10158        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10159        if (perms != null) {
10160            for (int i=perms.size()-1; i>=0; i--) {
10161                GrantUri grantUri = perms.keyAt(i);
10162                if (grantUri.sourceUserId == userId || !checkUser) {
10163                    if (matchesProvider(grantUri.uri, cpi)) {
10164                        return true;
10165                    }
10166                }
10167            }
10168        }
10169        return false;
10170    }
10171
10172    /**
10173     * Returns true if the uri authority is one of the authorities specified in the provider.
10174     */
10175    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10176        String uriAuth = uri.getAuthority();
10177        String cpiAuth = cpi.authority;
10178        if (cpiAuth.indexOf(';') == -1) {
10179            return cpiAuth.equals(uriAuth);
10180        }
10181        String[] cpiAuths = cpiAuth.split(";");
10182        int length = cpiAuths.length;
10183        for (int i = 0; i < length; i++) {
10184            if (cpiAuths[i].equals(uriAuth)) return true;
10185        }
10186        return false;
10187    }
10188
10189    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10190            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10191        if (r != null) {
10192            for (int i=0; i<r.conProviders.size(); i++) {
10193                ContentProviderConnection conn = r.conProviders.get(i);
10194                if (conn.provider == cpr) {
10195                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10196                            "Adding provider requested by "
10197                            + r.processName + " from process "
10198                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10199                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10200                    if (stable) {
10201                        conn.stableCount++;
10202                        conn.numStableIncs++;
10203                    } else {
10204                        conn.unstableCount++;
10205                        conn.numUnstableIncs++;
10206                    }
10207                    return conn;
10208                }
10209            }
10210            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10211            if (stable) {
10212                conn.stableCount = 1;
10213                conn.numStableIncs = 1;
10214            } else {
10215                conn.unstableCount = 1;
10216                conn.numUnstableIncs = 1;
10217            }
10218            cpr.connections.add(conn);
10219            r.conProviders.add(conn);
10220            startAssociationLocked(r.uid, r.processName, r.curProcState,
10221                    cpr.uid, cpr.name, cpr.info.processName);
10222            return conn;
10223        }
10224        cpr.addExternalProcessHandleLocked(externalProcessToken);
10225        return null;
10226    }
10227
10228    boolean decProviderCountLocked(ContentProviderConnection conn,
10229            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10230        if (conn != null) {
10231            cpr = conn.provider;
10232            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10233                    "Removing provider requested by "
10234                    + conn.client.processName + " from process "
10235                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10236                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10237            if (stable) {
10238                conn.stableCount--;
10239            } else {
10240                conn.unstableCount--;
10241            }
10242            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10243                cpr.connections.remove(conn);
10244                conn.client.conProviders.remove(conn);
10245                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10246                    // The client is more important than last activity -- note the time this
10247                    // is happening, so we keep the old provider process around a bit as last
10248                    // activity to avoid thrashing it.
10249                    if (cpr.proc != null) {
10250                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10251                    }
10252                }
10253                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10254                return true;
10255            }
10256            return false;
10257        }
10258        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10259        return false;
10260    }
10261
10262    private void checkTime(long startTime, String where) {
10263        long now = SystemClock.elapsedRealtime();
10264        if ((now-startTime) > 1000) {
10265            // If we are taking more than a second, log about it.
10266            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10267        }
10268    }
10269
10270    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10271            String name, IBinder token, boolean stable, int userId) {
10272        ContentProviderRecord cpr;
10273        ContentProviderConnection conn = null;
10274        ProviderInfo cpi = null;
10275
10276        synchronized(this) {
10277            long startTime = SystemClock.elapsedRealtime();
10278
10279            ProcessRecord r = null;
10280            if (caller != null) {
10281                r = getRecordForAppLocked(caller);
10282                if (r == null) {
10283                    throw new SecurityException(
10284                            "Unable to find app for caller " + caller
10285                          + " (pid=" + Binder.getCallingPid()
10286                          + ") when getting content provider " + name);
10287                }
10288            }
10289
10290            boolean checkCrossUser = true;
10291
10292            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10293
10294            // First check if this content provider has been published...
10295            cpr = mProviderMap.getProviderByName(name, userId);
10296            // If that didn't work, check if it exists for user 0 and then
10297            // verify that it's a singleton provider before using it.
10298            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10299                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10300                if (cpr != null) {
10301                    cpi = cpr.info;
10302                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10303                            cpi.name, cpi.flags)
10304                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10305                        userId = UserHandle.USER_SYSTEM;
10306                        checkCrossUser = false;
10307                    } else {
10308                        cpr = null;
10309                        cpi = null;
10310                    }
10311                }
10312            }
10313
10314            boolean providerRunning = cpr != null;
10315            if (providerRunning) {
10316                cpi = cpr.info;
10317                String msg;
10318                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10319                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10320                        != null) {
10321                    throw new SecurityException(msg);
10322                }
10323                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10324
10325                if (r != null && cpr.canRunHere(r)) {
10326                    // This provider has been published or is in the process
10327                    // of being published...  but it is also allowed to run
10328                    // in the caller's process, so don't make a connection
10329                    // and just let the caller instantiate its own instance.
10330                    ContentProviderHolder holder = cpr.newHolder(null);
10331                    // don't give caller the provider object, it needs
10332                    // to make its own.
10333                    holder.provider = null;
10334                    return holder;
10335                }
10336
10337                final long origId = Binder.clearCallingIdentity();
10338
10339                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10340
10341                // In this case the provider instance already exists, so we can
10342                // return it right away.
10343                conn = incProviderCountLocked(r, cpr, token, stable);
10344                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10345                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10346                        // If this is a perceptible app accessing the provider,
10347                        // make sure to count it as being accessed and thus
10348                        // back up on the LRU list.  This is good because
10349                        // content providers are often expensive to start.
10350                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10351                        updateLruProcessLocked(cpr.proc, false, null);
10352                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10353                    }
10354                }
10355
10356                if (cpr.proc != null) {
10357                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10358                    boolean success = updateOomAdjLocked(cpr.proc);
10359                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10360                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10361                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10362                    // NOTE: there is still a race here where a signal could be
10363                    // pending on the process even though we managed to update its
10364                    // adj level.  Not sure what to do about this, but at least
10365                    // the race is now smaller.
10366                    if (!success) {
10367                        // Uh oh...  it looks like the provider's process
10368                        // has been killed on us.  We need to wait for a new
10369                        // process to be started, and make sure its death
10370                        // doesn't kill our process.
10371                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10372                                + " is crashing; detaching " + r);
10373                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10374                        checkTime(startTime, "getContentProviderImpl: before appDied");
10375                        appDiedLocked(cpr.proc);
10376                        checkTime(startTime, "getContentProviderImpl: after appDied");
10377                        if (!lastRef) {
10378                            // This wasn't the last ref our process had on
10379                            // the provider...  we have now been killed, bail.
10380                            return null;
10381                        }
10382                        providerRunning = false;
10383                        conn = null;
10384                    }
10385                }
10386
10387                Binder.restoreCallingIdentity(origId);
10388            }
10389
10390            if (!providerRunning) {
10391                try {
10392                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10393                    cpi = AppGlobals.getPackageManager().
10394                        resolveContentProvider(name,
10395                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10396                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10397                } catch (RemoteException ex) {
10398                }
10399                if (cpi == null) {
10400                    return null;
10401                }
10402                // If the provider is a singleton AND
10403                // (it's a call within the same user || the provider is a
10404                // privileged app)
10405                // Then allow connecting to the singleton provider
10406                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10407                        cpi.name, cpi.flags)
10408                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10409                if (singleton) {
10410                    userId = UserHandle.USER_SYSTEM;
10411                }
10412                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10413                checkTime(startTime, "getContentProviderImpl: got app info for user");
10414
10415                String msg;
10416                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10417                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10418                        != null) {
10419                    throw new SecurityException(msg);
10420                }
10421                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10422
10423                if (!mProcessesReady
10424                        && !cpi.processName.equals("system")) {
10425                    // If this content provider does not run in the system
10426                    // process, and the system is not yet ready to run other
10427                    // processes, then fail fast instead of hanging.
10428                    throw new IllegalArgumentException(
10429                            "Attempt to launch content provider before system ready");
10430                }
10431
10432                // Make sure that the user who owns this provider is running.  If not,
10433                // we don't want to allow it to run.
10434                if (!mUserController.isUserRunningLocked(userId, 0)) {
10435                    Slog.w(TAG, "Unable to launch app "
10436                            + cpi.applicationInfo.packageName + "/"
10437                            + cpi.applicationInfo.uid + " for provider "
10438                            + name + ": user " + userId + " is stopped");
10439                    return null;
10440                }
10441
10442                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10443                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10444                cpr = mProviderMap.getProviderByClass(comp, userId);
10445                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10446                final boolean firstClass = cpr == null;
10447                if (firstClass) {
10448                    final long ident = Binder.clearCallingIdentity();
10449
10450                    // If permissions need a review before any of the app components can run,
10451                    // we return no provider and launch a review activity if the calling app
10452                    // is in the foreground.
10453                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10454                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10455                            return null;
10456                        }
10457                    }
10458
10459                    try {
10460                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10461                        ApplicationInfo ai =
10462                            AppGlobals.getPackageManager().
10463                                getApplicationInfo(
10464                                        cpi.applicationInfo.packageName,
10465                                        STOCK_PM_FLAGS, userId);
10466                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10467                        if (ai == null) {
10468                            Slog.w(TAG, "No package info for content provider "
10469                                    + cpi.name);
10470                            return null;
10471                        }
10472                        ai = getAppInfoForUser(ai, userId);
10473                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10474                    } catch (RemoteException ex) {
10475                        // pm is in same process, this will never happen.
10476                    } finally {
10477                        Binder.restoreCallingIdentity(ident);
10478                    }
10479                }
10480
10481                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10482
10483                if (r != null && cpr.canRunHere(r)) {
10484                    // If this is a multiprocess provider, then just return its
10485                    // info and allow the caller to instantiate it.  Only do
10486                    // this if the provider is the same user as the caller's
10487                    // process, or can run as root (so can be in any process).
10488                    return cpr.newHolder(null);
10489                }
10490
10491                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10492                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10493                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10494
10495                // This is single process, and our app is now connecting to it.
10496                // See if we are already in the process of launching this
10497                // provider.
10498                final int N = mLaunchingProviders.size();
10499                int i;
10500                for (i = 0; i < N; i++) {
10501                    if (mLaunchingProviders.get(i) == cpr) {
10502                        break;
10503                    }
10504                }
10505
10506                // If the provider is not already being launched, then get it
10507                // started.
10508                if (i >= N) {
10509                    final long origId = Binder.clearCallingIdentity();
10510
10511                    try {
10512                        // Content provider is now in use, its package can't be stopped.
10513                        try {
10514                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10515                            AppGlobals.getPackageManager().setPackageStoppedState(
10516                                    cpr.appInfo.packageName, false, userId);
10517                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10518                        } catch (RemoteException e) {
10519                        } catch (IllegalArgumentException e) {
10520                            Slog.w(TAG, "Failed trying to unstop package "
10521                                    + cpr.appInfo.packageName + ": " + e);
10522                        }
10523
10524                        // Use existing process if already started
10525                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10526                        ProcessRecord proc = getProcessRecordLocked(
10527                                cpi.processName, cpr.appInfo.uid, false);
10528                        if (proc != null && proc.thread != null) {
10529                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10530                                    "Installing in existing process " + proc);
10531                            if (!proc.pubProviders.containsKey(cpi.name)) {
10532                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10533                                proc.pubProviders.put(cpi.name, cpr);
10534                                try {
10535                                    proc.thread.scheduleInstallProvider(cpi);
10536                                } catch (RemoteException e) {
10537                                }
10538                            }
10539                        } else {
10540                            checkTime(startTime, "getContentProviderImpl: before start process");
10541                            proc = startProcessLocked(cpi.processName,
10542                                    cpr.appInfo, false, 0, "content provider",
10543                                    new ComponentName(cpi.applicationInfo.packageName,
10544                                            cpi.name), false, false, false);
10545                            checkTime(startTime, "getContentProviderImpl: after start process");
10546                            if (proc == null) {
10547                                Slog.w(TAG, "Unable to launch app "
10548                                        + cpi.applicationInfo.packageName + "/"
10549                                        + cpi.applicationInfo.uid + " for provider "
10550                                        + name + ": process is bad");
10551                                return null;
10552                            }
10553                        }
10554                        cpr.launchingApp = proc;
10555                        mLaunchingProviders.add(cpr);
10556                    } finally {
10557                        Binder.restoreCallingIdentity(origId);
10558                    }
10559                }
10560
10561                checkTime(startTime, "getContentProviderImpl: updating data structures");
10562
10563                // Make sure the provider is published (the same provider class
10564                // may be published under multiple names).
10565                if (firstClass) {
10566                    mProviderMap.putProviderByClass(comp, cpr);
10567                }
10568
10569                mProviderMap.putProviderByName(name, cpr);
10570                conn = incProviderCountLocked(r, cpr, token, stable);
10571                if (conn != null) {
10572                    conn.waiting = true;
10573                }
10574            }
10575            checkTime(startTime, "getContentProviderImpl: done!");
10576        }
10577
10578        // Wait for the provider to be published...
10579        synchronized (cpr) {
10580            while (cpr.provider == null) {
10581                if (cpr.launchingApp == null) {
10582                    Slog.w(TAG, "Unable to launch app "
10583                            + cpi.applicationInfo.packageName + "/"
10584                            + cpi.applicationInfo.uid + " for provider "
10585                            + name + ": launching app became null");
10586                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10587                            UserHandle.getUserId(cpi.applicationInfo.uid),
10588                            cpi.applicationInfo.packageName,
10589                            cpi.applicationInfo.uid, name);
10590                    return null;
10591                }
10592                try {
10593                    if (DEBUG_MU) Slog.v(TAG_MU,
10594                            "Waiting to start provider " + cpr
10595                            + " launchingApp=" + cpr.launchingApp);
10596                    if (conn != null) {
10597                        conn.waiting = true;
10598                    }
10599                    cpr.wait();
10600                } catch (InterruptedException ex) {
10601                } finally {
10602                    if (conn != null) {
10603                        conn.waiting = false;
10604                    }
10605                }
10606            }
10607        }
10608        return cpr != null ? cpr.newHolder(conn) : null;
10609    }
10610
10611    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10612            ProcessRecord r, final int userId) {
10613        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10614                cpi.packageName, userId)) {
10615
10616            final boolean callerForeground = r == null || r.setSchedGroup
10617                    != ProcessList.SCHED_GROUP_BACKGROUND;
10618
10619            // Show a permission review UI only for starting from a foreground app
10620            if (!callerForeground) {
10621                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10622                        + cpi.packageName + " requires a permissions review");
10623                return false;
10624            }
10625
10626            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10627            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10628                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10629            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10630
10631            if (DEBUG_PERMISSIONS_REVIEW) {
10632                Slog.i(TAG, "u" + userId + " Launching permission review "
10633                        + "for package " + cpi.packageName);
10634            }
10635
10636            final UserHandle userHandle = new UserHandle(userId);
10637            mHandler.post(new Runnable() {
10638                @Override
10639                public void run() {
10640                    mContext.startActivityAsUser(intent, userHandle);
10641                }
10642            });
10643
10644            return false;
10645        }
10646
10647        return true;
10648    }
10649
10650    PackageManagerInternal getPackageManagerInternalLocked() {
10651        if (mPackageManagerInt == null) {
10652            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10653        }
10654        return mPackageManagerInt;
10655    }
10656
10657    @Override
10658    public final ContentProviderHolder getContentProvider(
10659            IApplicationThread caller, String name, int userId, boolean stable) {
10660        enforceNotIsolatedCaller("getContentProvider");
10661        if (caller == null) {
10662            String msg = "null IApplicationThread when getting content provider "
10663                    + name;
10664            Slog.w(TAG, msg);
10665            throw new SecurityException(msg);
10666        }
10667        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10668        // with cross-user grant.
10669        return getContentProviderImpl(caller, name, null, stable, userId);
10670    }
10671
10672    public ContentProviderHolder getContentProviderExternal(
10673            String name, int userId, IBinder token) {
10674        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10675            "Do not have permission in call getContentProviderExternal()");
10676        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10677                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10678        return getContentProviderExternalUnchecked(name, token, userId);
10679    }
10680
10681    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10682            IBinder token, int userId) {
10683        return getContentProviderImpl(null, name, token, true, userId);
10684    }
10685
10686    /**
10687     * Drop a content provider from a ProcessRecord's bookkeeping
10688     */
10689    public void removeContentProvider(IBinder connection, boolean stable) {
10690        enforceNotIsolatedCaller("removeContentProvider");
10691        long ident = Binder.clearCallingIdentity();
10692        try {
10693            synchronized (this) {
10694                ContentProviderConnection conn;
10695                try {
10696                    conn = (ContentProviderConnection)connection;
10697                } catch (ClassCastException e) {
10698                    String msg ="removeContentProvider: " + connection
10699                            + " not a ContentProviderConnection";
10700                    Slog.w(TAG, msg);
10701                    throw new IllegalArgumentException(msg);
10702                }
10703                if (conn == null) {
10704                    throw new NullPointerException("connection is null");
10705                }
10706                if (decProviderCountLocked(conn, null, null, stable)) {
10707                    updateOomAdjLocked();
10708                }
10709            }
10710        } finally {
10711            Binder.restoreCallingIdentity(ident);
10712        }
10713    }
10714
10715    public void removeContentProviderExternal(String name, IBinder token) {
10716        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10717            "Do not have permission in call removeContentProviderExternal()");
10718        int userId = UserHandle.getCallingUserId();
10719        long ident = Binder.clearCallingIdentity();
10720        try {
10721            removeContentProviderExternalUnchecked(name, token, userId);
10722        } finally {
10723            Binder.restoreCallingIdentity(ident);
10724        }
10725    }
10726
10727    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10728        synchronized (this) {
10729            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10730            if(cpr == null) {
10731                //remove from mProvidersByClass
10732                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10733                return;
10734            }
10735
10736            //update content provider record entry info
10737            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10738            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10739            if (localCpr.hasExternalProcessHandles()) {
10740                if (localCpr.removeExternalProcessHandleLocked(token)) {
10741                    updateOomAdjLocked();
10742                } else {
10743                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10744                            + " with no external reference for token: "
10745                            + token + ".");
10746                }
10747            } else {
10748                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10749                        + " with no external references.");
10750            }
10751        }
10752    }
10753
10754    public final void publishContentProviders(IApplicationThread caller,
10755            List<ContentProviderHolder> providers) {
10756        if (providers == null) {
10757            return;
10758        }
10759
10760        enforceNotIsolatedCaller("publishContentProviders");
10761        synchronized (this) {
10762            final ProcessRecord r = getRecordForAppLocked(caller);
10763            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10764            if (r == null) {
10765                throw new SecurityException(
10766                        "Unable to find app for caller " + caller
10767                      + " (pid=" + Binder.getCallingPid()
10768                      + ") when publishing content providers");
10769            }
10770
10771            final long origId = Binder.clearCallingIdentity();
10772
10773            final int N = providers.size();
10774            for (int i = 0; i < N; i++) {
10775                ContentProviderHolder src = providers.get(i);
10776                if (src == null || src.info == null || src.provider == null) {
10777                    continue;
10778                }
10779                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10780                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10781                if (dst != null) {
10782                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10783                    mProviderMap.putProviderByClass(comp, dst);
10784                    String names[] = dst.info.authority.split(";");
10785                    for (int j = 0; j < names.length; j++) {
10786                        mProviderMap.putProviderByName(names[j], dst);
10787                    }
10788
10789                    int launchingCount = mLaunchingProviders.size();
10790                    int j;
10791                    boolean wasInLaunchingProviders = false;
10792                    for (j = 0; j < launchingCount; j++) {
10793                        if (mLaunchingProviders.get(j) == dst) {
10794                            mLaunchingProviders.remove(j);
10795                            wasInLaunchingProviders = true;
10796                            j--;
10797                            launchingCount--;
10798                        }
10799                    }
10800                    if (wasInLaunchingProviders) {
10801                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10802                    }
10803                    synchronized (dst) {
10804                        dst.provider = src.provider;
10805                        dst.proc = r;
10806                        dst.notifyAll();
10807                    }
10808                    updateOomAdjLocked(r);
10809                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10810                            src.info.authority);
10811                }
10812            }
10813
10814            Binder.restoreCallingIdentity(origId);
10815        }
10816    }
10817
10818    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10819        ContentProviderConnection conn;
10820        try {
10821            conn = (ContentProviderConnection)connection;
10822        } catch (ClassCastException e) {
10823            String msg ="refContentProvider: " + connection
10824                    + " not a ContentProviderConnection";
10825            Slog.w(TAG, msg);
10826            throw new IllegalArgumentException(msg);
10827        }
10828        if (conn == null) {
10829            throw new NullPointerException("connection is null");
10830        }
10831
10832        synchronized (this) {
10833            if (stable > 0) {
10834                conn.numStableIncs += stable;
10835            }
10836            stable = conn.stableCount + stable;
10837            if (stable < 0) {
10838                throw new IllegalStateException("stableCount < 0: " + stable);
10839            }
10840
10841            if (unstable > 0) {
10842                conn.numUnstableIncs += unstable;
10843            }
10844            unstable = conn.unstableCount + unstable;
10845            if (unstable < 0) {
10846                throw new IllegalStateException("unstableCount < 0: " + unstable);
10847            }
10848
10849            if ((stable+unstable) <= 0) {
10850                throw new IllegalStateException("ref counts can't go to zero here: stable="
10851                        + stable + " unstable=" + unstable);
10852            }
10853            conn.stableCount = stable;
10854            conn.unstableCount = unstable;
10855            return !conn.dead;
10856        }
10857    }
10858
10859    public void unstableProviderDied(IBinder connection) {
10860        ContentProviderConnection conn;
10861        try {
10862            conn = (ContentProviderConnection)connection;
10863        } catch (ClassCastException e) {
10864            String msg ="refContentProvider: " + connection
10865                    + " not a ContentProviderConnection";
10866            Slog.w(TAG, msg);
10867            throw new IllegalArgumentException(msg);
10868        }
10869        if (conn == null) {
10870            throw new NullPointerException("connection is null");
10871        }
10872
10873        // Safely retrieve the content provider associated with the connection.
10874        IContentProvider provider;
10875        synchronized (this) {
10876            provider = conn.provider.provider;
10877        }
10878
10879        if (provider == null) {
10880            // Um, yeah, we're way ahead of you.
10881            return;
10882        }
10883
10884        // Make sure the caller is being honest with us.
10885        if (provider.asBinder().pingBinder()) {
10886            // Er, no, still looks good to us.
10887            synchronized (this) {
10888                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10889                        + " says " + conn + " died, but we don't agree");
10890                return;
10891            }
10892        }
10893
10894        // Well look at that!  It's dead!
10895        synchronized (this) {
10896            if (conn.provider.provider != provider) {
10897                // But something changed...  good enough.
10898                return;
10899            }
10900
10901            ProcessRecord proc = conn.provider.proc;
10902            if (proc == null || proc.thread == null) {
10903                // Seems like the process is already cleaned up.
10904                return;
10905            }
10906
10907            // As far as we're concerned, this is just like receiving a
10908            // death notification...  just a bit prematurely.
10909            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10910                    + ") early provider death");
10911            final long ident = Binder.clearCallingIdentity();
10912            try {
10913                appDiedLocked(proc);
10914            } finally {
10915                Binder.restoreCallingIdentity(ident);
10916            }
10917        }
10918    }
10919
10920    @Override
10921    public void appNotRespondingViaProvider(IBinder connection) {
10922        enforceCallingPermission(
10923                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10924
10925        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10926        if (conn == null) {
10927            Slog.w(TAG, "ContentProviderConnection is null");
10928            return;
10929        }
10930
10931        final ProcessRecord host = conn.provider.proc;
10932        if (host == null) {
10933            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10934            return;
10935        }
10936
10937        mHandler.post(new Runnable() {
10938            @Override
10939            public void run() {
10940                mAppErrors.appNotResponding(host, null, null, false,
10941                        "ContentProvider not responding");
10942            }
10943        });
10944    }
10945
10946    public final void installSystemProviders() {
10947        List<ProviderInfo> providers;
10948        synchronized (this) {
10949            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10950            providers = generateApplicationProvidersLocked(app);
10951            if (providers != null) {
10952                for (int i=providers.size()-1; i>=0; i--) {
10953                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10954                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10955                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10956                                + ": not system .apk");
10957                        providers.remove(i);
10958                    }
10959                }
10960            }
10961        }
10962        if (providers != null) {
10963            mSystemThread.installSystemProviders(providers);
10964        }
10965
10966        mCoreSettingsObserver = new CoreSettingsObserver(this);
10967        mFontScaleSettingObserver = new FontScaleSettingObserver();
10968
10969        //mUsageStatsService.monitorPackages();
10970    }
10971
10972    private void startPersistentApps(int matchFlags) {
10973        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10974
10975        synchronized (this) {
10976            try {
10977                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10978                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10979                for (ApplicationInfo app : apps) {
10980                    if (!"android".equals(app.packageName)) {
10981                        addAppLocked(app, false, null /* ABI override */);
10982                    }
10983                }
10984            } catch (RemoteException ex) {
10985            }
10986        }
10987    }
10988
10989    /**
10990     * When a user is unlocked, we need to install encryption-unaware providers
10991     * belonging to any running apps.
10992     */
10993    private void installEncryptionUnawareProviders(int userId) {
10994        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10995            // TODO: eventually pivot this back to look at current user state,
10996            // similar to the comment in UserManager.isUserUnlocked(), but for
10997            // now, if we started apps when "unlocked" then unaware providers
10998            // have already been spun up.
10999            return;
11000        }
11001
11002        // We're only interested in providers that are encryption unaware, and
11003        // we don't care about uninstalled apps, since there's no way they're
11004        // running at this point.
11005        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11006
11007        synchronized (this) {
11008            final int NP = mProcessNames.getMap().size();
11009            for (int ip = 0; ip < NP; ip++) {
11010                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11011                final int NA = apps.size();
11012                for (int ia = 0; ia < NA; ia++) {
11013                    final ProcessRecord app = apps.valueAt(ia);
11014                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11015
11016                    final int NG = app.pkgList.size();
11017                    for (int ig = 0; ig < NG; ig++) {
11018                        try {
11019                            final String pkgName = app.pkgList.keyAt(ig);
11020                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11021                                    .getPackageInfo(pkgName, matchFlags, userId);
11022                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11023                                for (ProviderInfo provInfo : pkgInfo.providers) {
11024                                    Log.v(TAG, "Installing " + provInfo);
11025                                    app.thread.scheduleInstallProvider(provInfo);
11026                                }
11027                            }
11028                        } catch (RemoteException ignored) {
11029                        }
11030                    }
11031                }
11032            }
11033        }
11034    }
11035
11036    /**
11037     * Allows apps to retrieve the MIME type of a URI.
11038     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11039     * users, then it does not need permission to access the ContentProvider.
11040     * Either, it needs cross-user uri grants.
11041     *
11042     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11043     *
11044     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11045     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11046     */
11047    public String getProviderMimeType(Uri uri, int userId) {
11048        enforceNotIsolatedCaller("getProviderMimeType");
11049        final String name = uri.getAuthority();
11050        int callingUid = Binder.getCallingUid();
11051        int callingPid = Binder.getCallingPid();
11052        long ident = 0;
11053        boolean clearedIdentity = false;
11054        synchronized (this) {
11055            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11056        }
11057        if (canClearIdentity(callingPid, callingUid, userId)) {
11058            clearedIdentity = true;
11059            ident = Binder.clearCallingIdentity();
11060        }
11061        ContentProviderHolder holder = null;
11062        try {
11063            holder = getContentProviderExternalUnchecked(name, null, userId);
11064            if (holder != null) {
11065                return holder.provider.getType(uri);
11066            }
11067        } catch (RemoteException e) {
11068            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11069            return null;
11070        } finally {
11071            // We need to clear the identity to call removeContentProviderExternalUnchecked
11072            if (!clearedIdentity) {
11073                ident = Binder.clearCallingIdentity();
11074            }
11075            try {
11076                if (holder != null) {
11077                    removeContentProviderExternalUnchecked(name, null, userId);
11078                }
11079            } finally {
11080                Binder.restoreCallingIdentity(ident);
11081            }
11082        }
11083
11084        return null;
11085    }
11086
11087    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11088        if (UserHandle.getUserId(callingUid) == userId) {
11089            return true;
11090        }
11091        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11092                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11093                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11094                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11095                return true;
11096        }
11097        return false;
11098    }
11099
11100    // =========================================================
11101    // GLOBAL MANAGEMENT
11102    // =========================================================
11103
11104    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11105            boolean isolated, int isolatedUid) {
11106        String proc = customProcess != null ? customProcess : info.processName;
11107        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11108        final int userId = UserHandle.getUserId(info.uid);
11109        int uid = info.uid;
11110        if (isolated) {
11111            if (isolatedUid == 0) {
11112                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11113                while (true) {
11114                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11115                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11116                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11117                    }
11118                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11119                    mNextIsolatedProcessUid++;
11120                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11121                        // No process for this uid, use it.
11122                        break;
11123                    }
11124                    stepsLeft--;
11125                    if (stepsLeft <= 0) {
11126                        return null;
11127                    }
11128                }
11129            } else {
11130                // Special case for startIsolatedProcess (internal only), where
11131                // the uid of the isolated process is specified by the caller.
11132                uid = isolatedUid;
11133            }
11134        }
11135        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11136        if (!mBooted && !mBooting
11137                && userId == UserHandle.USER_SYSTEM
11138                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11139            r.persistent = true;
11140        }
11141        addProcessNameLocked(r);
11142        return r;
11143    }
11144
11145    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11146            String abiOverride) {
11147        ProcessRecord app;
11148        if (!isolated) {
11149            app = getProcessRecordLocked(info.processName, info.uid, true);
11150        } else {
11151            app = null;
11152        }
11153
11154        if (app == null) {
11155            app = newProcessRecordLocked(info, null, isolated, 0);
11156            updateLruProcessLocked(app, false, null);
11157            updateOomAdjLocked();
11158        }
11159
11160        // This package really, really can not be stopped.
11161        try {
11162            AppGlobals.getPackageManager().setPackageStoppedState(
11163                    info.packageName, false, UserHandle.getUserId(app.uid));
11164        } catch (RemoteException e) {
11165        } catch (IllegalArgumentException e) {
11166            Slog.w(TAG, "Failed trying to unstop package "
11167                    + info.packageName + ": " + e);
11168        }
11169
11170        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11171            app.persistent = true;
11172            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11173        }
11174        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11175            mPersistentStartingProcesses.add(app);
11176            startProcessLocked(app, "added application", app.processName, abiOverride,
11177                    null /* entryPoint */, null /* entryPointArgs */);
11178        }
11179
11180        return app;
11181    }
11182
11183    public void unhandledBack() {
11184        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11185                "unhandledBack()");
11186
11187        synchronized(this) {
11188            final long origId = Binder.clearCallingIdentity();
11189            try {
11190                getFocusedStack().unhandledBackLocked();
11191            } finally {
11192                Binder.restoreCallingIdentity(origId);
11193            }
11194        }
11195    }
11196
11197    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11198        enforceNotIsolatedCaller("openContentUri");
11199        final int userId = UserHandle.getCallingUserId();
11200        String name = uri.getAuthority();
11201        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11202        ParcelFileDescriptor pfd = null;
11203        if (cph != null) {
11204            // We record the binder invoker's uid in thread-local storage before
11205            // going to the content provider to open the file.  Later, in the code
11206            // that handles all permissions checks, we look for this uid and use
11207            // that rather than the Activity Manager's own uid.  The effect is that
11208            // we do the check against the caller's permissions even though it looks
11209            // to the content provider like the Activity Manager itself is making
11210            // the request.
11211            Binder token = new Binder();
11212            sCallerIdentity.set(new Identity(
11213                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11214            try {
11215                pfd = cph.provider.openFile(null, uri, "r", null, token);
11216            } catch (FileNotFoundException e) {
11217                // do nothing; pfd will be returned null
11218            } finally {
11219                // Ensure that whatever happens, we clean up the identity state
11220                sCallerIdentity.remove();
11221                // Ensure we're done with the provider.
11222                removeContentProviderExternalUnchecked(name, null, userId);
11223            }
11224        } else {
11225            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11226        }
11227        return pfd;
11228    }
11229
11230    // Actually is sleeping or shutting down or whatever else in the future
11231    // is an inactive state.
11232    public boolean isSleepingOrShuttingDown() {
11233        return isSleeping() || mShuttingDown;
11234    }
11235
11236    public boolean isSleeping() {
11237        return mSleeping;
11238    }
11239
11240    void onWakefulnessChanged(int wakefulness) {
11241        synchronized(this) {
11242            mWakefulness = wakefulness;
11243            updateSleepIfNeededLocked();
11244        }
11245    }
11246
11247    void finishRunningVoiceLocked() {
11248        if (mRunningVoice != null) {
11249            mRunningVoice = null;
11250            mVoiceWakeLock.release();
11251            updateSleepIfNeededLocked();
11252        }
11253    }
11254
11255    void startTimeTrackingFocusedActivityLocked() {
11256        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11257            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11258        }
11259    }
11260
11261    void updateSleepIfNeededLocked() {
11262        if (mSleeping && !shouldSleepLocked()) {
11263            mSleeping = false;
11264            startTimeTrackingFocusedActivityLocked();
11265            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11266            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11267            updateOomAdjLocked();
11268        } else if (!mSleeping && shouldSleepLocked()) {
11269            mSleeping = true;
11270            if (mCurAppTimeTracker != null) {
11271                mCurAppTimeTracker.stop();
11272            }
11273            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11274            mStackSupervisor.goingToSleepLocked();
11275            updateOomAdjLocked();
11276
11277            // Initialize the wake times of all processes.
11278            checkExcessivePowerUsageLocked(false);
11279            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11280            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11281            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11282        }
11283    }
11284
11285    private boolean shouldSleepLocked() {
11286        // Resume applications while running a voice interactor.
11287        if (mRunningVoice != null) {
11288            return false;
11289        }
11290
11291        // TODO: Transform the lock screen state into a sleep token instead.
11292        switch (mWakefulness) {
11293            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11294            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11295            case PowerManagerInternal.WAKEFULNESS_DOZING:
11296                // Pause applications whenever the lock screen is shown or any sleep
11297                // tokens have been acquired.
11298                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11299            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11300            default:
11301                // If we're asleep then pause applications unconditionally.
11302                return true;
11303        }
11304    }
11305
11306    /** Pokes the task persister. */
11307    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11308        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11309    }
11310
11311    /** Notifies all listeners when the task stack has changed. */
11312    void notifyTaskStackChangedLocked() {
11313        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11314        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11315        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11316        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11317    }
11318
11319    /** Notifies all listeners when an Activity is pinned. */
11320    void notifyActivityPinnedLocked() {
11321        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11322        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11323    }
11324
11325    /**
11326     * Notifies all listeners when an attempt was made to start an an activity that is already
11327     * running in the pinned stack and the activity was not actually started, but the task is
11328     * either brought to the front or a new Intent is delivered to it.
11329     */
11330    void notifyPinnedActivityRestartAttemptLocked() {
11331        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11332        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11333    }
11334
11335    /** Notifies all listeners when the pinned stack animation ends. */
11336    @Override
11337    public void notifyPinnedStackAnimationEnded() {
11338        synchronized (this) {
11339            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11340            mHandler.obtainMessage(
11341                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11342        }
11343    }
11344
11345    @Override
11346    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11347        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11348    }
11349
11350    @Override
11351    public boolean shutdown(int timeout) {
11352        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11353                != PackageManager.PERMISSION_GRANTED) {
11354            throw new SecurityException("Requires permission "
11355                    + android.Manifest.permission.SHUTDOWN);
11356        }
11357
11358        boolean timedout = false;
11359
11360        synchronized(this) {
11361            mShuttingDown = true;
11362            updateEventDispatchingLocked();
11363            timedout = mStackSupervisor.shutdownLocked(timeout);
11364        }
11365
11366        mAppOpsService.shutdown();
11367        if (mUsageStatsService != null) {
11368            mUsageStatsService.prepareShutdown();
11369        }
11370        mBatteryStatsService.shutdown();
11371        synchronized (this) {
11372            mProcessStats.shutdownLocked();
11373            notifyTaskPersisterLocked(null, true);
11374        }
11375
11376        return timedout;
11377    }
11378
11379    public final void activitySlept(IBinder token) {
11380        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11381
11382        final long origId = Binder.clearCallingIdentity();
11383
11384        synchronized (this) {
11385            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11386            if (r != null) {
11387                mStackSupervisor.activitySleptLocked(r);
11388            }
11389        }
11390
11391        Binder.restoreCallingIdentity(origId);
11392    }
11393
11394    private String lockScreenShownToString() {
11395        switch (mLockScreenShown) {
11396            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11397            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11398            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11399            default: return "Unknown=" + mLockScreenShown;
11400        }
11401    }
11402
11403    void logLockScreen(String msg) {
11404        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11405                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11406                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11407                + " mSleeping=" + mSleeping);
11408    }
11409
11410    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11411        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11412        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11413        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11414            boolean wasRunningVoice = mRunningVoice != null;
11415            mRunningVoice = session;
11416            if (!wasRunningVoice) {
11417                mVoiceWakeLock.acquire();
11418                updateSleepIfNeededLocked();
11419            }
11420        }
11421    }
11422
11423    private void updateEventDispatchingLocked() {
11424        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11425    }
11426
11427    public void setLockScreenShown(boolean shown) {
11428        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11429                != PackageManager.PERMISSION_GRANTED) {
11430            throw new SecurityException("Requires permission "
11431                    + android.Manifest.permission.DEVICE_POWER);
11432        }
11433
11434        synchronized(this) {
11435            long ident = Binder.clearCallingIdentity();
11436            try {
11437                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11438                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11439                updateSleepIfNeededLocked();
11440            } finally {
11441                Binder.restoreCallingIdentity(ident);
11442            }
11443        }
11444    }
11445
11446    @Override
11447    public void notifyLockedProfile(@UserIdInt int userId) {
11448        try {
11449            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11450                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11451            }
11452        } catch (RemoteException ex) {
11453            throw new SecurityException("Fail to check is caller a privileged app", ex);
11454        }
11455
11456        synchronized (this) {
11457            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11458                final long ident = Binder.clearCallingIdentity();
11459                try {
11460                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11461                    // Get the focused task before launching launcher.
11462
11463                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11464
11465                        // If there is no device lock, we will show the profile's credential page.
11466                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11467                        if (mFocusedActivity != null) {
11468                            mStackSupervisor.startActivityFromRecentsInner(
11469                                    mFocusedActivity.task.taskId, null);
11470                        }
11471                    } else {
11472                        // Showing launcher to avoid user entering credential twice.
11473                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11474                    }
11475                } finally {
11476                    Binder.restoreCallingIdentity(ident);
11477                }
11478            }
11479        }
11480    }
11481
11482    @Override
11483    public void stopAppSwitches() {
11484        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11485                != PackageManager.PERMISSION_GRANTED) {
11486            throw new SecurityException("viewquires permission "
11487                    + android.Manifest.permission.STOP_APP_SWITCHES);
11488        }
11489
11490        synchronized(this) {
11491            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11492                    + APP_SWITCH_DELAY_TIME;
11493            mDidAppSwitch = false;
11494            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11495            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11496            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11497        }
11498    }
11499
11500    public void resumeAppSwitches() {
11501        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11502                != PackageManager.PERMISSION_GRANTED) {
11503            throw new SecurityException("Requires permission "
11504                    + android.Manifest.permission.STOP_APP_SWITCHES);
11505        }
11506
11507        synchronized(this) {
11508            // Note that we don't execute any pending app switches... we will
11509            // let those wait until either the timeout, or the next start
11510            // activity request.
11511            mAppSwitchesAllowedTime = 0;
11512        }
11513    }
11514
11515    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11516            int callingPid, int callingUid, String name) {
11517        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11518            return true;
11519        }
11520
11521        int perm = checkComponentPermission(
11522                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11523                sourceUid, -1, true);
11524        if (perm == PackageManager.PERMISSION_GRANTED) {
11525            return true;
11526        }
11527
11528        // If the actual IPC caller is different from the logical source, then
11529        // also see if they are allowed to control app switches.
11530        if (callingUid != -1 && callingUid != sourceUid) {
11531            perm = checkComponentPermission(
11532                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11533                    callingUid, -1, true);
11534            if (perm == PackageManager.PERMISSION_GRANTED) {
11535                return true;
11536            }
11537        }
11538
11539        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11540        return false;
11541    }
11542
11543    public void setDebugApp(String packageName, boolean waitForDebugger,
11544            boolean persistent) {
11545        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11546                "setDebugApp()");
11547
11548        long ident = Binder.clearCallingIdentity();
11549        try {
11550            // Note that this is not really thread safe if there are multiple
11551            // callers into it at the same time, but that's not a situation we
11552            // care about.
11553            if (persistent) {
11554                final ContentResolver resolver = mContext.getContentResolver();
11555                Settings.Global.putString(
11556                    resolver, Settings.Global.DEBUG_APP,
11557                    packageName);
11558                Settings.Global.putInt(
11559                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11560                    waitForDebugger ? 1 : 0);
11561            }
11562
11563            synchronized (this) {
11564                if (!persistent) {
11565                    mOrigDebugApp = mDebugApp;
11566                    mOrigWaitForDebugger = mWaitForDebugger;
11567                }
11568                mDebugApp = packageName;
11569                mWaitForDebugger = waitForDebugger;
11570                mDebugTransient = !persistent;
11571                if (packageName != null) {
11572                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11573                            false, UserHandle.USER_ALL, "set debug app");
11574                }
11575            }
11576        } finally {
11577            Binder.restoreCallingIdentity(ident);
11578        }
11579    }
11580
11581    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11582        synchronized (this) {
11583            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11584            if (!isDebuggable) {
11585                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11586                    throw new SecurityException("Process not debuggable: " + app.packageName);
11587                }
11588            }
11589
11590            mTrackAllocationApp = processName;
11591        }
11592    }
11593
11594    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11595        synchronized (this) {
11596            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11597            if (!isDebuggable) {
11598                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11599                    throw new SecurityException("Process not debuggable: " + app.packageName);
11600                }
11601            }
11602            mProfileApp = processName;
11603            mProfileFile = profilerInfo.profileFile;
11604            if (mProfileFd != null) {
11605                try {
11606                    mProfileFd.close();
11607                } catch (IOException e) {
11608                }
11609                mProfileFd = null;
11610            }
11611            mProfileFd = profilerInfo.profileFd;
11612            mSamplingInterval = profilerInfo.samplingInterval;
11613            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11614            mProfileType = 0;
11615        }
11616    }
11617
11618    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11619        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11620        if (!isDebuggable) {
11621            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11622                throw new SecurityException("Process not debuggable: " + app.packageName);
11623            }
11624        }
11625        mNativeDebuggingApp = processName;
11626    }
11627
11628    @Override
11629    public void setAlwaysFinish(boolean enabled) {
11630        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11631                "setAlwaysFinish()");
11632
11633        long ident = Binder.clearCallingIdentity();
11634        try {
11635            Settings.Global.putInt(
11636                    mContext.getContentResolver(),
11637                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11638
11639            synchronized (this) {
11640                mAlwaysFinishActivities = enabled;
11641            }
11642        } finally {
11643            Binder.restoreCallingIdentity(ident);
11644        }
11645    }
11646
11647    @Override
11648    public void setLenientBackgroundCheck(boolean enabled) {
11649        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11650                "setLenientBackgroundCheck()");
11651
11652        long ident = Binder.clearCallingIdentity();
11653        try {
11654            Settings.Global.putInt(
11655                    mContext.getContentResolver(),
11656                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11657
11658            synchronized (this) {
11659                mLenientBackgroundCheck = enabled;
11660            }
11661        } finally {
11662            Binder.restoreCallingIdentity(ident);
11663        }
11664    }
11665
11666    @Override
11667    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11668        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11669                "setActivityController()");
11670        synchronized (this) {
11671            mController = controller;
11672            mControllerIsAMonkey = imAMonkey;
11673            Watchdog.getInstance().setActivityController(controller);
11674        }
11675    }
11676
11677    @Override
11678    public void setUserIsMonkey(boolean userIsMonkey) {
11679        synchronized (this) {
11680            synchronized (mPidsSelfLocked) {
11681                final int callingPid = Binder.getCallingPid();
11682                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11683                if (precessRecord == null) {
11684                    throw new SecurityException("Unknown process: " + callingPid);
11685                }
11686                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11687                    throw new SecurityException("Only an instrumentation process "
11688                            + "with a UiAutomation can call setUserIsMonkey");
11689                }
11690            }
11691            mUserIsMonkey = userIsMonkey;
11692        }
11693    }
11694
11695    @Override
11696    public boolean isUserAMonkey() {
11697        synchronized (this) {
11698            // If there is a controller also implies the user is a monkey.
11699            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11700        }
11701    }
11702
11703    public void requestBugReport(int bugreportType) {
11704        String service = null;
11705        switch (bugreportType) {
11706            case ActivityManager.BUGREPORT_OPTION_FULL:
11707                service = "bugreport";
11708                break;
11709            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11710                service = "bugreportplus";
11711                break;
11712            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11713                service = "bugreportremote";
11714                break;
11715        }
11716        if (service == null) {
11717            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11718                    + bugreportType);
11719        }
11720        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11721        SystemProperties.set("ctl.start", service);
11722    }
11723
11724    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11725        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11726    }
11727
11728    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11729        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11730            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11731        }
11732        return KEY_DISPATCHING_TIMEOUT;
11733    }
11734
11735    @Override
11736    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11737        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11738                != PackageManager.PERMISSION_GRANTED) {
11739            throw new SecurityException("Requires permission "
11740                    + android.Manifest.permission.FILTER_EVENTS);
11741        }
11742        ProcessRecord proc;
11743        long timeout;
11744        synchronized (this) {
11745            synchronized (mPidsSelfLocked) {
11746                proc = mPidsSelfLocked.get(pid);
11747            }
11748            timeout = getInputDispatchingTimeoutLocked(proc);
11749        }
11750
11751        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11752            return -1;
11753        }
11754
11755        return timeout;
11756    }
11757
11758    /**
11759     * Handle input dispatching timeouts.
11760     * Returns whether input dispatching should be aborted or not.
11761     */
11762    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11763            final ActivityRecord activity, final ActivityRecord parent,
11764            final boolean aboveSystem, String reason) {
11765        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11766                != PackageManager.PERMISSION_GRANTED) {
11767            throw new SecurityException("Requires permission "
11768                    + android.Manifest.permission.FILTER_EVENTS);
11769        }
11770
11771        final String annotation;
11772        if (reason == null) {
11773            annotation = "Input dispatching timed out";
11774        } else {
11775            annotation = "Input dispatching timed out (" + reason + ")";
11776        }
11777
11778        if (proc != null) {
11779            synchronized (this) {
11780                if (proc.debugging) {
11781                    return false;
11782                }
11783
11784                if (mDidDexOpt) {
11785                    // Give more time since we were dexopting.
11786                    mDidDexOpt = false;
11787                    return false;
11788                }
11789
11790                if (proc.instrumentationClass != null) {
11791                    Bundle info = new Bundle();
11792                    info.putString("shortMsg", "keyDispatchingTimedOut");
11793                    info.putString("longMsg", annotation);
11794                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11795                    return true;
11796                }
11797            }
11798            mHandler.post(new Runnable() {
11799                @Override
11800                public void run() {
11801                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11802                }
11803            });
11804        }
11805
11806        return true;
11807    }
11808
11809    @Override
11810    public Bundle getAssistContextExtras(int requestType) {
11811        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11812                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11813        if (pae == null) {
11814            return null;
11815        }
11816        synchronized (pae) {
11817            while (!pae.haveResult) {
11818                try {
11819                    pae.wait();
11820                } catch (InterruptedException e) {
11821                }
11822            }
11823        }
11824        synchronized (this) {
11825            buildAssistBundleLocked(pae, pae.result);
11826            mPendingAssistExtras.remove(pae);
11827            mUiHandler.removeCallbacks(pae);
11828        }
11829        return pae.extras;
11830    }
11831
11832    @Override
11833    public boolean isAssistDataAllowedOnCurrentActivity() {
11834        int userId;
11835        synchronized (this) {
11836            userId = mUserController.getCurrentUserIdLocked();
11837            ActivityRecord activity = getFocusedStack().topActivity();
11838            if (activity == null) {
11839                return false;
11840            }
11841            userId = activity.userId;
11842        }
11843        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11844                Context.DEVICE_POLICY_SERVICE);
11845        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11846    }
11847
11848    @Override
11849    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11850        long ident = Binder.clearCallingIdentity();
11851        try {
11852            synchronized (this) {
11853                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11854                ActivityRecord top = getFocusedStack().topActivity();
11855                if (top != caller) {
11856                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11857                            + " is not current top " + top);
11858                    return false;
11859                }
11860                if (!top.nowVisible) {
11861                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11862                            + " is not visible");
11863                    return false;
11864                }
11865            }
11866            AssistUtils utils = new AssistUtils(mContext);
11867            return utils.showSessionForActiveService(args,
11868                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11869        } finally {
11870            Binder.restoreCallingIdentity(ident);
11871        }
11872    }
11873
11874    @Override
11875    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11876            Bundle receiverExtras,
11877            IBinder activityToken, boolean focused) {
11878        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11879                activityToken, focused,
11880                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11881                != null;
11882    }
11883
11884    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11885            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11886            int userHandle, Bundle args, long timeout) {
11887        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11888                "enqueueAssistContext()");
11889        synchronized (this) {
11890            ActivityRecord activity = getFocusedStack().topActivity();
11891            if (activity == null) {
11892                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11893                return null;
11894            }
11895            if (activity.app == null || activity.app.thread == null) {
11896                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11897                return null;
11898            }
11899            if (focused) {
11900                if (activityToken != null) {
11901                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11902                    if (activity != caller) {
11903                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11904                                + " is not current top " + activity);
11905                        return null;
11906                    }
11907                }
11908            } else {
11909                activity = ActivityRecord.forTokenLocked(activityToken);
11910                if (activity == null) {
11911                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11912                            + " couldn't be found");
11913                    return null;
11914                }
11915            }
11916
11917            PendingAssistExtras pae;
11918            Bundle extras = new Bundle();
11919            if (args != null) {
11920                extras.putAll(args);
11921            }
11922            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11923            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11924            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11925                    userHandle);
11926            try {
11927                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11928                        requestType);
11929                mPendingAssistExtras.add(pae);
11930                mUiHandler.postDelayed(pae, timeout);
11931            } catch (RemoteException e) {
11932                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11933                return null;
11934            }
11935            return pae;
11936        }
11937    }
11938
11939    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11940        IResultReceiver receiver;
11941        synchronized (this) {
11942            mPendingAssistExtras.remove(pae);
11943            receiver = pae.receiver;
11944        }
11945        if (receiver != null) {
11946            // Caller wants result sent back to them.
11947            try {
11948                pae.receiver.send(0, null);
11949            } catch (RemoteException e) {
11950            }
11951        }
11952    }
11953
11954    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11955        if (result != null) {
11956            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11957        }
11958        if (pae.hint != null) {
11959            pae.extras.putBoolean(pae.hint, true);
11960        }
11961    }
11962
11963    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11964            AssistContent content, Uri referrer) {
11965        PendingAssistExtras pae = (PendingAssistExtras)token;
11966        synchronized (pae) {
11967            pae.result = extras;
11968            pae.structure = structure;
11969            pae.content = content;
11970            if (referrer != null) {
11971                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11972            }
11973            pae.haveResult = true;
11974            pae.notifyAll();
11975            if (pae.intent == null && pae.receiver == null) {
11976                // Caller is just waiting for the result.
11977                return;
11978            }
11979        }
11980
11981        // We are now ready to launch the assist activity.
11982        IResultReceiver sendReceiver = null;
11983        Bundle sendBundle = null;
11984        synchronized (this) {
11985            buildAssistBundleLocked(pae, extras);
11986            boolean exists = mPendingAssistExtras.remove(pae);
11987            mUiHandler.removeCallbacks(pae);
11988            if (!exists) {
11989                // Timed out.
11990                return;
11991            }
11992            if ((sendReceiver=pae.receiver) != null) {
11993                // Caller wants result sent back to them.
11994                sendBundle = new Bundle();
11995                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
11996                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
11997                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
11998                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
11999                        pae.receiverExtras);
12000            }
12001        }
12002        if (sendReceiver != null) {
12003            try {
12004                sendReceiver.send(0, sendBundle);
12005            } catch (RemoteException e) {
12006            }
12007            return;
12008        }
12009
12010        long ident = Binder.clearCallingIdentity();
12011        try {
12012            pae.intent.replaceExtras(pae.extras);
12013            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12014                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12015                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12016            closeSystemDialogs("assist");
12017            try {
12018                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12019            } catch (ActivityNotFoundException e) {
12020                Slog.w(TAG, "No activity to handle assist action.", e);
12021            }
12022        } finally {
12023            Binder.restoreCallingIdentity(ident);
12024        }
12025    }
12026
12027    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12028            Bundle args) {
12029        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12030                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12031    }
12032
12033    public void registerProcessObserver(IProcessObserver observer) {
12034        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12035                "registerProcessObserver()");
12036        synchronized (this) {
12037            mProcessObservers.register(observer);
12038        }
12039    }
12040
12041    @Override
12042    public void unregisterProcessObserver(IProcessObserver observer) {
12043        synchronized (this) {
12044            mProcessObservers.unregister(observer);
12045        }
12046    }
12047
12048    @Override
12049    public void registerUidObserver(IUidObserver observer, int which) {
12050        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12051                "registerUidObserver()");
12052        synchronized (this) {
12053            mUidObservers.register(observer, which);
12054        }
12055    }
12056
12057    @Override
12058    public void unregisterUidObserver(IUidObserver observer) {
12059        synchronized (this) {
12060            mUidObservers.unregister(observer);
12061        }
12062    }
12063
12064    @Override
12065    public boolean convertFromTranslucent(IBinder token) {
12066        final long origId = Binder.clearCallingIdentity();
12067        try {
12068            synchronized (this) {
12069                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12070                if (r == null) {
12071                    return false;
12072                }
12073                final boolean translucentChanged = r.changeWindowTranslucency(true);
12074                if (translucentChanged) {
12075                    r.task.stack.releaseBackgroundResources(r);
12076                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12077                }
12078                mWindowManager.setAppFullscreen(token, true);
12079                return translucentChanged;
12080            }
12081        } finally {
12082            Binder.restoreCallingIdentity(origId);
12083        }
12084    }
12085
12086    @Override
12087    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12088        final long origId = Binder.clearCallingIdentity();
12089        try {
12090            synchronized (this) {
12091                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12092                if (r == null) {
12093                    return false;
12094                }
12095                int index = r.task.mActivities.lastIndexOf(r);
12096                if (index > 0) {
12097                    ActivityRecord under = r.task.mActivities.get(index - 1);
12098                    under.returningOptions = options;
12099                }
12100                final boolean translucentChanged = r.changeWindowTranslucency(false);
12101                if (translucentChanged) {
12102                    r.task.stack.convertActivityToTranslucent(r);
12103                }
12104                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12105                mWindowManager.setAppFullscreen(token, false);
12106                return translucentChanged;
12107            }
12108        } finally {
12109            Binder.restoreCallingIdentity(origId);
12110        }
12111    }
12112
12113    @Override
12114    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12115        final long origId = Binder.clearCallingIdentity();
12116        try {
12117            synchronized (this) {
12118                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12119                if (r != null) {
12120                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12121                }
12122            }
12123            return false;
12124        } finally {
12125            Binder.restoreCallingIdentity(origId);
12126        }
12127    }
12128
12129    @Override
12130    public boolean isBackgroundVisibleBehind(IBinder token) {
12131        final long origId = Binder.clearCallingIdentity();
12132        try {
12133            synchronized (this) {
12134                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12135                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12136                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12137                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12138                return visible;
12139            }
12140        } finally {
12141            Binder.restoreCallingIdentity(origId);
12142        }
12143    }
12144
12145    @Override
12146    public ActivityOptions getActivityOptions(IBinder token) {
12147        final long origId = Binder.clearCallingIdentity();
12148        try {
12149            synchronized (this) {
12150                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12151                if (r != null) {
12152                    final ActivityOptions activityOptions = r.pendingOptions;
12153                    r.pendingOptions = null;
12154                    return activityOptions;
12155                }
12156                return null;
12157            }
12158        } finally {
12159            Binder.restoreCallingIdentity(origId);
12160        }
12161    }
12162
12163    @Override
12164    public void setImmersive(IBinder token, boolean immersive) {
12165        synchronized(this) {
12166            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12167            if (r == null) {
12168                throw new IllegalArgumentException();
12169            }
12170            r.immersive = immersive;
12171
12172            // update associated state if we're frontmost
12173            if (r == mFocusedActivity) {
12174                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12175                applyUpdateLockStateLocked(r);
12176            }
12177        }
12178    }
12179
12180    @Override
12181    public boolean isImmersive(IBinder token) {
12182        synchronized (this) {
12183            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12184            if (r == null) {
12185                throw new IllegalArgumentException();
12186            }
12187            return r.immersive;
12188        }
12189    }
12190
12191    @Override
12192    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12193        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12194            throw new UnsupportedOperationException("VR mode not supported on this device!");
12195        }
12196
12197        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12198
12199        ActivityRecord r;
12200        synchronized (this) {
12201            r = ActivityRecord.isInStackLocked(token);
12202        }
12203
12204        if (r == null) {
12205            throw new IllegalArgumentException();
12206        }
12207
12208        int err;
12209        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12210                VrManagerInternal.NO_ERROR) {
12211            return err;
12212        }
12213
12214        synchronized(this) {
12215            r.requestedVrComponent = (enabled) ? packageName : null;
12216
12217            // Update associated state if this activity is currently focused
12218            if (r == mFocusedActivity) {
12219                applyUpdateVrModeLocked(r);
12220            }
12221            return 0;
12222        }
12223    }
12224
12225    @Override
12226    public boolean isVrModePackageEnabled(ComponentName packageName) {
12227        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12228            throw new UnsupportedOperationException("VR mode not supported on this device!");
12229        }
12230
12231        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12232
12233        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12234                VrManagerInternal.NO_ERROR;
12235    }
12236
12237    public boolean isTopActivityImmersive() {
12238        enforceNotIsolatedCaller("startActivity");
12239        synchronized (this) {
12240            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12241            return (r != null) ? r.immersive : false;
12242        }
12243    }
12244
12245    @Override
12246    public boolean isTopOfTask(IBinder token) {
12247        synchronized (this) {
12248            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12249            if (r == null) {
12250                throw new IllegalArgumentException();
12251            }
12252            return r.task.getTopActivity() == r;
12253        }
12254    }
12255
12256    public final void enterSafeMode() {
12257        synchronized(this) {
12258            // It only makes sense to do this before the system is ready
12259            // and started launching other packages.
12260            if (!mSystemReady) {
12261                try {
12262                    AppGlobals.getPackageManager().enterSafeMode();
12263                } catch (RemoteException e) {
12264                }
12265            }
12266
12267            mSafeMode = true;
12268        }
12269    }
12270
12271    public final void showSafeModeOverlay() {
12272        View v = LayoutInflater.from(mContext).inflate(
12273                com.android.internal.R.layout.safe_mode, null);
12274        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12275        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12276        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12277        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12278        lp.gravity = Gravity.BOTTOM | Gravity.START;
12279        lp.format = v.getBackground().getOpacity();
12280        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12281                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12282        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12283        ((WindowManager)mContext.getSystemService(
12284                Context.WINDOW_SERVICE)).addView(v, lp);
12285    }
12286
12287    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12288        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12289            return;
12290        }
12291        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12292        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12293        synchronized (stats) {
12294            if (mBatteryStatsService.isOnBattery()) {
12295                mBatteryStatsService.enforceCallingPermission();
12296                int MY_UID = Binder.getCallingUid();
12297                final int uid;
12298                if (sender == null) {
12299                    uid = sourceUid;
12300                } else {
12301                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12302                }
12303                BatteryStatsImpl.Uid.Pkg pkg =
12304                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12305                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12306                pkg.noteWakeupAlarmLocked(tag);
12307            }
12308        }
12309    }
12310
12311    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12312        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12313            return;
12314        }
12315        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12316        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12317        synchronized (stats) {
12318            mBatteryStatsService.enforceCallingPermission();
12319            int MY_UID = Binder.getCallingUid();
12320            final int uid;
12321            if (sender == null) {
12322                uid = sourceUid;
12323            } else {
12324                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12325            }
12326            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12327        }
12328    }
12329
12330    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12331        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12332            return;
12333        }
12334        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12335        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12336        synchronized (stats) {
12337            mBatteryStatsService.enforceCallingPermission();
12338            int MY_UID = Binder.getCallingUid();
12339            final int uid;
12340            if (sender == null) {
12341                uid = sourceUid;
12342            } else {
12343                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12344            }
12345            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12346        }
12347    }
12348
12349    public boolean killPids(int[] pids, String pReason, boolean secure) {
12350        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12351            throw new SecurityException("killPids only available to the system");
12352        }
12353        String reason = (pReason == null) ? "Unknown" : pReason;
12354        // XXX Note: don't acquire main activity lock here, because the window
12355        // manager calls in with its locks held.
12356
12357        boolean killed = false;
12358        synchronized (mPidsSelfLocked) {
12359            int worstType = 0;
12360            for (int i=0; i<pids.length; i++) {
12361                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12362                if (proc != null) {
12363                    int type = proc.setAdj;
12364                    if (type > worstType) {
12365                        worstType = type;
12366                    }
12367                }
12368            }
12369
12370            // If the worst oom_adj is somewhere in the cached proc LRU range,
12371            // then constrain it so we will kill all cached procs.
12372            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12373                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12374                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12375            }
12376
12377            // If this is not a secure call, don't let it kill processes that
12378            // are important.
12379            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12380                worstType = ProcessList.SERVICE_ADJ;
12381            }
12382
12383            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12384            for (int i=0; i<pids.length; i++) {
12385                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12386                if (proc == null) {
12387                    continue;
12388                }
12389                int adj = proc.setAdj;
12390                if (adj >= worstType && !proc.killedByAm) {
12391                    proc.kill(reason, true);
12392                    killed = true;
12393                }
12394            }
12395        }
12396        return killed;
12397    }
12398
12399    @Override
12400    public void killUid(int appId, int userId, String reason) {
12401        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12402        synchronized (this) {
12403            final long identity = Binder.clearCallingIdentity();
12404            try {
12405                killPackageProcessesLocked(null, appId, userId,
12406                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12407                        reason != null ? reason : "kill uid");
12408            } finally {
12409                Binder.restoreCallingIdentity(identity);
12410            }
12411        }
12412    }
12413
12414    @Override
12415    public boolean killProcessesBelowForeground(String reason) {
12416        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12417            throw new SecurityException("killProcessesBelowForeground() only available to system");
12418        }
12419
12420        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12421    }
12422
12423    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12424        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12425            throw new SecurityException("killProcessesBelowAdj() only available to system");
12426        }
12427
12428        boolean killed = false;
12429        synchronized (mPidsSelfLocked) {
12430            final int size = mPidsSelfLocked.size();
12431            for (int i = 0; i < size; i++) {
12432                final int pid = mPidsSelfLocked.keyAt(i);
12433                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12434                if (proc == null) continue;
12435
12436                final int adj = proc.setAdj;
12437                if (adj > belowAdj && !proc.killedByAm) {
12438                    proc.kill(reason, true);
12439                    killed = true;
12440                }
12441            }
12442        }
12443        return killed;
12444    }
12445
12446    @Override
12447    public void hang(final IBinder who, boolean allowRestart) {
12448        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12449                != PackageManager.PERMISSION_GRANTED) {
12450            throw new SecurityException("Requires permission "
12451                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12452        }
12453
12454        final IBinder.DeathRecipient death = new DeathRecipient() {
12455            @Override
12456            public void binderDied() {
12457                synchronized (this) {
12458                    notifyAll();
12459                }
12460            }
12461        };
12462
12463        try {
12464            who.linkToDeath(death, 0);
12465        } catch (RemoteException e) {
12466            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12467            return;
12468        }
12469
12470        synchronized (this) {
12471            Watchdog.getInstance().setAllowRestart(allowRestart);
12472            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12473            synchronized (death) {
12474                while (who.isBinderAlive()) {
12475                    try {
12476                        death.wait();
12477                    } catch (InterruptedException e) {
12478                    }
12479                }
12480            }
12481            Watchdog.getInstance().setAllowRestart(true);
12482        }
12483    }
12484
12485    @Override
12486    public void restart() {
12487        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12488                != PackageManager.PERMISSION_GRANTED) {
12489            throw new SecurityException("Requires permission "
12490                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12491        }
12492
12493        Log.i(TAG, "Sending shutdown broadcast...");
12494
12495        BroadcastReceiver br = new BroadcastReceiver() {
12496            @Override public void onReceive(Context context, Intent intent) {
12497                // Now the broadcast is done, finish up the low-level shutdown.
12498                Log.i(TAG, "Shutting down activity manager...");
12499                shutdown(10000);
12500                Log.i(TAG, "Shutdown complete, restarting!");
12501                Process.killProcess(Process.myPid());
12502                System.exit(10);
12503            }
12504        };
12505
12506        // First send the high-level shut down broadcast.
12507        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12508        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12509        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12510        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12511        mContext.sendOrderedBroadcastAsUser(intent,
12512                UserHandle.ALL, null, br, mHandler, 0, null, null);
12513        */
12514        br.onReceive(mContext, intent);
12515    }
12516
12517    private long getLowRamTimeSinceIdle(long now) {
12518        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12519    }
12520
12521    @Override
12522    public void performIdleMaintenance() {
12523        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12524                != PackageManager.PERMISSION_GRANTED) {
12525            throw new SecurityException("Requires permission "
12526                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12527        }
12528
12529        synchronized (this) {
12530            final long now = SystemClock.uptimeMillis();
12531            final long timeSinceLastIdle = now - mLastIdleTime;
12532            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12533            mLastIdleTime = now;
12534            mLowRamTimeSinceLastIdle = 0;
12535            if (mLowRamStartTime != 0) {
12536                mLowRamStartTime = now;
12537            }
12538
12539            StringBuilder sb = new StringBuilder(128);
12540            sb.append("Idle maintenance over ");
12541            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12542            sb.append(" low RAM for ");
12543            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12544            Slog.i(TAG, sb.toString());
12545
12546            // If at least 1/3 of our time since the last idle period has been spent
12547            // with RAM low, then we want to kill processes.
12548            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12549
12550            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12551                ProcessRecord proc = mLruProcesses.get(i);
12552                if (proc.notCachedSinceIdle) {
12553                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12554                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12555                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12556                        if (doKilling && proc.initialIdlePss != 0
12557                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12558                            sb = new StringBuilder(128);
12559                            sb.append("Kill");
12560                            sb.append(proc.processName);
12561                            sb.append(" in idle maint: pss=");
12562                            sb.append(proc.lastPss);
12563                            sb.append(", swapPss=");
12564                            sb.append(proc.lastSwapPss);
12565                            sb.append(", initialPss=");
12566                            sb.append(proc.initialIdlePss);
12567                            sb.append(", period=");
12568                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12569                            sb.append(", lowRamPeriod=");
12570                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12571                            Slog.wtfQuiet(TAG, sb.toString());
12572                            proc.kill("idle maint (pss " + proc.lastPss
12573                                    + " from " + proc.initialIdlePss + ")", true);
12574                        }
12575                    }
12576                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12577                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12578                    proc.notCachedSinceIdle = true;
12579                    proc.initialIdlePss = 0;
12580                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12581                            mTestPssMode, isSleeping(), now);
12582                }
12583            }
12584
12585            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12586            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12587        }
12588    }
12589
12590    private void retrieveSettings() {
12591        final ContentResolver resolver = mContext.getContentResolver();
12592        final boolean freeformWindowManagement =
12593                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12594                        || Settings.Global.getInt(
12595                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12596        final boolean supportsPictureInPicture =
12597                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12598
12599        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12600        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12601        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12602        final boolean alwaysFinishActivities =
12603                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12604        final boolean lenientBackgroundCheck =
12605                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12606        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12607        final boolean forceResizable = Settings.Global.getInt(
12608                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12609        // Transfer any global setting for forcing RTL layout, into a System Property
12610        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12611
12612        final Configuration configuration = new Configuration();
12613        Settings.System.getConfiguration(resolver, configuration);
12614        if (forceRtl) {
12615            // This will take care of setting the correct layout direction flags
12616            configuration.setLayoutDirection(configuration.locale);
12617        }
12618
12619        synchronized (this) {
12620            mDebugApp = mOrigDebugApp = debugApp;
12621            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12622            mAlwaysFinishActivities = alwaysFinishActivities;
12623            mLenientBackgroundCheck = lenientBackgroundCheck;
12624            mForceResizableActivities = forceResizable;
12625            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12626            if (supportsMultiWindow || forceResizable) {
12627                mSupportsMultiWindow = true;
12628                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12629                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12630            } else {
12631                mSupportsMultiWindow = false;
12632                mSupportsFreeformWindowManagement = false;
12633                mSupportsPictureInPicture = false;
12634            }
12635            // This happens before any activities are started, so we can
12636            // change mConfiguration in-place.
12637            updateConfigurationLocked(configuration, null, true);
12638            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12639                    "Initial config: " + mConfiguration);
12640
12641            // Load resources only after the current configuration has been set.
12642            final Resources res = mContext.getResources();
12643            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12644            mThumbnailWidth = res.getDimensionPixelSize(
12645                    com.android.internal.R.dimen.thumbnail_width);
12646            mThumbnailHeight = res.getDimensionPixelSize(
12647                    com.android.internal.R.dimen.thumbnail_height);
12648            mFullscreenThumbnailScale = res.getFraction(
12649                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12650            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12651                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12652            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12653                    com.android.internal.R.string.config_appsNotReportingCrashes));
12654        }
12655    }
12656
12657    public boolean testIsSystemReady() {
12658        // no need to synchronize(this) just to read & return the value
12659        return mSystemReady;
12660    }
12661
12662    public void systemReady(final Runnable goingCallback) {
12663        synchronized(this) {
12664            if (mSystemReady) {
12665                // If we're done calling all the receivers, run the next "boot phase" passed in
12666                // by the SystemServer
12667                if (goingCallback != null) {
12668                    goingCallback.run();
12669                }
12670                return;
12671            }
12672
12673            mLocalDeviceIdleController
12674                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12675
12676            // Make sure we have the current profile info, since it is needed for security checks.
12677            mUserController.onSystemReady();
12678            mRecentTasks.onSystemReadyLocked();
12679            mAppOpsService.systemReady();
12680            mSystemReady = true;
12681        }
12682
12683        ArrayList<ProcessRecord> procsToKill = null;
12684        synchronized(mPidsSelfLocked) {
12685            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12686                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12687                if (!isAllowedWhileBooting(proc.info)){
12688                    if (procsToKill == null) {
12689                        procsToKill = new ArrayList<ProcessRecord>();
12690                    }
12691                    procsToKill.add(proc);
12692                }
12693            }
12694        }
12695
12696        synchronized(this) {
12697            if (procsToKill != null) {
12698                for (int i=procsToKill.size()-1; i>=0; i--) {
12699                    ProcessRecord proc = procsToKill.get(i);
12700                    Slog.i(TAG, "Removing system update proc: " + proc);
12701                    removeProcessLocked(proc, true, false, "system update done");
12702                }
12703            }
12704
12705            // Now that we have cleaned up any update processes, we
12706            // are ready to start launching real processes and know that
12707            // we won't trample on them any more.
12708            mProcessesReady = true;
12709        }
12710
12711        Slog.i(TAG, "System now ready");
12712        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12713            SystemClock.uptimeMillis());
12714
12715        synchronized(this) {
12716            // Make sure we have no pre-ready processes sitting around.
12717
12718            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12719                ResolveInfo ri = mContext.getPackageManager()
12720                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12721                                STOCK_PM_FLAGS);
12722                CharSequence errorMsg = null;
12723                if (ri != null) {
12724                    ActivityInfo ai = ri.activityInfo;
12725                    ApplicationInfo app = ai.applicationInfo;
12726                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12727                        mTopAction = Intent.ACTION_FACTORY_TEST;
12728                        mTopData = null;
12729                        mTopComponent = new ComponentName(app.packageName,
12730                                ai.name);
12731                    } else {
12732                        errorMsg = mContext.getResources().getText(
12733                                com.android.internal.R.string.factorytest_not_system);
12734                    }
12735                } else {
12736                    errorMsg = mContext.getResources().getText(
12737                            com.android.internal.R.string.factorytest_no_action);
12738                }
12739                if (errorMsg != null) {
12740                    mTopAction = null;
12741                    mTopData = null;
12742                    mTopComponent = null;
12743                    Message msg = Message.obtain();
12744                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12745                    msg.getData().putCharSequence("msg", errorMsg);
12746                    mUiHandler.sendMessage(msg);
12747                }
12748            }
12749        }
12750
12751        retrieveSettings();
12752        final int currentUserId;
12753        synchronized (this) {
12754            currentUserId = mUserController.getCurrentUserIdLocked();
12755            readGrantedUriPermissionsLocked();
12756        }
12757
12758        if (goingCallback != null) goingCallback.run();
12759
12760        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12761                Integer.toString(currentUserId), currentUserId);
12762        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12763                Integer.toString(currentUserId), currentUserId);
12764        mSystemServiceManager.startUser(currentUserId);
12765
12766        synchronized (this) {
12767            // Only start up encryption-aware persistent apps; once user is
12768            // unlocked we'll come back around and start unaware apps
12769            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12770
12771            // Start up initial activity.
12772            mBooting = true;
12773            // Enable home activity for system user, so that the system can always boot
12774            if (UserManager.isSplitSystemUser()) {
12775                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12776                try {
12777                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12778                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12779                            UserHandle.USER_SYSTEM);
12780                } catch (RemoteException e) {
12781                    throw e.rethrowAsRuntimeException();
12782                }
12783            }
12784            startHomeActivityLocked(currentUserId, "systemReady");
12785
12786            try {
12787                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12788                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12789                            + " data partition or your device will be unstable.");
12790                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12791                }
12792            } catch (RemoteException e) {
12793            }
12794
12795            if (!Build.isBuildConsistent()) {
12796                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12797                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12798            }
12799
12800            long ident = Binder.clearCallingIdentity();
12801            try {
12802                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12803                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12804                        | Intent.FLAG_RECEIVER_FOREGROUND);
12805                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12806                broadcastIntentLocked(null, null, intent,
12807                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12808                        null, false, false, MY_PID, Process.SYSTEM_UID,
12809                        currentUserId);
12810                intent = new Intent(Intent.ACTION_USER_STARTING);
12811                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12812                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12813                broadcastIntentLocked(null, null, intent,
12814                        null, new IIntentReceiver.Stub() {
12815                            @Override
12816                            public void performReceive(Intent intent, int resultCode, String data,
12817                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12818                                    throws RemoteException {
12819                            }
12820                        }, 0, null, null,
12821                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12822                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12823            } catch (Throwable t) {
12824                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12825            } finally {
12826                Binder.restoreCallingIdentity(ident);
12827            }
12828            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12829            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12830        }
12831    }
12832
12833    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12834        synchronized (this) {
12835            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12836        }
12837    }
12838
12839    void skipCurrentReceiverLocked(ProcessRecord app) {
12840        for (BroadcastQueue queue : mBroadcastQueues) {
12841            queue.skipCurrentReceiverLocked(app);
12842        }
12843    }
12844
12845    /**
12846     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12847     * The application process will exit immediately after this call returns.
12848     * @param app object of the crashing app, null for the system server
12849     * @param crashInfo describing the exception
12850     */
12851    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12852        ProcessRecord r = findAppProcess(app, "Crash");
12853        final String processName = app == null ? "system_server"
12854                : (r == null ? "unknown" : r.processName);
12855
12856        handleApplicationCrashInner("crash", r, processName, crashInfo);
12857    }
12858
12859    /* Native crash reporting uses this inner version because it needs to be somewhat
12860     * decoupled from the AM-managed cleanup lifecycle
12861     */
12862    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12863            ApplicationErrorReport.CrashInfo crashInfo) {
12864        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12865                UserHandle.getUserId(Binder.getCallingUid()), processName,
12866                r == null ? -1 : r.info.flags,
12867                crashInfo.exceptionClassName,
12868                crashInfo.exceptionMessage,
12869                crashInfo.throwFileName,
12870                crashInfo.throwLineNumber);
12871
12872        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12873
12874        mAppErrors.crashApplication(r, crashInfo);
12875    }
12876
12877    public void handleApplicationStrictModeViolation(
12878            IBinder app,
12879            int violationMask,
12880            StrictMode.ViolationInfo info) {
12881        ProcessRecord r = findAppProcess(app, "StrictMode");
12882        if (r == null) {
12883            return;
12884        }
12885
12886        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12887            Integer stackFingerprint = info.hashCode();
12888            boolean logIt = true;
12889            synchronized (mAlreadyLoggedViolatedStacks) {
12890                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12891                    logIt = false;
12892                    // TODO: sub-sample into EventLog for these, with
12893                    // the info.durationMillis?  Then we'd get
12894                    // the relative pain numbers, without logging all
12895                    // the stack traces repeatedly.  We'd want to do
12896                    // likewise in the client code, which also does
12897                    // dup suppression, before the Binder call.
12898                } else {
12899                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12900                        mAlreadyLoggedViolatedStacks.clear();
12901                    }
12902                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12903                }
12904            }
12905            if (logIt) {
12906                logStrictModeViolationToDropBox(r, info);
12907            }
12908        }
12909
12910        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12911            AppErrorResult result = new AppErrorResult();
12912            synchronized (this) {
12913                final long origId = Binder.clearCallingIdentity();
12914
12915                Message msg = Message.obtain();
12916                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12917                HashMap<String, Object> data = new HashMap<String, Object>();
12918                data.put("result", result);
12919                data.put("app", r);
12920                data.put("violationMask", violationMask);
12921                data.put("info", info);
12922                msg.obj = data;
12923                mUiHandler.sendMessage(msg);
12924
12925                Binder.restoreCallingIdentity(origId);
12926            }
12927            int res = result.get();
12928            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12929        }
12930    }
12931
12932    // Depending on the policy in effect, there could be a bunch of
12933    // these in quick succession so we try to batch these together to
12934    // minimize disk writes, number of dropbox entries, and maximize
12935    // compression, by having more fewer, larger records.
12936    private void logStrictModeViolationToDropBox(
12937            ProcessRecord process,
12938            StrictMode.ViolationInfo info) {
12939        if (info == null) {
12940            return;
12941        }
12942        final boolean isSystemApp = process == null ||
12943                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12944                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12945        final String processName = process == null ? "unknown" : process.processName;
12946        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12947        final DropBoxManager dbox = (DropBoxManager)
12948                mContext.getSystemService(Context.DROPBOX_SERVICE);
12949
12950        // Exit early if the dropbox isn't configured to accept this report type.
12951        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12952
12953        boolean bufferWasEmpty;
12954        boolean needsFlush;
12955        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12956        synchronized (sb) {
12957            bufferWasEmpty = sb.length() == 0;
12958            appendDropBoxProcessHeaders(process, processName, sb);
12959            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12960            sb.append("System-App: ").append(isSystemApp).append("\n");
12961            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12962            if (info.violationNumThisLoop != 0) {
12963                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12964            }
12965            if (info.numAnimationsRunning != 0) {
12966                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12967            }
12968            if (info.broadcastIntentAction != null) {
12969                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12970            }
12971            if (info.durationMillis != -1) {
12972                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12973            }
12974            if (info.numInstances != -1) {
12975                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12976            }
12977            if (info.tags != null) {
12978                for (String tag : info.tags) {
12979                    sb.append("Span-Tag: ").append(tag).append("\n");
12980                }
12981            }
12982            sb.append("\n");
12983            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12984                sb.append(info.crashInfo.stackTrace);
12985                sb.append("\n");
12986            }
12987            if (info.message != null) {
12988                sb.append(info.message);
12989                sb.append("\n");
12990            }
12991
12992            // Only buffer up to ~64k.  Various logging bits truncate
12993            // things at 128k.
12994            needsFlush = (sb.length() > 64 * 1024);
12995        }
12996
12997        // Flush immediately if the buffer's grown too large, or this
12998        // is a non-system app.  Non-system apps are isolated with a
12999        // different tag & policy and not batched.
13000        //
13001        // Batching is useful during internal testing with
13002        // StrictMode settings turned up high.  Without batching,
13003        // thousands of separate files could be created on boot.
13004        if (!isSystemApp || needsFlush) {
13005            new Thread("Error dump: " + dropboxTag) {
13006                @Override
13007                public void run() {
13008                    String report;
13009                    synchronized (sb) {
13010                        report = sb.toString();
13011                        sb.delete(0, sb.length());
13012                        sb.trimToSize();
13013                    }
13014                    if (report.length() != 0) {
13015                        dbox.addText(dropboxTag, report);
13016                    }
13017                }
13018            }.start();
13019            return;
13020        }
13021
13022        // System app batching:
13023        if (!bufferWasEmpty) {
13024            // An existing dropbox-writing thread is outstanding, so
13025            // we don't need to start it up.  The existing thread will
13026            // catch the buffer appends we just did.
13027            return;
13028        }
13029
13030        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13031        // (After this point, we shouldn't access AMS internal data structures.)
13032        new Thread("Error dump: " + dropboxTag) {
13033            @Override
13034            public void run() {
13035                // 5 second sleep to let stacks arrive and be batched together
13036                try {
13037                    Thread.sleep(5000);  // 5 seconds
13038                } catch (InterruptedException e) {}
13039
13040                String errorReport;
13041                synchronized (mStrictModeBuffer) {
13042                    errorReport = mStrictModeBuffer.toString();
13043                    if (errorReport.length() == 0) {
13044                        return;
13045                    }
13046                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13047                    mStrictModeBuffer.trimToSize();
13048                }
13049                dbox.addText(dropboxTag, errorReport);
13050            }
13051        }.start();
13052    }
13053
13054    /**
13055     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13056     * @param app object of the crashing app, null for the system server
13057     * @param tag reported by the caller
13058     * @param system whether this wtf is coming from the system
13059     * @param crashInfo describing the context of the error
13060     * @return true if the process should exit immediately (WTF is fatal)
13061     */
13062    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13063            final ApplicationErrorReport.CrashInfo crashInfo) {
13064        final int callingUid = Binder.getCallingUid();
13065        final int callingPid = Binder.getCallingPid();
13066
13067        if (system) {
13068            // If this is coming from the system, we could very well have low-level
13069            // system locks held, so we want to do this all asynchronously.  And we
13070            // never want this to become fatal, so there is that too.
13071            mHandler.post(new Runnable() {
13072                @Override public void run() {
13073                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13074                }
13075            });
13076            return false;
13077        }
13078
13079        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13080                crashInfo);
13081
13082        if (r != null && r.pid != Process.myPid() &&
13083                Settings.Global.getInt(mContext.getContentResolver(),
13084                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13085            mAppErrors.crashApplication(r, crashInfo);
13086            return true;
13087        } else {
13088            return false;
13089        }
13090    }
13091
13092    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13093            final ApplicationErrorReport.CrashInfo crashInfo) {
13094        final ProcessRecord r = findAppProcess(app, "WTF");
13095        final String processName = app == null ? "system_server"
13096                : (r == null ? "unknown" : r.processName);
13097
13098        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13099                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13100
13101        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13102
13103        return r;
13104    }
13105
13106    /**
13107     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13108     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13109     */
13110    private ProcessRecord findAppProcess(IBinder app, String reason) {
13111        if (app == null) {
13112            return null;
13113        }
13114
13115        synchronized (this) {
13116            final int NP = mProcessNames.getMap().size();
13117            for (int ip=0; ip<NP; ip++) {
13118                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13119                final int NA = apps.size();
13120                for (int ia=0; ia<NA; ia++) {
13121                    ProcessRecord p = apps.valueAt(ia);
13122                    if (p.thread != null && p.thread.asBinder() == app) {
13123                        return p;
13124                    }
13125                }
13126            }
13127
13128            Slog.w(TAG, "Can't find mystery application for " + reason
13129                    + " from pid=" + Binder.getCallingPid()
13130                    + " uid=" + Binder.getCallingUid() + ": " + app);
13131            return null;
13132        }
13133    }
13134
13135    /**
13136     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13137     * to append various headers to the dropbox log text.
13138     */
13139    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13140            StringBuilder sb) {
13141        // Watchdog thread ends up invoking this function (with
13142        // a null ProcessRecord) to add the stack file to dropbox.
13143        // Do not acquire a lock on this (am) in such cases, as it
13144        // could cause a potential deadlock, if and when watchdog
13145        // is invoked due to unavailability of lock on am and it
13146        // would prevent watchdog from killing system_server.
13147        if (process == null) {
13148            sb.append("Process: ").append(processName).append("\n");
13149            return;
13150        }
13151        // Note: ProcessRecord 'process' is guarded by the service
13152        // instance.  (notably process.pkgList, which could otherwise change
13153        // concurrently during execution of this method)
13154        synchronized (this) {
13155            sb.append("Process: ").append(processName).append("\n");
13156            int flags = process.info.flags;
13157            IPackageManager pm = AppGlobals.getPackageManager();
13158            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13159            for (int ip=0; ip<process.pkgList.size(); ip++) {
13160                String pkg = process.pkgList.keyAt(ip);
13161                sb.append("Package: ").append(pkg);
13162                try {
13163                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13164                    if (pi != null) {
13165                        sb.append(" v").append(pi.versionCode);
13166                        if (pi.versionName != null) {
13167                            sb.append(" (").append(pi.versionName).append(")");
13168                        }
13169                    }
13170                } catch (RemoteException e) {
13171                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13172                }
13173                sb.append("\n");
13174            }
13175        }
13176    }
13177
13178    private static String processClass(ProcessRecord process) {
13179        if (process == null || process.pid == MY_PID) {
13180            return "system_server";
13181        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13182            return "system_app";
13183        } else {
13184            return "data_app";
13185        }
13186    }
13187
13188    private volatile long mWtfClusterStart;
13189    private volatile int mWtfClusterCount;
13190
13191    /**
13192     * Write a description of an error (crash, WTF, ANR) to the drop box.
13193     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13194     * @param process which caused the error, null means the system server
13195     * @param activity which triggered the error, null if unknown
13196     * @param parent activity related to the error, null if unknown
13197     * @param subject line related to the error, null if absent
13198     * @param report in long form describing the error, null if absent
13199     * @param logFile to include in the report, null if none
13200     * @param crashInfo giving an application stack trace, null if absent
13201     */
13202    public void addErrorToDropBox(String eventType,
13203            ProcessRecord process, String processName, ActivityRecord activity,
13204            ActivityRecord parent, String subject,
13205            final String report, final File logFile,
13206            final ApplicationErrorReport.CrashInfo crashInfo) {
13207        // NOTE -- this must never acquire the ActivityManagerService lock,
13208        // otherwise the watchdog may be prevented from resetting the system.
13209
13210        final String dropboxTag = processClass(process) + "_" + eventType;
13211        final DropBoxManager dbox = (DropBoxManager)
13212                mContext.getSystemService(Context.DROPBOX_SERVICE);
13213
13214        // Exit early if the dropbox isn't configured to accept this report type.
13215        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13216
13217        // Rate-limit how often we're willing to do the heavy lifting below to
13218        // collect and record logs; currently 5 logs per 10 second period.
13219        final long now = SystemClock.elapsedRealtime();
13220        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13221            mWtfClusterStart = now;
13222            mWtfClusterCount = 1;
13223        } else {
13224            if (mWtfClusterCount++ >= 5) return;
13225        }
13226
13227        final StringBuilder sb = new StringBuilder(1024);
13228        appendDropBoxProcessHeaders(process, processName, sb);
13229        if (process != null) {
13230            sb.append("Foreground: ")
13231                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13232                    .append("\n");
13233        }
13234        if (activity != null) {
13235            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13236        }
13237        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13238            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13239        }
13240        if (parent != null && parent != activity) {
13241            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13242        }
13243        if (subject != null) {
13244            sb.append("Subject: ").append(subject).append("\n");
13245        }
13246        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13247        if (Debug.isDebuggerConnected()) {
13248            sb.append("Debugger: Connected\n");
13249        }
13250        sb.append("\n");
13251
13252        // Do the rest in a worker thread to avoid blocking the caller on I/O
13253        // (After this point, we shouldn't access AMS internal data structures.)
13254        Thread worker = new Thread("Error dump: " + dropboxTag) {
13255            @Override
13256            public void run() {
13257                if (report != null) {
13258                    sb.append(report);
13259                }
13260                if (logFile != null) {
13261                    try {
13262                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13263                                    "\n\n[[TRUNCATED]]"));
13264                    } catch (IOException e) {
13265                        Slog.e(TAG, "Error reading " + logFile, e);
13266                    }
13267                }
13268                if (crashInfo != null && crashInfo.stackTrace != null) {
13269                    sb.append(crashInfo.stackTrace);
13270                }
13271
13272                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13273                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13274                if (lines > 0) {
13275                    sb.append("\n");
13276
13277                    // Merge several logcat streams, and take the last N lines
13278                    InputStreamReader input = null;
13279                    try {
13280                        java.lang.Process logcat = new ProcessBuilder(
13281                                "/system/bin/timeout", "-k", "15s", "10s",
13282                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13283                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13284                                        .redirectErrorStream(true).start();
13285
13286                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13287                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13288                        input = new InputStreamReader(logcat.getInputStream());
13289
13290                        int num;
13291                        char[] buf = new char[8192];
13292                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13293                    } catch (IOException e) {
13294                        Slog.e(TAG, "Error running logcat", e);
13295                    } finally {
13296                        if (input != null) try { input.close(); } catch (IOException e) {}
13297                    }
13298                }
13299
13300                dbox.addText(dropboxTag, sb.toString());
13301            }
13302        };
13303
13304        if (process == null) {
13305            // If process is null, we are being called from some internal code
13306            // and may be about to die -- run this synchronously.
13307            worker.run();
13308        } else {
13309            worker.start();
13310        }
13311    }
13312
13313    @Override
13314    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13315        enforceNotIsolatedCaller("getProcessesInErrorState");
13316        // assume our apps are happy - lazy create the list
13317        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13318
13319        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13320                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13321        int userId = UserHandle.getUserId(Binder.getCallingUid());
13322
13323        synchronized (this) {
13324
13325            // iterate across all processes
13326            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13327                ProcessRecord app = mLruProcesses.get(i);
13328                if (!allUsers && app.userId != userId) {
13329                    continue;
13330                }
13331                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13332                    // This one's in trouble, so we'll generate a report for it
13333                    // crashes are higher priority (in case there's a crash *and* an anr)
13334                    ActivityManager.ProcessErrorStateInfo report = null;
13335                    if (app.crashing) {
13336                        report = app.crashingReport;
13337                    } else if (app.notResponding) {
13338                        report = app.notRespondingReport;
13339                    }
13340
13341                    if (report != null) {
13342                        if (errList == null) {
13343                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13344                        }
13345                        errList.add(report);
13346                    } else {
13347                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13348                                " crashing = " + app.crashing +
13349                                " notResponding = " + app.notResponding);
13350                    }
13351                }
13352            }
13353        }
13354
13355        return errList;
13356    }
13357
13358    static int procStateToImportance(int procState, int memAdj,
13359            ActivityManager.RunningAppProcessInfo currApp) {
13360        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13361        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13362            currApp.lru = memAdj;
13363        } else {
13364            currApp.lru = 0;
13365        }
13366        return imp;
13367    }
13368
13369    private void fillInProcMemInfo(ProcessRecord app,
13370            ActivityManager.RunningAppProcessInfo outInfo) {
13371        outInfo.pid = app.pid;
13372        outInfo.uid = app.info.uid;
13373        if (mHeavyWeightProcess == app) {
13374            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13375        }
13376        if (app.persistent) {
13377            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13378        }
13379        if (app.activities.size() > 0) {
13380            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13381        }
13382        outInfo.lastTrimLevel = app.trimMemoryLevel;
13383        int adj = app.curAdj;
13384        int procState = app.curProcState;
13385        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13386        outInfo.importanceReasonCode = app.adjTypeCode;
13387        outInfo.processState = app.curProcState;
13388    }
13389
13390    @Override
13391    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13392        enforceNotIsolatedCaller("getRunningAppProcesses");
13393
13394        final int callingUid = Binder.getCallingUid();
13395
13396        // Lazy instantiation of list
13397        List<ActivityManager.RunningAppProcessInfo> runList = null;
13398        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13399                callingUid) == PackageManager.PERMISSION_GRANTED;
13400        final int userId = UserHandle.getUserId(callingUid);
13401        final boolean allUids = isGetTasksAllowed(
13402                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13403
13404        synchronized (this) {
13405            // Iterate across all processes
13406            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13407                ProcessRecord app = mLruProcesses.get(i);
13408                if ((!allUsers && app.userId != userId)
13409                        || (!allUids && app.uid != callingUid)) {
13410                    continue;
13411                }
13412                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13413                    // Generate process state info for running application
13414                    ActivityManager.RunningAppProcessInfo currApp =
13415                        new ActivityManager.RunningAppProcessInfo(app.processName,
13416                                app.pid, app.getPackageList());
13417                    fillInProcMemInfo(app, currApp);
13418                    if (app.adjSource instanceof ProcessRecord) {
13419                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13420                        currApp.importanceReasonImportance =
13421                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13422                                        app.adjSourceProcState);
13423                    } else if (app.adjSource instanceof ActivityRecord) {
13424                        ActivityRecord r = (ActivityRecord)app.adjSource;
13425                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13426                    }
13427                    if (app.adjTarget instanceof ComponentName) {
13428                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13429                    }
13430                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13431                    //        + " lru=" + currApp.lru);
13432                    if (runList == null) {
13433                        runList = new ArrayList<>();
13434                    }
13435                    runList.add(currApp);
13436                }
13437            }
13438        }
13439        return runList;
13440    }
13441
13442    @Override
13443    public List<ApplicationInfo> getRunningExternalApplications() {
13444        enforceNotIsolatedCaller("getRunningExternalApplications");
13445        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13446        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13447        if (runningApps != null && runningApps.size() > 0) {
13448            Set<String> extList = new HashSet<String>();
13449            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13450                if (app.pkgList != null) {
13451                    for (String pkg : app.pkgList) {
13452                        extList.add(pkg);
13453                    }
13454                }
13455            }
13456            IPackageManager pm = AppGlobals.getPackageManager();
13457            for (String pkg : extList) {
13458                try {
13459                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13460                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13461                        retList.add(info);
13462                    }
13463                } catch (RemoteException e) {
13464                }
13465            }
13466        }
13467        return retList;
13468    }
13469
13470    @Override
13471    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13472        enforceNotIsolatedCaller("getMyMemoryState");
13473        synchronized (this) {
13474            ProcessRecord proc;
13475            synchronized (mPidsSelfLocked) {
13476                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13477            }
13478            fillInProcMemInfo(proc, outInfo);
13479        }
13480    }
13481
13482    @Override
13483    public int getMemoryTrimLevel() {
13484        enforceNotIsolatedCaller("getMyMemoryState");
13485        synchronized (this) {
13486            return mLastMemoryLevel;
13487        }
13488    }
13489
13490    @Override
13491    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13492            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13493        (new ActivityManagerShellCommand(this, false)).exec(
13494                this, in, out, err, args, resultReceiver);
13495    }
13496
13497    @Override
13498    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13499        if (checkCallingPermission(android.Manifest.permission.DUMP)
13500                != PackageManager.PERMISSION_GRANTED) {
13501            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13502                    + Binder.getCallingPid()
13503                    + ", uid=" + Binder.getCallingUid()
13504                    + " without permission "
13505                    + android.Manifest.permission.DUMP);
13506            return;
13507        }
13508
13509        boolean dumpAll = false;
13510        boolean dumpClient = false;
13511        String dumpPackage = null;
13512
13513        int opti = 0;
13514        while (opti < args.length) {
13515            String opt = args[opti];
13516            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13517                break;
13518            }
13519            opti++;
13520            if ("-a".equals(opt)) {
13521                dumpAll = true;
13522            } else if ("-c".equals(opt)) {
13523                dumpClient = true;
13524            } else if ("-p".equals(opt)) {
13525                if (opti < args.length) {
13526                    dumpPackage = args[opti];
13527                    opti++;
13528                } else {
13529                    pw.println("Error: -p option requires package argument");
13530                    return;
13531                }
13532                dumpClient = true;
13533            } else if ("-h".equals(opt)) {
13534                ActivityManagerShellCommand.dumpHelp(pw, true);
13535                return;
13536            } else {
13537                pw.println("Unknown argument: " + opt + "; use -h for help");
13538            }
13539        }
13540
13541        long origId = Binder.clearCallingIdentity();
13542        boolean more = false;
13543        // Is the caller requesting to dump a particular piece of data?
13544        if (opti < args.length) {
13545            String cmd = args[opti];
13546            opti++;
13547            if ("activities".equals(cmd) || "a".equals(cmd)) {
13548                synchronized (this) {
13549                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13550                }
13551            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13552                synchronized (this) {
13553                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13554                }
13555            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13556                String[] newArgs;
13557                String name;
13558                if (opti >= args.length) {
13559                    name = null;
13560                    newArgs = EMPTY_STRING_ARRAY;
13561                } else {
13562                    dumpPackage = args[opti];
13563                    opti++;
13564                    newArgs = new String[args.length - opti];
13565                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13566                            args.length - opti);
13567                }
13568                synchronized (this) {
13569                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13570                }
13571            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13572                String[] newArgs;
13573                String name;
13574                if (opti >= args.length) {
13575                    name = null;
13576                    newArgs = EMPTY_STRING_ARRAY;
13577                } else {
13578                    dumpPackage = args[opti];
13579                    opti++;
13580                    newArgs = new String[args.length - opti];
13581                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13582                            args.length - opti);
13583                }
13584                synchronized (this) {
13585                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13586                }
13587            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13588                String[] newArgs;
13589                String name;
13590                if (opti >= args.length) {
13591                    name = null;
13592                    newArgs = EMPTY_STRING_ARRAY;
13593                } else {
13594                    dumpPackage = args[opti];
13595                    opti++;
13596                    newArgs = new String[args.length - opti];
13597                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13598                            args.length - opti);
13599                }
13600                synchronized (this) {
13601                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13602                }
13603            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13604                synchronized (this) {
13605                    dumpOomLocked(fd, pw, args, opti, true);
13606                }
13607            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13608                synchronized (this) {
13609                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13610                }
13611            } else if ("provider".equals(cmd)) {
13612                String[] newArgs;
13613                String name;
13614                if (opti >= args.length) {
13615                    name = null;
13616                    newArgs = EMPTY_STRING_ARRAY;
13617                } else {
13618                    name = args[opti];
13619                    opti++;
13620                    newArgs = new String[args.length - opti];
13621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13622                }
13623                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13624                    pw.println("No providers match: " + name);
13625                    pw.println("Use -h for help.");
13626                }
13627            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13628                synchronized (this) {
13629                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13630                }
13631            } else if ("service".equals(cmd)) {
13632                String[] newArgs;
13633                String name;
13634                if (opti >= args.length) {
13635                    name = null;
13636                    newArgs = EMPTY_STRING_ARRAY;
13637                } else {
13638                    name = args[opti];
13639                    opti++;
13640                    newArgs = new String[args.length - opti];
13641                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13642                            args.length - opti);
13643                }
13644                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13645                    pw.println("No services match: " + name);
13646                    pw.println("Use -h for help.");
13647                }
13648            } else if ("package".equals(cmd)) {
13649                String[] newArgs;
13650                if (opti >= args.length) {
13651                    pw.println("package: no package name specified");
13652                    pw.println("Use -h for help.");
13653                } else {
13654                    dumpPackage = args[opti];
13655                    opti++;
13656                    newArgs = new String[args.length - opti];
13657                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13658                            args.length - opti);
13659                    args = newArgs;
13660                    opti = 0;
13661                    more = true;
13662                }
13663            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13664                synchronized (this) {
13665                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13666                }
13667            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13668                synchronized (this) {
13669                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13670                }
13671            } else if ("locks".equals(cmd)) {
13672                LockGuard.dump(fd, pw, args);
13673            } else {
13674                // Dumping a single activity?
13675                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13676                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13677                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13678                    if (res < 0) {
13679                        pw.println("Bad activity command, or no activities match: " + cmd);
13680                        pw.println("Use -h for help.");
13681                    }
13682                }
13683            }
13684            if (!more) {
13685                Binder.restoreCallingIdentity(origId);
13686                return;
13687            }
13688        }
13689
13690        // No piece of data specified, dump everything.
13691        synchronized (this) {
13692            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13693            pw.println();
13694            if (dumpAll) {
13695                pw.println("-------------------------------------------------------------------------------");
13696            }
13697            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13698            pw.println();
13699            if (dumpAll) {
13700                pw.println("-------------------------------------------------------------------------------");
13701            }
13702            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13703            pw.println();
13704            if (dumpAll) {
13705                pw.println("-------------------------------------------------------------------------------");
13706            }
13707            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13708            pw.println();
13709            if (dumpAll) {
13710                pw.println("-------------------------------------------------------------------------------");
13711            }
13712            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13713            pw.println();
13714            if (dumpAll) {
13715                pw.println("-------------------------------------------------------------------------------");
13716            }
13717            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13718            pw.println();
13719            if (dumpAll) {
13720                pw.println("-------------------------------------------------------------------------------");
13721            }
13722            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13723            if (mAssociations.size() > 0) {
13724                pw.println();
13725                if (dumpAll) {
13726                    pw.println("-------------------------------------------------------------------------------");
13727                }
13728                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13729            }
13730            pw.println();
13731            if (dumpAll) {
13732                pw.println("-------------------------------------------------------------------------------");
13733            }
13734            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13735        }
13736        Binder.restoreCallingIdentity(origId);
13737    }
13738
13739    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13740            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13741        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13742
13743        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13744                dumpPackage);
13745        boolean needSep = printedAnything;
13746
13747        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13748                dumpPackage, needSep, "  mFocusedActivity: ");
13749        if (printed) {
13750            printedAnything = true;
13751            needSep = false;
13752        }
13753
13754        if (dumpPackage == null) {
13755            if (needSep) {
13756                pw.println();
13757            }
13758            needSep = true;
13759            printedAnything = true;
13760            mStackSupervisor.dump(pw, "  ");
13761        }
13762
13763        if (!printedAnything) {
13764            pw.println("  (nothing)");
13765        }
13766    }
13767
13768    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13769            int opti, boolean dumpAll, String dumpPackage) {
13770        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13771
13772        boolean printedAnything = false;
13773
13774        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13775            boolean printedHeader = false;
13776
13777            final int N = mRecentTasks.size();
13778            for (int i=0; i<N; i++) {
13779                TaskRecord tr = mRecentTasks.get(i);
13780                if (dumpPackage != null) {
13781                    if (tr.realActivity == null ||
13782                            !dumpPackage.equals(tr.realActivity)) {
13783                        continue;
13784                    }
13785                }
13786                if (!printedHeader) {
13787                    pw.println("  Recent tasks:");
13788                    printedHeader = true;
13789                    printedAnything = true;
13790                }
13791                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13792                        pw.println(tr);
13793                if (dumpAll) {
13794                    mRecentTasks.get(i).dump(pw, "    ");
13795                }
13796            }
13797        }
13798
13799        if (!printedAnything) {
13800            pw.println("  (nothing)");
13801        }
13802    }
13803
13804    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13805            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13806        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13807
13808        int dumpUid = 0;
13809        if (dumpPackage != null) {
13810            IPackageManager pm = AppGlobals.getPackageManager();
13811            try {
13812                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13813            } catch (RemoteException e) {
13814            }
13815        }
13816
13817        boolean printedAnything = false;
13818
13819        final long now = SystemClock.uptimeMillis();
13820
13821        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13822            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13823                    = mAssociations.valueAt(i1);
13824            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13825                SparseArray<ArrayMap<String, Association>> sourceUids
13826                        = targetComponents.valueAt(i2);
13827                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13828                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13829                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13830                        Association ass = sourceProcesses.valueAt(i4);
13831                        if (dumpPackage != null) {
13832                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13833                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13834                                continue;
13835                            }
13836                        }
13837                        printedAnything = true;
13838                        pw.print("  ");
13839                        pw.print(ass.mTargetProcess);
13840                        pw.print("/");
13841                        UserHandle.formatUid(pw, ass.mTargetUid);
13842                        pw.print(" <- ");
13843                        pw.print(ass.mSourceProcess);
13844                        pw.print("/");
13845                        UserHandle.formatUid(pw, ass.mSourceUid);
13846                        pw.println();
13847                        pw.print("    via ");
13848                        pw.print(ass.mTargetComponent.flattenToShortString());
13849                        pw.println();
13850                        pw.print("    ");
13851                        long dur = ass.mTime;
13852                        if (ass.mNesting > 0) {
13853                            dur += now - ass.mStartTime;
13854                        }
13855                        TimeUtils.formatDuration(dur, pw);
13856                        pw.print(" (");
13857                        pw.print(ass.mCount);
13858                        pw.print(" times)");
13859                        pw.print("  ");
13860                        for (int i=0; i<ass.mStateTimes.length; i++) {
13861                            long amt = ass.mStateTimes[i];
13862                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13863                                amt += now - ass.mLastStateUptime;
13864                            }
13865                            if (amt != 0) {
13866                                pw.print(" ");
13867                                pw.print(ProcessList.makeProcStateString(
13868                                            i + ActivityManager.MIN_PROCESS_STATE));
13869                                pw.print("=");
13870                                TimeUtils.formatDuration(amt, pw);
13871                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13872                                    pw.print("*");
13873                                }
13874                            }
13875                        }
13876                        pw.println();
13877                        if (ass.mNesting > 0) {
13878                            pw.print("    Currently active: ");
13879                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13880                            pw.println();
13881                        }
13882                    }
13883                }
13884            }
13885
13886        }
13887
13888        if (!printedAnything) {
13889            pw.println("  (nothing)");
13890        }
13891    }
13892
13893    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13894            String header, boolean needSep) {
13895        boolean printed = false;
13896        int whichAppId = -1;
13897        if (dumpPackage != null) {
13898            try {
13899                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13900                        dumpPackage, 0);
13901                whichAppId = UserHandle.getAppId(info.uid);
13902            } catch (NameNotFoundException e) {
13903                e.printStackTrace();
13904            }
13905        }
13906        for (int i=0; i<uids.size(); i++) {
13907            UidRecord uidRec = uids.valueAt(i);
13908            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13909                continue;
13910            }
13911            if (!printed) {
13912                printed = true;
13913                if (needSep) {
13914                    pw.println();
13915                }
13916                pw.print("  ");
13917                pw.println(header);
13918                needSep = true;
13919            }
13920            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13921            pw.print(": "); pw.println(uidRec);
13922        }
13923        return printed;
13924    }
13925
13926    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13927            int opti, boolean dumpAll, String dumpPackage) {
13928        boolean needSep = false;
13929        boolean printedAnything = false;
13930        int numPers = 0;
13931
13932        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13933
13934        if (dumpAll) {
13935            final int NP = mProcessNames.getMap().size();
13936            for (int ip=0; ip<NP; ip++) {
13937                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13938                final int NA = procs.size();
13939                for (int ia=0; ia<NA; ia++) {
13940                    ProcessRecord r = procs.valueAt(ia);
13941                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13942                        continue;
13943                    }
13944                    if (!needSep) {
13945                        pw.println("  All known processes:");
13946                        needSep = true;
13947                        printedAnything = true;
13948                    }
13949                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13950                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13951                        pw.print(" "); pw.println(r);
13952                    r.dump(pw, "    ");
13953                    if (r.persistent) {
13954                        numPers++;
13955                    }
13956                }
13957            }
13958        }
13959
13960        if (mIsolatedProcesses.size() > 0) {
13961            boolean printed = false;
13962            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13963                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13964                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13965                    continue;
13966                }
13967                if (!printed) {
13968                    if (needSep) {
13969                        pw.println();
13970                    }
13971                    pw.println("  Isolated process list (sorted by uid):");
13972                    printedAnything = true;
13973                    printed = true;
13974                    needSep = true;
13975                }
13976                pw.println(String.format("%sIsolated #%2d: %s",
13977                        "    ", i, r.toString()));
13978            }
13979        }
13980
13981        if (mActiveUids.size() > 0) {
13982            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13983                printedAnything = needSep = true;
13984            }
13985        }
13986        if (mValidateUids.size() > 0) {
13987            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13988                printedAnything = needSep = true;
13989            }
13990        }
13991
13992        if (mLruProcesses.size() > 0) {
13993            if (needSep) {
13994                pw.println();
13995            }
13996            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13997                    pw.print(" total, non-act at ");
13998                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13999                    pw.print(", non-svc at ");
14000                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14001                    pw.println("):");
14002            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14003            needSep = true;
14004            printedAnything = true;
14005        }
14006
14007        if (dumpAll || dumpPackage != null) {
14008            synchronized (mPidsSelfLocked) {
14009                boolean printed = false;
14010                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14011                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14012                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14013                        continue;
14014                    }
14015                    if (!printed) {
14016                        if (needSep) pw.println();
14017                        needSep = true;
14018                        pw.println("  PID mappings:");
14019                        printed = true;
14020                        printedAnything = true;
14021                    }
14022                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14023                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14024                }
14025            }
14026        }
14027
14028        if (mForegroundProcesses.size() > 0) {
14029            synchronized (mPidsSelfLocked) {
14030                boolean printed = false;
14031                for (int i=0; i<mForegroundProcesses.size(); i++) {
14032                    ProcessRecord r = mPidsSelfLocked.get(
14033                            mForegroundProcesses.valueAt(i).pid);
14034                    if (dumpPackage != null && (r == null
14035                            || !r.pkgList.containsKey(dumpPackage))) {
14036                        continue;
14037                    }
14038                    if (!printed) {
14039                        if (needSep) pw.println();
14040                        needSep = true;
14041                        pw.println("  Foreground Processes:");
14042                        printed = true;
14043                        printedAnything = true;
14044                    }
14045                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14046                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14047                }
14048            }
14049        }
14050
14051        if (mPersistentStartingProcesses.size() > 0) {
14052            if (needSep) pw.println();
14053            needSep = true;
14054            printedAnything = true;
14055            pw.println("  Persisent processes that are starting:");
14056            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14057                    "Starting Norm", "Restarting PERS", dumpPackage);
14058        }
14059
14060        if (mRemovedProcesses.size() > 0) {
14061            if (needSep) pw.println();
14062            needSep = true;
14063            printedAnything = true;
14064            pw.println("  Processes that are being removed:");
14065            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14066                    "Removed Norm", "Removed PERS", dumpPackage);
14067        }
14068
14069        if (mProcessesOnHold.size() > 0) {
14070            if (needSep) pw.println();
14071            needSep = true;
14072            printedAnything = true;
14073            pw.println("  Processes that are on old until the system is ready:");
14074            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14075                    "OnHold Norm", "OnHold PERS", dumpPackage);
14076        }
14077
14078        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14079
14080        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14081        if (needSep) {
14082            printedAnything = true;
14083        }
14084
14085        if (dumpPackage == null) {
14086            pw.println();
14087            needSep = false;
14088            mUserController.dump(pw, dumpAll);
14089        }
14090        if (mHomeProcess != null && (dumpPackage == null
14091                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14092            if (needSep) {
14093                pw.println();
14094                needSep = false;
14095            }
14096            pw.println("  mHomeProcess: " + mHomeProcess);
14097        }
14098        if (mPreviousProcess != null && (dumpPackage == null
14099                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14100            if (needSep) {
14101                pw.println();
14102                needSep = false;
14103            }
14104            pw.println("  mPreviousProcess: " + mPreviousProcess);
14105        }
14106        if (dumpAll) {
14107            StringBuilder sb = new StringBuilder(128);
14108            sb.append("  mPreviousProcessVisibleTime: ");
14109            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14110            pw.println(sb);
14111        }
14112        if (mHeavyWeightProcess != null && (dumpPackage == null
14113                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14114            if (needSep) {
14115                pw.println();
14116                needSep = false;
14117            }
14118            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14119        }
14120        if (dumpPackage == null) {
14121            pw.println("  mConfiguration: " + mConfiguration);
14122        }
14123        if (dumpAll) {
14124            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14125            if (mCompatModePackages.getPackages().size() > 0) {
14126                boolean printed = false;
14127                for (Map.Entry<String, Integer> entry
14128                        : mCompatModePackages.getPackages().entrySet()) {
14129                    String pkg = entry.getKey();
14130                    int mode = entry.getValue();
14131                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14132                        continue;
14133                    }
14134                    if (!printed) {
14135                        pw.println("  mScreenCompatPackages:");
14136                        printed = true;
14137                    }
14138                    pw.print("    "); pw.print(pkg); pw.print(": ");
14139                            pw.print(mode); pw.println();
14140                }
14141            }
14142        }
14143        if (dumpPackage == null) {
14144            pw.println("  mWakefulness="
14145                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14146            pw.println("  mSleepTokens=" + mSleepTokens);
14147            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14148                    + lockScreenShownToString());
14149            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14150            if (mRunningVoice != null) {
14151                pw.println("  mRunningVoice=" + mRunningVoice);
14152                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14153            }
14154        }
14155        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14156                || mOrigWaitForDebugger) {
14157            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14158                    || dumpPackage.equals(mOrigDebugApp)) {
14159                if (needSep) {
14160                    pw.println();
14161                    needSep = false;
14162                }
14163                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14164                        + " mDebugTransient=" + mDebugTransient
14165                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14166            }
14167        }
14168        if (mCurAppTimeTracker != null) {
14169            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14170        }
14171        if (mMemWatchProcesses.getMap().size() > 0) {
14172            pw.println("  Mem watch processes:");
14173            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14174                    = mMemWatchProcesses.getMap();
14175            for (int i=0; i<procs.size(); i++) {
14176                final String proc = procs.keyAt(i);
14177                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14178                for (int j=0; j<uids.size(); j++) {
14179                    if (needSep) {
14180                        pw.println();
14181                        needSep = false;
14182                    }
14183                    StringBuilder sb = new StringBuilder();
14184                    sb.append("    ").append(proc).append('/');
14185                    UserHandle.formatUid(sb, uids.keyAt(j));
14186                    Pair<Long, String> val = uids.valueAt(j);
14187                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14188                    if (val.second != null) {
14189                        sb.append(", report to ").append(val.second);
14190                    }
14191                    pw.println(sb.toString());
14192                }
14193            }
14194            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14195            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14196            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14197                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14198        }
14199        if (mTrackAllocationApp != null) {
14200            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14201                if (needSep) {
14202                    pw.println();
14203                    needSep = false;
14204                }
14205                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14206            }
14207        }
14208        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14209                || mProfileFd != null) {
14210            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14211                if (needSep) {
14212                    pw.println();
14213                    needSep = false;
14214                }
14215                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14216                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14217                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14218                        + mAutoStopProfiler);
14219                pw.println("  mProfileType=" + mProfileType);
14220            }
14221        }
14222        if (mNativeDebuggingApp != null) {
14223            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14224                if (needSep) {
14225                    pw.println();
14226                    needSep = false;
14227                }
14228                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14229            }
14230        }
14231        if (dumpPackage == null) {
14232            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14233                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14234                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14235            }
14236            if (mController != null) {
14237                pw.println("  mController=" + mController
14238                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14239            }
14240            if (dumpAll) {
14241                pw.println("  Total persistent processes: " + numPers);
14242                pw.println("  mProcessesReady=" + mProcessesReady
14243                        + " mSystemReady=" + mSystemReady
14244                        + " mBooted=" + mBooted
14245                        + " mFactoryTest=" + mFactoryTest);
14246                pw.println("  mBooting=" + mBooting
14247                        + " mCallFinishBooting=" + mCallFinishBooting
14248                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14249                pw.print("  mLastPowerCheckRealtime=");
14250                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14251                        pw.println("");
14252                pw.print("  mLastPowerCheckUptime=");
14253                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14254                        pw.println("");
14255                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14256                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14257                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14258                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14259                        + " (" + mLruProcesses.size() + " total)"
14260                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14261                        + " mNumServiceProcs=" + mNumServiceProcs
14262                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14263                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14264                        + " mLastMemoryLevel" + mLastMemoryLevel
14265                        + " mLastNumProcesses" + mLastNumProcesses);
14266                long now = SystemClock.uptimeMillis();
14267                pw.print("  mLastIdleTime=");
14268                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14269                        pw.print(" mLowRamSinceLastIdle=");
14270                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14271                        pw.println();
14272            }
14273        }
14274
14275        if (!printedAnything) {
14276            pw.println("  (nothing)");
14277        }
14278    }
14279
14280    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14281            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14282        if (mProcessesToGc.size() > 0) {
14283            boolean printed = false;
14284            long now = SystemClock.uptimeMillis();
14285            for (int i=0; i<mProcessesToGc.size(); i++) {
14286                ProcessRecord proc = mProcessesToGc.get(i);
14287                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14288                    continue;
14289                }
14290                if (!printed) {
14291                    if (needSep) pw.println();
14292                    needSep = true;
14293                    pw.println("  Processes that are waiting to GC:");
14294                    printed = true;
14295                }
14296                pw.print("    Process "); pw.println(proc);
14297                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14298                        pw.print(", last gced=");
14299                        pw.print(now-proc.lastRequestedGc);
14300                        pw.print(" ms ago, last lowMem=");
14301                        pw.print(now-proc.lastLowMemory);
14302                        pw.println(" ms ago");
14303
14304            }
14305        }
14306        return needSep;
14307    }
14308
14309    void printOomLevel(PrintWriter pw, String name, int adj) {
14310        pw.print("    ");
14311        if (adj >= 0) {
14312            pw.print(' ');
14313            if (adj < 10) pw.print(' ');
14314        } else {
14315            if (adj > -10) pw.print(' ');
14316        }
14317        pw.print(adj);
14318        pw.print(": ");
14319        pw.print(name);
14320        pw.print(" (");
14321        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14322        pw.println(")");
14323    }
14324
14325    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14326            int opti, boolean dumpAll) {
14327        boolean needSep = false;
14328
14329        if (mLruProcesses.size() > 0) {
14330            if (needSep) pw.println();
14331            needSep = true;
14332            pw.println("  OOM levels:");
14333            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14334            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14335            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14336            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14337            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14338            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14339            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14340            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14341            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14342            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14343            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14344            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14345            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14346            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14347
14348            if (needSep) pw.println();
14349            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14350                    pw.print(" total, non-act at ");
14351                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14352                    pw.print(", non-svc at ");
14353                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14354                    pw.println("):");
14355            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14356            needSep = true;
14357        }
14358
14359        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14360
14361        pw.println();
14362        pw.println("  mHomeProcess: " + mHomeProcess);
14363        pw.println("  mPreviousProcess: " + mPreviousProcess);
14364        if (mHeavyWeightProcess != null) {
14365            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14366        }
14367
14368        return true;
14369    }
14370
14371    /**
14372     * There are three ways to call this:
14373     *  - no provider specified: dump all the providers
14374     *  - a flattened component name that matched an existing provider was specified as the
14375     *    first arg: dump that one provider
14376     *  - the first arg isn't the flattened component name of an existing provider:
14377     *    dump all providers whose component contains the first arg as a substring
14378     */
14379    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14380            int opti, boolean dumpAll) {
14381        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14382    }
14383
14384    static class ItemMatcher {
14385        ArrayList<ComponentName> components;
14386        ArrayList<String> strings;
14387        ArrayList<Integer> objects;
14388        boolean all;
14389
14390        ItemMatcher() {
14391            all = true;
14392        }
14393
14394        void build(String name) {
14395            ComponentName componentName = ComponentName.unflattenFromString(name);
14396            if (componentName != null) {
14397                if (components == null) {
14398                    components = new ArrayList<ComponentName>();
14399                }
14400                components.add(componentName);
14401                all = false;
14402            } else {
14403                int objectId = 0;
14404                // Not a '/' separated full component name; maybe an object ID?
14405                try {
14406                    objectId = Integer.parseInt(name, 16);
14407                    if (objects == null) {
14408                        objects = new ArrayList<Integer>();
14409                    }
14410                    objects.add(objectId);
14411                    all = false;
14412                } catch (RuntimeException e) {
14413                    // Not an integer; just do string match.
14414                    if (strings == null) {
14415                        strings = new ArrayList<String>();
14416                    }
14417                    strings.add(name);
14418                    all = false;
14419                }
14420            }
14421        }
14422
14423        int build(String[] args, int opti) {
14424            for (; opti<args.length; opti++) {
14425                String name = args[opti];
14426                if ("--".equals(name)) {
14427                    return opti+1;
14428                }
14429                build(name);
14430            }
14431            return opti;
14432        }
14433
14434        boolean match(Object object, ComponentName comp) {
14435            if (all) {
14436                return true;
14437            }
14438            if (components != null) {
14439                for (int i=0; i<components.size(); i++) {
14440                    if (components.get(i).equals(comp)) {
14441                        return true;
14442                    }
14443                }
14444            }
14445            if (objects != null) {
14446                for (int i=0; i<objects.size(); i++) {
14447                    if (System.identityHashCode(object) == objects.get(i)) {
14448                        return true;
14449                    }
14450                }
14451            }
14452            if (strings != null) {
14453                String flat = comp.flattenToString();
14454                for (int i=0; i<strings.size(); i++) {
14455                    if (flat.contains(strings.get(i))) {
14456                        return true;
14457                    }
14458                }
14459            }
14460            return false;
14461        }
14462    }
14463
14464    /**
14465     * There are three things that cmd can be:
14466     *  - a flattened component name that matches an existing activity
14467     *  - the cmd arg isn't the flattened component name of an existing activity:
14468     *    dump all activity whose component contains the cmd as a substring
14469     *  - A hex number of the ActivityRecord object instance.
14470     */
14471    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14472            int opti, boolean dumpAll) {
14473        ArrayList<ActivityRecord> activities;
14474
14475        synchronized (this) {
14476            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14477        }
14478
14479        if (activities.size() <= 0) {
14480            return false;
14481        }
14482
14483        String[] newArgs = new String[args.length - opti];
14484        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14485
14486        TaskRecord lastTask = null;
14487        boolean needSep = false;
14488        for (int i=activities.size()-1; i>=0; i--) {
14489            ActivityRecord r = activities.get(i);
14490            if (needSep) {
14491                pw.println();
14492            }
14493            needSep = true;
14494            synchronized (this) {
14495                if (lastTask != r.task) {
14496                    lastTask = r.task;
14497                    pw.print("TASK "); pw.print(lastTask.affinity);
14498                            pw.print(" id="); pw.println(lastTask.taskId);
14499                    if (dumpAll) {
14500                        lastTask.dump(pw, "  ");
14501                    }
14502                }
14503            }
14504            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14505        }
14506        return true;
14507    }
14508
14509    /**
14510     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14511     * there is a thread associated with the activity.
14512     */
14513    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14514            final ActivityRecord r, String[] args, boolean dumpAll) {
14515        String innerPrefix = prefix + "  ";
14516        synchronized (this) {
14517            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14518                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14519                    pw.print(" pid=");
14520                    if (r.app != null) pw.println(r.app.pid);
14521                    else pw.println("(not running)");
14522            if (dumpAll) {
14523                r.dump(pw, innerPrefix);
14524            }
14525        }
14526        if (r.app != null && r.app.thread != null) {
14527            // flush anything that is already in the PrintWriter since the thread is going
14528            // to write to the file descriptor directly
14529            pw.flush();
14530            try {
14531                TransferPipe tp = new TransferPipe();
14532                try {
14533                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14534                            r.appToken, innerPrefix, args);
14535                    tp.go(fd);
14536                } finally {
14537                    tp.kill();
14538                }
14539            } catch (IOException e) {
14540                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14541            } catch (RemoteException e) {
14542                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14543            }
14544        }
14545    }
14546
14547    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14548            int opti, boolean dumpAll, String dumpPackage) {
14549        boolean needSep = false;
14550        boolean onlyHistory = false;
14551        boolean printedAnything = false;
14552
14553        if ("history".equals(dumpPackage)) {
14554            if (opti < args.length && "-s".equals(args[opti])) {
14555                dumpAll = false;
14556            }
14557            onlyHistory = true;
14558            dumpPackage = null;
14559        }
14560
14561        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14562        if (!onlyHistory && dumpAll) {
14563            if (mRegisteredReceivers.size() > 0) {
14564                boolean printed = false;
14565                Iterator it = mRegisteredReceivers.values().iterator();
14566                while (it.hasNext()) {
14567                    ReceiverList r = (ReceiverList)it.next();
14568                    if (dumpPackage != null && (r.app == null ||
14569                            !dumpPackage.equals(r.app.info.packageName))) {
14570                        continue;
14571                    }
14572                    if (!printed) {
14573                        pw.println("  Registered Receivers:");
14574                        needSep = true;
14575                        printed = true;
14576                        printedAnything = true;
14577                    }
14578                    pw.print("  * "); pw.println(r);
14579                    r.dump(pw, "    ");
14580                }
14581            }
14582
14583            if (mReceiverResolver.dump(pw, needSep ?
14584                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14585                    "    ", dumpPackage, false, false)) {
14586                needSep = true;
14587                printedAnything = true;
14588            }
14589        }
14590
14591        for (BroadcastQueue q : mBroadcastQueues) {
14592            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14593            printedAnything |= needSep;
14594        }
14595
14596        needSep = true;
14597
14598        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14599            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14600                if (needSep) {
14601                    pw.println();
14602                }
14603                needSep = true;
14604                printedAnything = true;
14605                pw.print("  Sticky broadcasts for user ");
14606                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14607                StringBuilder sb = new StringBuilder(128);
14608                for (Map.Entry<String, ArrayList<Intent>> ent
14609                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14610                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14611                    if (dumpAll) {
14612                        pw.println(":");
14613                        ArrayList<Intent> intents = ent.getValue();
14614                        final int N = intents.size();
14615                        for (int i=0; i<N; i++) {
14616                            sb.setLength(0);
14617                            sb.append("    Intent: ");
14618                            intents.get(i).toShortString(sb, false, true, false, false);
14619                            pw.println(sb.toString());
14620                            Bundle bundle = intents.get(i).getExtras();
14621                            if (bundle != null) {
14622                                pw.print("      ");
14623                                pw.println(bundle.toString());
14624                            }
14625                        }
14626                    } else {
14627                        pw.println("");
14628                    }
14629                }
14630            }
14631        }
14632
14633        if (!onlyHistory && dumpAll) {
14634            pw.println();
14635            for (BroadcastQueue queue : mBroadcastQueues) {
14636                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14637                        + queue.mBroadcastsScheduled);
14638            }
14639            pw.println("  mHandler:");
14640            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14641            needSep = true;
14642            printedAnything = true;
14643        }
14644
14645        if (!printedAnything) {
14646            pw.println("  (nothing)");
14647        }
14648    }
14649
14650    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14651            int opti, boolean dumpAll, String dumpPackage) {
14652        boolean needSep;
14653        boolean printedAnything = false;
14654
14655        ItemMatcher matcher = new ItemMatcher();
14656        matcher.build(args, opti);
14657
14658        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14659
14660        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14661        printedAnything |= needSep;
14662
14663        if (mLaunchingProviders.size() > 0) {
14664            boolean printed = false;
14665            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14666                ContentProviderRecord r = mLaunchingProviders.get(i);
14667                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14668                    continue;
14669                }
14670                if (!printed) {
14671                    if (needSep) pw.println();
14672                    needSep = true;
14673                    pw.println("  Launching content providers:");
14674                    printed = true;
14675                    printedAnything = true;
14676                }
14677                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14678                        pw.println(r);
14679            }
14680        }
14681
14682        if (!printedAnything) {
14683            pw.println("  (nothing)");
14684        }
14685    }
14686
14687    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14688            int opti, boolean dumpAll, String dumpPackage) {
14689        boolean needSep = false;
14690        boolean printedAnything = false;
14691
14692        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14693
14694        if (mGrantedUriPermissions.size() > 0) {
14695            boolean printed = false;
14696            int dumpUid = -2;
14697            if (dumpPackage != null) {
14698                try {
14699                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14700                            MATCH_UNINSTALLED_PACKAGES, 0);
14701                } catch (NameNotFoundException e) {
14702                    dumpUid = -1;
14703                }
14704            }
14705            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14706                int uid = mGrantedUriPermissions.keyAt(i);
14707                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14708                    continue;
14709                }
14710                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14711                if (!printed) {
14712                    if (needSep) pw.println();
14713                    needSep = true;
14714                    pw.println("  Granted Uri Permissions:");
14715                    printed = true;
14716                    printedAnything = true;
14717                }
14718                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14719                for (UriPermission perm : perms.values()) {
14720                    pw.print("    "); pw.println(perm);
14721                    if (dumpAll) {
14722                        perm.dump(pw, "      ");
14723                    }
14724                }
14725            }
14726        }
14727
14728        if (!printedAnything) {
14729            pw.println("  (nothing)");
14730        }
14731    }
14732
14733    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14734            int opti, boolean dumpAll, String dumpPackage) {
14735        boolean printed = false;
14736
14737        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14738
14739        if (mIntentSenderRecords.size() > 0) {
14740            Iterator<WeakReference<PendingIntentRecord>> it
14741                    = mIntentSenderRecords.values().iterator();
14742            while (it.hasNext()) {
14743                WeakReference<PendingIntentRecord> ref = it.next();
14744                PendingIntentRecord rec = ref != null ? ref.get(): null;
14745                if (dumpPackage != null && (rec == null
14746                        || !dumpPackage.equals(rec.key.packageName))) {
14747                    continue;
14748                }
14749                printed = true;
14750                if (rec != null) {
14751                    pw.print("  * "); pw.println(rec);
14752                    if (dumpAll) {
14753                        rec.dump(pw, "    ");
14754                    }
14755                } else {
14756                    pw.print("  * "); pw.println(ref);
14757                }
14758            }
14759        }
14760
14761        if (!printed) {
14762            pw.println("  (nothing)");
14763        }
14764    }
14765
14766    private static final int dumpProcessList(PrintWriter pw,
14767            ActivityManagerService service, List list,
14768            String prefix, String normalLabel, String persistentLabel,
14769            String dumpPackage) {
14770        int numPers = 0;
14771        final int N = list.size()-1;
14772        for (int i=N; i>=0; i--) {
14773            ProcessRecord r = (ProcessRecord)list.get(i);
14774            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14775                continue;
14776            }
14777            pw.println(String.format("%s%s #%2d: %s",
14778                    prefix, (r.persistent ? persistentLabel : normalLabel),
14779                    i, r.toString()));
14780            if (r.persistent) {
14781                numPers++;
14782            }
14783        }
14784        return numPers;
14785    }
14786
14787    private static final boolean dumpProcessOomList(PrintWriter pw,
14788            ActivityManagerService service, List<ProcessRecord> origList,
14789            String prefix, String normalLabel, String persistentLabel,
14790            boolean inclDetails, String dumpPackage) {
14791
14792        ArrayList<Pair<ProcessRecord, Integer>> list
14793                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14794        for (int i=0; i<origList.size(); i++) {
14795            ProcessRecord r = origList.get(i);
14796            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14797                continue;
14798            }
14799            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14800        }
14801
14802        if (list.size() <= 0) {
14803            return false;
14804        }
14805
14806        Comparator<Pair<ProcessRecord, Integer>> comparator
14807                = new Comparator<Pair<ProcessRecord, Integer>>() {
14808            @Override
14809            public int compare(Pair<ProcessRecord, Integer> object1,
14810                    Pair<ProcessRecord, Integer> object2) {
14811                if (object1.first.setAdj != object2.first.setAdj) {
14812                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14813                }
14814                if (object1.first.setProcState != object2.first.setProcState) {
14815                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14816                }
14817                if (object1.second.intValue() != object2.second.intValue()) {
14818                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14819                }
14820                return 0;
14821            }
14822        };
14823
14824        Collections.sort(list, comparator);
14825
14826        final long curRealtime = SystemClock.elapsedRealtime();
14827        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14828        final long curUptime = SystemClock.uptimeMillis();
14829        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14830
14831        for (int i=list.size()-1; i>=0; i--) {
14832            ProcessRecord r = list.get(i).first;
14833            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14834            char schedGroup;
14835            switch (r.setSchedGroup) {
14836                case ProcessList.SCHED_GROUP_BACKGROUND:
14837                    schedGroup = 'B';
14838                    break;
14839                case ProcessList.SCHED_GROUP_DEFAULT:
14840                    schedGroup = 'F';
14841                    break;
14842                case ProcessList.SCHED_GROUP_TOP_APP:
14843                    schedGroup = 'T';
14844                    break;
14845                default:
14846                    schedGroup = '?';
14847                    break;
14848            }
14849            char foreground;
14850            if (r.foregroundActivities) {
14851                foreground = 'A';
14852            } else if (r.foregroundServices) {
14853                foreground = 'S';
14854            } else {
14855                foreground = ' ';
14856            }
14857            String procState = ProcessList.makeProcStateString(r.curProcState);
14858            pw.print(prefix);
14859            pw.print(r.persistent ? persistentLabel : normalLabel);
14860            pw.print(" #");
14861            int num = (origList.size()-1)-list.get(i).second;
14862            if (num < 10) pw.print(' ');
14863            pw.print(num);
14864            pw.print(": ");
14865            pw.print(oomAdj);
14866            pw.print(' ');
14867            pw.print(schedGroup);
14868            pw.print('/');
14869            pw.print(foreground);
14870            pw.print('/');
14871            pw.print(procState);
14872            pw.print(" trm:");
14873            if (r.trimMemoryLevel < 10) pw.print(' ');
14874            pw.print(r.trimMemoryLevel);
14875            pw.print(' ');
14876            pw.print(r.toShortString());
14877            pw.print(" (");
14878            pw.print(r.adjType);
14879            pw.println(')');
14880            if (r.adjSource != null || r.adjTarget != null) {
14881                pw.print(prefix);
14882                pw.print("    ");
14883                if (r.adjTarget instanceof ComponentName) {
14884                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14885                } else if (r.adjTarget != null) {
14886                    pw.print(r.adjTarget.toString());
14887                } else {
14888                    pw.print("{null}");
14889                }
14890                pw.print("<=");
14891                if (r.adjSource instanceof ProcessRecord) {
14892                    pw.print("Proc{");
14893                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14894                    pw.println("}");
14895                } else if (r.adjSource != null) {
14896                    pw.println(r.adjSource.toString());
14897                } else {
14898                    pw.println("{null}");
14899                }
14900            }
14901            if (inclDetails) {
14902                pw.print(prefix);
14903                pw.print("    ");
14904                pw.print("oom: max="); pw.print(r.maxAdj);
14905                pw.print(" curRaw="); pw.print(r.curRawAdj);
14906                pw.print(" setRaw="); pw.print(r.setRawAdj);
14907                pw.print(" cur="); pw.print(r.curAdj);
14908                pw.print(" set="); pw.println(r.setAdj);
14909                pw.print(prefix);
14910                pw.print("    ");
14911                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14912                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14913                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14914                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14915                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14916                pw.println();
14917                pw.print(prefix);
14918                pw.print("    ");
14919                pw.print("cached="); pw.print(r.cached);
14920                pw.print(" empty="); pw.print(r.empty);
14921                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14922
14923                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14924                    if (r.lastWakeTime != 0) {
14925                        long wtime;
14926                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14927                        synchronized (stats) {
14928                            wtime = stats.getProcessWakeTime(r.info.uid,
14929                                    r.pid, curRealtime);
14930                        }
14931                        long timeUsed = wtime - r.lastWakeTime;
14932                        pw.print(prefix);
14933                        pw.print("    ");
14934                        pw.print("keep awake over ");
14935                        TimeUtils.formatDuration(realtimeSince, pw);
14936                        pw.print(" used ");
14937                        TimeUtils.formatDuration(timeUsed, pw);
14938                        pw.print(" (");
14939                        pw.print((timeUsed*100)/realtimeSince);
14940                        pw.println("%)");
14941                    }
14942                    if (r.lastCpuTime != 0) {
14943                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14944                        pw.print(prefix);
14945                        pw.print("    ");
14946                        pw.print("run cpu over ");
14947                        TimeUtils.formatDuration(uptimeSince, pw);
14948                        pw.print(" used ");
14949                        TimeUtils.formatDuration(timeUsed, pw);
14950                        pw.print(" (");
14951                        pw.print((timeUsed*100)/uptimeSince);
14952                        pw.println("%)");
14953                    }
14954                }
14955            }
14956        }
14957        return true;
14958    }
14959
14960    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14961            String[] args) {
14962        ArrayList<ProcessRecord> procs;
14963        synchronized (this) {
14964            if (args != null && args.length > start
14965                    && args[start].charAt(0) != '-') {
14966                procs = new ArrayList<ProcessRecord>();
14967                int pid = -1;
14968                try {
14969                    pid = Integer.parseInt(args[start]);
14970                } catch (NumberFormatException e) {
14971                }
14972                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14973                    ProcessRecord proc = mLruProcesses.get(i);
14974                    if (proc.pid == pid) {
14975                        procs.add(proc);
14976                    } else if (allPkgs && proc.pkgList != null
14977                            && proc.pkgList.containsKey(args[start])) {
14978                        procs.add(proc);
14979                    } else if (proc.processName.equals(args[start])) {
14980                        procs.add(proc);
14981                    }
14982                }
14983                if (procs.size() <= 0) {
14984                    return null;
14985                }
14986            } else {
14987                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14988            }
14989        }
14990        return procs;
14991    }
14992
14993    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14994            PrintWriter pw, String[] args) {
14995        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14996        if (procs == null) {
14997            pw.println("No process found for: " + args[0]);
14998            return;
14999        }
15000
15001        long uptime = SystemClock.uptimeMillis();
15002        long realtime = SystemClock.elapsedRealtime();
15003        pw.println("Applications Graphics Acceleration Info:");
15004        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15005
15006        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15007            ProcessRecord r = procs.get(i);
15008            if (r.thread != null) {
15009                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15010                pw.flush();
15011                try {
15012                    TransferPipe tp = new TransferPipe();
15013                    try {
15014                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15015                        tp.go(fd);
15016                    } finally {
15017                        tp.kill();
15018                    }
15019                } catch (IOException e) {
15020                    pw.println("Failure while dumping the app: " + r);
15021                    pw.flush();
15022                } catch (RemoteException e) {
15023                    pw.println("Got a RemoteException while dumping the app " + r);
15024                    pw.flush();
15025                }
15026            }
15027        }
15028    }
15029
15030    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15031        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15032        if (procs == null) {
15033            pw.println("No process found for: " + args[0]);
15034            return;
15035        }
15036
15037        pw.println("Applications Database Info:");
15038
15039        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15040            ProcessRecord r = procs.get(i);
15041            if (r.thread != null) {
15042                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15043                pw.flush();
15044                try {
15045                    TransferPipe tp = new TransferPipe();
15046                    try {
15047                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15048                        tp.go(fd);
15049                    } finally {
15050                        tp.kill();
15051                    }
15052                } catch (IOException e) {
15053                    pw.println("Failure while dumping the app: " + r);
15054                    pw.flush();
15055                } catch (RemoteException e) {
15056                    pw.println("Got a RemoteException while dumping the app " + r);
15057                    pw.flush();
15058                }
15059            }
15060        }
15061    }
15062
15063    final static class MemItem {
15064        final boolean isProc;
15065        final String label;
15066        final String shortLabel;
15067        final long pss;
15068        final long swapPss;
15069        final int id;
15070        final boolean hasActivities;
15071        ArrayList<MemItem> subitems;
15072
15073        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15074                boolean _hasActivities) {
15075            isProc = true;
15076            label = _label;
15077            shortLabel = _shortLabel;
15078            pss = _pss;
15079            swapPss = _swapPss;
15080            id = _id;
15081            hasActivities = _hasActivities;
15082        }
15083
15084        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15085            isProc = false;
15086            label = _label;
15087            shortLabel = _shortLabel;
15088            pss = _pss;
15089            swapPss = _swapPss;
15090            id = _id;
15091            hasActivities = false;
15092        }
15093    }
15094
15095    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15096            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15097        if (sort && !isCompact) {
15098            Collections.sort(items, new Comparator<MemItem>() {
15099                @Override
15100                public int compare(MemItem lhs, MemItem rhs) {
15101                    if (lhs.pss < rhs.pss) {
15102                        return 1;
15103                    } else if (lhs.pss > rhs.pss) {
15104                        return -1;
15105                    }
15106                    return 0;
15107                }
15108            });
15109        }
15110
15111        for (int i=0; i<items.size(); i++) {
15112            MemItem mi = items.get(i);
15113            if (!isCompact) {
15114                if (dumpSwapPss) {
15115                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15116                            mi.label, stringifyKBSize(mi.swapPss));
15117                } else {
15118                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15119                }
15120            } else if (mi.isProc) {
15121                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15122                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15123                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15124                pw.println(mi.hasActivities ? ",a" : ",e");
15125            } else {
15126                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15127                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15128            }
15129            if (mi.subitems != null) {
15130                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15131                        true, isCompact, dumpSwapPss);
15132            }
15133        }
15134    }
15135
15136    // These are in KB.
15137    static final long[] DUMP_MEM_BUCKETS = new long[] {
15138        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15139        120*1024, 160*1024, 200*1024,
15140        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15141        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15142    };
15143
15144    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15145            boolean stackLike) {
15146        int start = label.lastIndexOf('.');
15147        if (start >= 0) start++;
15148        else start = 0;
15149        int end = label.length();
15150        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15151            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15152                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15153                out.append(bucket);
15154                out.append(stackLike ? "MB." : "MB ");
15155                out.append(label, start, end);
15156                return;
15157            }
15158        }
15159        out.append(memKB/1024);
15160        out.append(stackLike ? "MB." : "MB ");
15161        out.append(label, start, end);
15162    }
15163
15164    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15165            ProcessList.NATIVE_ADJ,
15166            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15167            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15168            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15169            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15170            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15171            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15172    };
15173    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15174            "Native",
15175            "System", "Persistent", "Persistent Service", "Foreground",
15176            "Visible", "Perceptible",
15177            "Heavy Weight", "Backup",
15178            "A Services", "Home",
15179            "Previous", "B Services", "Cached"
15180    };
15181    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15182            "native",
15183            "sys", "pers", "persvc", "fore",
15184            "vis", "percept",
15185            "heavy", "backup",
15186            "servicea", "home",
15187            "prev", "serviceb", "cached"
15188    };
15189
15190    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15191            long realtime, boolean isCheckinRequest, boolean isCompact) {
15192        if (isCompact) {
15193            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15194        }
15195        if (isCheckinRequest || isCompact) {
15196            // short checkin version
15197            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15198        } else {
15199            pw.println("Applications Memory Usage (in Kilobytes):");
15200            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15201        }
15202    }
15203
15204    private static final int KSM_SHARED = 0;
15205    private static final int KSM_SHARING = 1;
15206    private static final int KSM_UNSHARED = 2;
15207    private static final int KSM_VOLATILE = 3;
15208
15209    private final long[] getKsmInfo() {
15210        long[] longOut = new long[4];
15211        final int[] SINGLE_LONG_FORMAT = new int[] {
15212            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15213        };
15214        long[] longTmp = new long[1];
15215        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15216                SINGLE_LONG_FORMAT, null, longTmp, null);
15217        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15218        longTmp[0] = 0;
15219        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15220                SINGLE_LONG_FORMAT, null, longTmp, null);
15221        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15222        longTmp[0] = 0;
15223        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15224                SINGLE_LONG_FORMAT, null, longTmp, null);
15225        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15226        longTmp[0] = 0;
15227        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15228                SINGLE_LONG_FORMAT, null, longTmp, null);
15229        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15230        return longOut;
15231    }
15232
15233    private static String stringifySize(long size, int order) {
15234        Locale locale = Locale.US;
15235        switch (order) {
15236            case 1:
15237                return String.format(locale, "%,13d", size);
15238            case 1024:
15239                return String.format(locale, "%,9dK", size / 1024);
15240            case 1024 * 1024:
15241                return String.format(locale, "%,5dM", size / 1024 / 1024);
15242            case 1024 * 1024 * 1024:
15243                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15244            default:
15245                throw new IllegalArgumentException("Invalid size order");
15246        }
15247    }
15248
15249    private static String stringifyKBSize(long size) {
15250        return stringifySize(size * 1024, 1024);
15251    }
15252
15253    // Update this version number in case you change the 'compact' format
15254    private static final int MEMINFO_COMPACT_VERSION = 1;
15255
15256    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15257            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15258        boolean dumpDetails = false;
15259        boolean dumpFullDetails = false;
15260        boolean dumpDalvik = false;
15261        boolean dumpSummaryOnly = false;
15262        boolean dumpUnreachable = false;
15263        boolean oomOnly = false;
15264        boolean isCompact = false;
15265        boolean localOnly = false;
15266        boolean packages = false;
15267        boolean isCheckinRequest = false;
15268        boolean dumpSwapPss = false;
15269
15270        int opti = 0;
15271        while (opti < args.length) {
15272            String opt = args[opti];
15273            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15274                break;
15275            }
15276            opti++;
15277            if ("-a".equals(opt)) {
15278                dumpDetails = true;
15279                dumpFullDetails = true;
15280                dumpDalvik = true;
15281                dumpSwapPss = true;
15282            } else if ("-d".equals(opt)) {
15283                dumpDalvik = true;
15284            } else if ("-c".equals(opt)) {
15285                isCompact = true;
15286            } else if ("-s".equals(opt)) {
15287                dumpDetails = true;
15288                dumpSummaryOnly = true;
15289            } else if ("-S".equals(opt)) {
15290                dumpSwapPss = true;
15291            } else if ("--unreachable".equals(opt)) {
15292                dumpUnreachable = true;
15293            } else if ("--oom".equals(opt)) {
15294                oomOnly = true;
15295            } else if ("--local".equals(opt)) {
15296                localOnly = true;
15297            } else if ("--package".equals(opt)) {
15298                packages = true;
15299            } else if ("--checkin".equals(opt)) {
15300                isCheckinRequest = true;
15301
15302            } else if ("-h".equals(opt)) {
15303                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15304                pw.println("  -a: include all available information for each process.");
15305                pw.println("  -d: include dalvik details.");
15306                pw.println("  -c: dump in a compact machine-parseable representation.");
15307                pw.println("  -s: dump only summary of application memory usage.");
15308                pw.println("  -S: dump also SwapPss.");
15309                pw.println("  --oom: only show processes organized by oom adj.");
15310                pw.println("  --local: only collect details locally, don't call process.");
15311                pw.println("  --package: interpret process arg as package, dumping all");
15312                pw.println("             processes that have loaded that package.");
15313                pw.println("  --checkin: dump data for a checkin");
15314                pw.println("If [process] is specified it can be the name or ");
15315                pw.println("pid of a specific process to dump.");
15316                return;
15317            } else {
15318                pw.println("Unknown argument: " + opt + "; use -h for help");
15319            }
15320        }
15321
15322        long uptime = SystemClock.uptimeMillis();
15323        long realtime = SystemClock.elapsedRealtime();
15324        final long[] tmpLong = new long[1];
15325
15326        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15327        if (procs == null) {
15328            // No Java processes.  Maybe they want to print a native process.
15329            if (args != null && args.length > opti
15330                    && args[opti].charAt(0) != '-') {
15331                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15332                        = new ArrayList<ProcessCpuTracker.Stats>();
15333                updateCpuStatsNow();
15334                int findPid = -1;
15335                try {
15336                    findPid = Integer.parseInt(args[opti]);
15337                } catch (NumberFormatException e) {
15338                }
15339                synchronized (mProcessCpuTracker) {
15340                    final int N = mProcessCpuTracker.countStats();
15341                    for (int i=0; i<N; i++) {
15342                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15343                        if (st.pid == findPid || (st.baseName != null
15344                                && st.baseName.equals(args[opti]))) {
15345                            nativeProcs.add(st);
15346                        }
15347                    }
15348                }
15349                if (nativeProcs.size() > 0) {
15350                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15351                            isCompact);
15352                    Debug.MemoryInfo mi = null;
15353                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15354                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15355                        final int pid = r.pid;
15356                        if (!isCheckinRequest && dumpDetails) {
15357                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15358                        }
15359                        if (mi == null) {
15360                            mi = new Debug.MemoryInfo();
15361                        }
15362                        if (dumpDetails || (!brief && !oomOnly)) {
15363                            Debug.getMemoryInfo(pid, mi);
15364                        } else {
15365                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15366                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15367                        }
15368                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15369                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15370                        if (isCheckinRequest) {
15371                            pw.println();
15372                        }
15373                    }
15374                    return;
15375                }
15376            }
15377            pw.println("No process found for: " + args[opti]);
15378            return;
15379        }
15380
15381        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15382            dumpDetails = true;
15383        }
15384
15385        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15386
15387        String[] innerArgs = new String[args.length-opti];
15388        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15389
15390        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15391        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15392        long nativePss = 0;
15393        long nativeSwapPss = 0;
15394        long dalvikPss = 0;
15395        long dalvikSwapPss = 0;
15396        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15397                EmptyArray.LONG;
15398        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15399                EmptyArray.LONG;
15400        long otherPss = 0;
15401        long otherSwapPss = 0;
15402        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15403        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15404
15405        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15406        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15407        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15408                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15409
15410        long totalPss = 0;
15411        long totalSwapPss = 0;
15412        long cachedPss = 0;
15413        long cachedSwapPss = 0;
15414        boolean hasSwapPss = false;
15415
15416        Debug.MemoryInfo mi = null;
15417        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15418            final ProcessRecord r = procs.get(i);
15419            final IApplicationThread thread;
15420            final int pid;
15421            final int oomAdj;
15422            final boolean hasActivities;
15423            synchronized (this) {
15424                thread = r.thread;
15425                pid = r.pid;
15426                oomAdj = r.getSetAdjWithServices();
15427                hasActivities = r.activities.size() > 0;
15428            }
15429            if (thread != null) {
15430                if (!isCheckinRequest && dumpDetails) {
15431                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15432                }
15433                if (mi == null) {
15434                    mi = new Debug.MemoryInfo();
15435                }
15436                if (dumpDetails || (!brief && !oomOnly)) {
15437                    Debug.getMemoryInfo(pid, mi);
15438                    hasSwapPss = mi.hasSwappedOutPss;
15439                } else {
15440                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15441                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15442                }
15443                if (dumpDetails) {
15444                    if (localOnly) {
15445                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15446                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15447                        if (isCheckinRequest) {
15448                            pw.println();
15449                        }
15450                    } else {
15451                        try {
15452                            pw.flush();
15453                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15454                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15455                        } catch (RemoteException e) {
15456                            if (!isCheckinRequest) {
15457                                pw.println("Got RemoteException!");
15458                                pw.flush();
15459                            }
15460                        }
15461                    }
15462                }
15463
15464                final long myTotalPss = mi.getTotalPss();
15465                final long myTotalUss = mi.getTotalUss();
15466                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15467
15468                synchronized (this) {
15469                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15470                        // Record this for posterity if the process has been stable.
15471                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15472                    }
15473                }
15474
15475                if (!isCheckinRequest && mi != null) {
15476                    totalPss += myTotalPss;
15477                    totalSwapPss += myTotalSwapPss;
15478                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15479                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15480                            myTotalSwapPss, pid, hasActivities);
15481                    procMems.add(pssItem);
15482                    procMemsMap.put(pid, pssItem);
15483
15484                    nativePss += mi.nativePss;
15485                    nativeSwapPss += mi.nativeSwappedOutPss;
15486                    dalvikPss += mi.dalvikPss;
15487                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15488                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15489                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15490                        dalvikSubitemSwapPss[j] +=
15491                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15492                    }
15493                    otherPss += mi.otherPss;
15494                    otherSwapPss += mi.otherSwappedOutPss;
15495                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15496                        long mem = mi.getOtherPss(j);
15497                        miscPss[j] += mem;
15498                        otherPss -= mem;
15499                        mem = mi.getOtherSwappedOutPss(j);
15500                        miscSwapPss[j] += mem;
15501                        otherSwapPss -= mem;
15502                    }
15503
15504                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15505                        cachedPss += myTotalPss;
15506                        cachedSwapPss += myTotalSwapPss;
15507                    }
15508
15509                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15510                        if (oomIndex == (oomPss.length - 1)
15511                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15512                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15513                            oomPss[oomIndex] += myTotalPss;
15514                            oomSwapPss[oomIndex] += myTotalSwapPss;
15515                            if (oomProcs[oomIndex] == null) {
15516                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15517                            }
15518                            oomProcs[oomIndex].add(pssItem);
15519                            break;
15520                        }
15521                    }
15522                }
15523            }
15524        }
15525
15526        long nativeProcTotalPss = 0;
15527
15528        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15529            // If we are showing aggregations, also look for native processes to
15530            // include so that our aggregations are more accurate.
15531            updateCpuStatsNow();
15532            mi = null;
15533            synchronized (mProcessCpuTracker) {
15534                final int N = mProcessCpuTracker.countStats();
15535                for (int i=0; i<N; i++) {
15536                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15537                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15538                        if (mi == null) {
15539                            mi = new Debug.MemoryInfo();
15540                        }
15541                        if (!brief && !oomOnly) {
15542                            Debug.getMemoryInfo(st.pid, mi);
15543                        } else {
15544                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15545                            mi.nativePrivateDirty = (int)tmpLong[0];
15546                        }
15547
15548                        final long myTotalPss = mi.getTotalPss();
15549                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15550                        totalPss += myTotalPss;
15551                        nativeProcTotalPss += myTotalPss;
15552
15553                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15554                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15555                        procMems.add(pssItem);
15556
15557                        nativePss += mi.nativePss;
15558                        nativeSwapPss += mi.nativeSwappedOutPss;
15559                        dalvikPss += mi.dalvikPss;
15560                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15561                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15562                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15563                            dalvikSubitemSwapPss[j] +=
15564                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15565                        }
15566                        otherPss += mi.otherPss;
15567                        otherSwapPss += mi.otherSwappedOutPss;
15568                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15569                            long mem = mi.getOtherPss(j);
15570                            miscPss[j] += mem;
15571                            otherPss -= mem;
15572                            mem = mi.getOtherSwappedOutPss(j);
15573                            miscSwapPss[j] += mem;
15574                            otherSwapPss -= mem;
15575                        }
15576                        oomPss[0] += myTotalPss;
15577                        oomSwapPss[0] += myTotalSwapPss;
15578                        if (oomProcs[0] == null) {
15579                            oomProcs[0] = new ArrayList<MemItem>();
15580                        }
15581                        oomProcs[0].add(pssItem);
15582                    }
15583                }
15584            }
15585
15586            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15587
15588            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15589            final MemItem dalvikItem =
15590                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15591            if (dalvikSubitemPss.length > 0) {
15592                dalvikItem.subitems = new ArrayList<MemItem>();
15593                for (int j=0; j<dalvikSubitemPss.length; j++) {
15594                    final String name = Debug.MemoryInfo.getOtherLabel(
15595                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15596                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15597                                    dalvikSubitemSwapPss[j], j));
15598                }
15599            }
15600            catMems.add(dalvikItem);
15601            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15602            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15603                String label = Debug.MemoryInfo.getOtherLabel(j);
15604                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15605            }
15606
15607            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15608            for (int j=0; j<oomPss.length; j++) {
15609                if (oomPss[j] != 0) {
15610                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15611                            : DUMP_MEM_OOM_LABEL[j];
15612                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15613                            DUMP_MEM_OOM_ADJ[j]);
15614                    item.subitems = oomProcs[j];
15615                    oomMems.add(item);
15616                }
15617            }
15618
15619            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15620            if (!brief && !oomOnly && !isCompact) {
15621                pw.println();
15622                pw.println("Total PSS by process:");
15623                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15624                pw.println();
15625            }
15626            if (!isCompact) {
15627                pw.println("Total PSS by OOM adjustment:");
15628            }
15629            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15630            if (!brief && !oomOnly) {
15631                PrintWriter out = categoryPw != null ? categoryPw : pw;
15632                if (!isCompact) {
15633                    out.println();
15634                    out.println("Total PSS by category:");
15635                }
15636                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15637            }
15638            if (!isCompact) {
15639                pw.println();
15640            }
15641            MemInfoReader memInfo = new MemInfoReader();
15642            memInfo.readMemInfo();
15643            if (nativeProcTotalPss > 0) {
15644                synchronized (this) {
15645                    final long cachedKb = memInfo.getCachedSizeKb();
15646                    final long freeKb = memInfo.getFreeSizeKb();
15647                    final long zramKb = memInfo.getZramTotalSizeKb();
15648                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15649                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15650                            kernelKb*1024, nativeProcTotalPss*1024);
15651                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15652                            nativeProcTotalPss);
15653                }
15654            }
15655            if (!brief) {
15656                if (!isCompact) {
15657                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15658                    pw.print(" (status ");
15659                    switch (mLastMemoryLevel) {
15660                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15661                            pw.println("normal)");
15662                            break;
15663                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15664                            pw.println("moderate)");
15665                            break;
15666                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15667                            pw.println("low)");
15668                            break;
15669                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15670                            pw.println("critical)");
15671                            break;
15672                        default:
15673                            pw.print(mLastMemoryLevel);
15674                            pw.println(")");
15675                            break;
15676                    }
15677                    pw.print(" Free RAM: ");
15678                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15679                            + memInfo.getFreeSizeKb()));
15680                    pw.print(" (");
15681                    pw.print(stringifyKBSize(cachedPss));
15682                    pw.print(" cached pss + ");
15683                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15684                    pw.print(" cached kernel + ");
15685                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15686                    pw.println(" free)");
15687                } else {
15688                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15689                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15690                            + memInfo.getFreeSizeKb()); pw.print(",");
15691                    pw.println(totalPss - cachedPss);
15692                }
15693            }
15694            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15695                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15696                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15697            if (!isCompact) {
15698                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15699                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15700                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15701                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15702                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15703            } else {
15704                pw.print("lostram,"); pw.println(lostRAM);
15705            }
15706            if (!brief) {
15707                if (memInfo.getZramTotalSizeKb() != 0) {
15708                    if (!isCompact) {
15709                        pw.print("     ZRAM: ");
15710                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15711                                pw.print(" physical used for ");
15712                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15713                                        - memInfo.getSwapFreeSizeKb()));
15714                                pw.print(" in swap (");
15715                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15716                                pw.println(" total swap)");
15717                    } else {
15718                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15719                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15720                                pw.println(memInfo.getSwapFreeSizeKb());
15721                    }
15722                }
15723                final long[] ksm = getKsmInfo();
15724                if (!isCompact) {
15725                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15726                            || ksm[KSM_VOLATILE] != 0) {
15727                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15728                                pw.print(" saved from shared ");
15729                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15730                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15731                                pw.print(" unshared; ");
15732                                pw.print(stringifyKBSize(
15733                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15734                    }
15735                    pw.print("   Tuning: ");
15736                    pw.print(ActivityManager.staticGetMemoryClass());
15737                    pw.print(" (large ");
15738                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15739                    pw.print("), oom ");
15740                    pw.print(stringifySize(
15741                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15742                    pw.print(", restore limit ");
15743                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15744                    if (ActivityManager.isLowRamDeviceStatic()) {
15745                        pw.print(" (low-ram)");
15746                    }
15747                    if (ActivityManager.isHighEndGfx()) {
15748                        pw.print(" (high-end-gfx)");
15749                    }
15750                    pw.println();
15751                } else {
15752                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15753                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15754                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15755                    pw.print("tuning,");
15756                    pw.print(ActivityManager.staticGetMemoryClass());
15757                    pw.print(',');
15758                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15759                    pw.print(',');
15760                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15761                    if (ActivityManager.isLowRamDeviceStatic()) {
15762                        pw.print(",low-ram");
15763                    }
15764                    if (ActivityManager.isHighEndGfx()) {
15765                        pw.print(",high-end-gfx");
15766                    }
15767                    pw.println();
15768                }
15769            }
15770        }
15771    }
15772
15773    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15774            long memtrack, String name) {
15775        sb.append("  ");
15776        sb.append(ProcessList.makeOomAdjString(oomAdj));
15777        sb.append(' ');
15778        sb.append(ProcessList.makeProcStateString(procState));
15779        sb.append(' ');
15780        ProcessList.appendRamKb(sb, pss);
15781        sb.append(": ");
15782        sb.append(name);
15783        if (memtrack > 0) {
15784            sb.append(" (");
15785            sb.append(stringifyKBSize(memtrack));
15786            sb.append(" memtrack)");
15787        }
15788    }
15789
15790    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15791        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15792        sb.append(" (pid ");
15793        sb.append(mi.pid);
15794        sb.append(") ");
15795        sb.append(mi.adjType);
15796        sb.append('\n');
15797        if (mi.adjReason != null) {
15798            sb.append("                      ");
15799            sb.append(mi.adjReason);
15800            sb.append('\n');
15801        }
15802    }
15803
15804    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15805        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15806        for (int i=0, N=memInfos.size(); i<N; i++) {
15807            ProcessMemInfo mi = memInfos.get(i);
15808            infoMap.put(mi.pid, mi);
15809        }
15810        updateCpuStatsNow();
15811        long[] memtrackTmp = new long[1];
15812        synchronized (mProcessCpuTracker) {
15813            final int N = mProcessCpuTracker.countStats();
15814            for (int i=0; i<N; i++) {
15815                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15816                if (st.vsize > 0) {
15817                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15818                    if (pss > 0) {
15819                        if (infoMap.indexOfKey(st.pid) < 0) {
15820                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15821                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15822                            mi.pss = pss;
15823                            mi.memtrack = memtrackTmp[0];
15824                            memInfos.add(mi);
15825                        }
15826                    }
15827                }
15828            }
15829        }
15830
15831        long totalPss = 0;
15832        long totalMemtrack = 0;
15833        for (int i=0, N=memInfos.size(); i<N; i++) {
15834            ProcessMemInfo mi = memInfos.get(i);
15835            if (mi.pss == 0) {
15836                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15837                mi.memtrack = memtrackTmp[0];
15838            }
15839            totalPss += mi.pss;
15840            totalMemtrack += mi.memtrack;
15841        }
15842        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15843            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15844                if (lhs.oomAdj != rhs.oomAdj) {
15845                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15846                }
15847                if (lhs.pss != rhs.pss) {
15848                    return lhs.pss < rhs.pss ? 1 : -1;
15849                }
15850                return 0;
15851            }
15852        });
15853
15854        StringBuilder tag = new StringBuilder(128);
15855        StringBuilder stack = new StringBuilder(128);
15856        tag.append("Low on memory -- ");
15857        appendMemBucket(tag, totalPss, "total", false);
15858        appendMemBucket(stack, totalPss, "total", true);
15859
15860        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15861        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15862        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15863
15864        boolean firstLine = true;
15865        int lastOomAdj = Integer.MIN_VALUE;
15866        long extraNativeRam = 0;
15867        long extraNativeMemtrack = 0;
15868        long cachedPss = 0;
15869        for (int i=0, N=memInfos.size(); i<N; i++) {
15870            ProcessMemInfo mi = memInfos.get(i);
15871
15872            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15873                cachedPss += mi.pss;
15874            }
15875
15876            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15877                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15878                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15879                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15880                if (lastOomAdj != mi.oomAdj) {
15881                    lastOomAdj = mi.oomAdj;
15882                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15883                        tag.append(" / ");
15884                    }
15885                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15886                        if (firstLine) {
15887                            stack.append(":");
15888                            firstLine = false;
15889                        }
15890                        stack.append("\n\t at ");
15891                    } else {
15892                        stack.append("$");
15893                    }
15894                } else {
15895                    tag.append(" ");
15896                    stack.append("$");
15897                }
15898                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15899                    appendMemBucket(tag, mi.pss, mi.name, false);
15900                }
15901                appendMemBucket(stack, mi.pss, mi.name, true);
15902                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15903                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15904                    stack.append("(");
15905                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15906                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15907                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15908                            stack.append(":");
15909                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15910                        }
15911                    }
15912                    stack.append(")");
15913                }
15914            }
15915
15916            appendMemInfo(fullNativeBuilder, mi);
15917            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15918                // The short form only has native processes that are >= 512K.
15919                if (mi.pss >= 512) {
15920                    appendMemInfo(shortNativeBuilder, mi);
15921                } else {
15922                    extraNativeRam += mi.pss;
15923                    extraNativeMemtrack += mi.memtrack;
15924                }
15925            } else {
15926                // Short form has all other details, but if we have collected RAM
15927                // from smaller native processes let's dump a summary of that.
15928                if (extraNativeRam > 0) {
15929                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15930                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15931                    shortNativeBuilder.append('\n');
15932                    extraNativeRam = 0;
15933                }
15934                appendMemInfo(fullJavaBuilder, mi);
15935            }
15936        }
15937
15938        fullJavaBuilder.append("           ");
15939        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15940        fullJavaBuilder.append(": TOTAL");
15941        if (totalMemtrack > 0) {
15942            fullJavaBuilder.append(" (");
15943            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15944            fullJavaBuilder.append(" memtrack)");
15945        } else {
15946        }
15947        fullJavaBuilder.append("\n");
15948
15949        MemInfoReader memInfo = new MemInfoReader();
15950        memInfo.readMemInfo();
15951        final long[] infos = memInfo.getRawInfo();
15952
15953        StringBuilder memInfoBuilder = new StringBuilder(1024);
15954        Debug.getMemInfo(infos);
15955        memInfoBuilder.append("  MemInfo: ");
15956        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15957        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15958        memInfoBuilder.append(stringifyKBSize(
15959                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15960        memInfoBuilder.append(stringifyKBSize(
15961                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15962        memInfoBuilder.append(stringifyKBSize(
15963                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15964        memInfoBuilder.append("           ");
15965        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15966        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15967        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15968        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15969        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15970            memInfoBuilder.append("  ZRAM: ");
15971            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15972            memInfoBuilder.append(" RAM, ");
15973            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15974            memInfoBuilder.append(" swap total, ");
15975            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15976            memInfoBuilder.append(" swap free\n");
15977        }
15978        final long[] ksm = getKsmInfo();
15979        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15980                || ksm[KSM_VOLATILE] != 0) {
15981            memInfoBuilder.append("  KSM: ");
15982            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15983            memInfoBuilder.append(" saved from shared ");
15984            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15985            memInfoBuilder.append("\n       ");
15986            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15987            memInfoBuilder.append(" unshared; ");
15988            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15989            memInfoBuilder.append(" volatile\n");
15990        }
15991        memInfoBuilder.append("  Free RAM: ");
15992        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15993                + memInfo.getFreeSizeKb()));
15994        memInfoBuilder.append("\n");
15995        memInfoBuilder.append("  Used RAM: ");
15996        memInfoBuilder.append(stringifyKBSize(
15997                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15998        memInfoBuilder.append("\n");
15999        memInfoBuilder.append("  Lost RAM: ");
16000        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16001                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16002                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16003        memInfoBuilder.append("\n");
16004        Slog.i(TAG, "Low on memory:");
16005        Slog.i(TAG, shortNativeBuilder.toString());
16006        Slog.i(TAG, fullJavaBuilder.toString());
16007        Slog.i(TAG, memInfoBuilder.toString());
16008
16009        StringBuilder dropBuilder = new StringBuilder(1024);
16010        /*
16011        StringWriter oomSw = new StringWriter();
16012        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16013        StringWriter catSw = new StringWriter();
16014        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16015        String[] emptyArgs = new String[] { };
16016        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16017        oomPw.flush();
16018        String oomString = oomSw.toString();
16019        */
16020        dropBuilder.append("Low on memory:");
16021        dropBuilder.append(stack);
16022        dropBuilder.append('\n');
16023        dropBuilder.append(fullNativeBuilder);
16024        dropBuilder.append(fullJavaBuilder);
16025        dropBuilder.append('\n');
16026        dropBuilder.append(memInfoBuilder);
16027        dropBuilder.append('\n');
16028        /*
16029        dropBuilder.append(oomString);
16030        dropBuilder.append('\n');
16031        */
16032        StringWriter catSw = new StringWriter();
16033        synchronized (ActivityManagerService.this) {
16034            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16035            String[] emptyArgs = new String[] { };
16036            catPw.println();
16037            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16038            catPw.println();
16039            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16040                    false, false, null);
16041            catPw.println();
16042            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16043            catPw.flush();
16044        }
16045        dropBuilder.append(catSw.toString());
16046        addErrorToDropBox("lowmem", null, "system_server", null,
16047                null, tag.toString(), dropBuilder.toString(), null, null);
16048        //Slog.i(TAG, "Sent to dropbox:");
16049        //Slog.i(TAG, dropBuilder.toString());
16050        synchronized (ActivityManagerService.this) {
16051            long now = SystemClock.uptimeMillis();
16052            if (mLastMemUsageReportTime < now) {
16053                mLastMemUsageReportTime = now;
16054            }
16055        }
16056    }
16057
16058    /**
16059     * Searches array of arguments for the specified string
16060     * @param args array of argument strings
16061     * @param value value to search for
16062     * @return true if the value is contained in the array
16063     */
16064    private static boolean scanArgs(String[] args, String value) {
16065        if (args != null) {
16066            for (String arg : args) {
16067                if (value.equals(arg)) {
16068                    return true;
16069                }
16070            }
16071        }
16072        return false;
16073    }
16074
16075    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16076            ContentProviderRecord cpr, boolean always) {
16077        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16078
16079        if (!inLaunching || always) {
16080            synchronized (cpr) {
16081                cpr.launchingApp = null;
16082                cpr.notifyAll();
16083            }
16084            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16085            String names[] = cpr.info.authority.split(";");
16086            for (int j = 0; j < names.length; j++) {
16087                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16088            }
16089        }
16090
16091        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16092            ContentProviderConnection conn = cpr.connections.get(i);
16093            if (conn.waiting) {
16094                // If this connection is waiting for the provider, then we don't
16095                // need to mess with its process unless we are always removing
16096                // or for some reason the provider is not currently launching.
16097                if (inLaunching && !always) {
16098                    continue;
16099                }
16100            }
16101            ProcessRecord capp = conn.client;
16102            conn.dead = true;
16103            if (conn.stableCount > 0) {
16104                if (!capp.persistent && capp.thread != null
16105                        && capp.pid != 0
16106                        && capp.pid != MY_PID) {
16107                    capp.kill("depends on provider "
16108                            + cpr.name.flattenToShortString()
16109                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16110                }
16111            } else if (capp.thread != null && conn.provider.provider != null) {
16112                try {
16113                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16114                } catch (RemoteException e) {
16115                }
16116                // In the protocol here, we don't expect the client to correctly
16117                // clean up this connection, we'll just remove it.
16118                cpr.connections.remove(i);
16119                if (conn.client.conProviders.remove(conn)) {
16120                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16121                }
16122            }
16123        }
16124
16125        if (inLaunching && always) {
16126            mLaunchingProviders.remove(cpr);
16127        }
16128        return inLaunching;
16129    }
16130
16131    /**
16132     * Main code for cleaning up a process when it has gone away.  This is
16133     * called both as a result of the process dying, or directly when stopping
16134     * a process when running in single process mode.
16135     *
16136     * @return Returns true if the given process has been restarted, so the
16137     * app that was passed in must remain on the process lists.
16138     */
16139    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16140            boolean restarting, boolean allowRestart, int index) {
16141        if (index >= 0) {
16142            removeLruProcessLocked(app);
16143            ProcessList.remove(app.pid);
16144        }
16145
16146        mProcessesToGc.remove(app);
16147        mPendingPssProcesses.remove(app);
16148
16149        // Dismiss any open dialogs.
16150        if (app.crashDialog != null && !app.forceCrashReport) {
16151            app.crashDialog.dismiss();
16152            app.crashDialog = null;
16153        }
16154        if (app.anrDialog != null) {
16155            app.anrDialog.dismiss();
16156            app.anrDialog = null;
16157        }
16158        if (app.waitDialog != null) {
16159            app.waitDialog.dismiss();
16160            app.waitDialog = null;
16161        }
16162
16163        app.crashing = false;
16164        app.notResponding = false;
16165
16166        app.resetPackageList(mProcessStats);
16167        app.unlinkDeathRecipient();
16168        app.makeInactive(mProcessStats);
16169        app.waitingToKill = null;
16170        app.forcingToForeground = null;
16171        updateProcessForegroundLocked(app, false, false);
16172        app.foregroundActivities = false;
16173        app.hasShownUi = false;
16174        app.treatLikeActivity = false;
16175        app.hasAboveClient = false;
16176        app.hasClientActivities = false;
16177
16178        mServices.killServicesLocked(app, allowRestart);
16179
16180        boolean restart = false;
16181
16182        // Remove published content providers.
16183        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16184            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16185            final boolean always = app.bad || !allowRestart;
16186            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16187            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16188                // We left the provider in the launching list, need to
16189                // restart it.
16190                restart = true;
16191            }
16192
16193            cpr.provider = null;
16194            cpr.proc = null;
16195        }
16196        app.pubProviders.clear();
16197
16198        // Take care of any launching providers waiting for this process.
16199        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16200            restart = true;
16201        }
16202
16203        // Unregister from connected content providers.
16204        if (!app.conProviders.isEmpty()) {
16205            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16206                ContentProviderConnection conn = app.conProviders.get(i);
16207                conn.provider.connections.remove(conn);
16208                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16209                        conn.provider.name);
16210            }
16211            app.conProviders.clear();
16212        }
16213
16214        // At this point there may be remaining entries in mLaunchingProviders
16215        // where we were the only one waiting, so they are no longer of use.
16216        // Look for these and clean up if found.
16217        // XXX Commented out for now.  Trying to figure out a way to reproduce
16218        // the actual situation to identify what is actually going on.
16219        if (false) {
16220            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16221                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16222                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16223                    synchronized (cpr) {
16224                        cpr.launchingApp = null;
16225                        cpr.notifyAll();
16226                    }
16227                }
16228            }
16229        }
16230
16231        skipCurrentReceiverLocked(app);
16232
16233        // Unregister any receivers.
16234        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16235            removeReceiverLocked(app.receivers.valueAt(i));
16236        }
16237        app.receivers.clear();
16238
16239        // If the app is undergoing backup, tell the backup manager about it
16240        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16241            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16242                    + mBackupTarget.appInfo + " died during backup");
16243            try {
16244                IBackupManager bm = IBackupManager.Stub.asInterface(
16245                        ServiceManager.getService(Context.BACKUP_SERVICE));
16246                bm.agentDisconnected(app.info.packageName);
16247            } catch (RemoteException e) {
16248                // can't happen; backup manager is local
16249            }
16250        }
16251
16252        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16253            ProcessChangeItem item = mPendingProcessChanges.get(i);
16254            if (item.pid == app.pid) {
16255                mPendingProcessChanges.remove(i);
16256                mAvailProcessChanges.add(item);
16257            }
16258        }
16259        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16260                null).sendToTarget();
16261
16262        // If the caller is restarting this app, then leave it in its
16263        // current lists and let the caller take care of it.
16264        if (restarting) {
16265            return false;
16266        }
16267
16268        if (!app.persistent || app.isolated) {
16269            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16270                    "Removing non-persistent process during cleanup: " + app);
16271            removeProcessNameLocked(app.processName, app.uid);
16272            if (mHeavyWeightProcess == app) {
16273                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16274                        mHeavyWeightProcess.userId, 0));
16275                mHeavyWeightProcess = null;
16276            }
16277        } else if (!app.removed) {
16278            // This app is persistent, so we need to keep its record around.
16279            // If it is not already on the pending app list, add it there
16280            // and start a new process for it.
16281            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16282                mPersistentStartingProcesses.add(app);
16283                restart = true;
16284            }
16285        }
16286        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16287                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16288        mProcessesOnHold.remove(app);
16289
16290        if (app == mHomeProcess) {
16291            mHomeProcess = null;
16292        }
16293        if (app == mPreviousProcess) {
16294            mPreviousProcess = null;
16295        }
16296
16297        if (restart && !app.isolated) {
16298            // We have components that still need to be running in the
16299            // process, so re-launch it.
16300            if (index < 0) {
16301                ProcessList.remove(app.pid);
16302            }
16303            addProcessNameLocked(app);
16304            startProcessLocked(app, "restart", app.processName);
16305            return true;
16306        } else if (app.pid > 0 && app.pid != MY_PID) {
16307            // Goodbye!
16308            boolean removed;
16309            synchronized (mPidsSelfLocked) {
16310                mPidsSelfLocked.remove(app.pid);
16311                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16312            }
16313            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16314            if (app.isolated) {
16315                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16316            }
16317            app.setPid(0);
16318        }
16319        return false;
16320    }
16321
16322    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16323        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16324            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16325            if (cpr.launchingApp == app) {
16326                return true;
16327            }
16328        }
16329        return false;
16330    }
16331
16332    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16333        // Look through the content providers we are waiting to have launched,
16334        // and if any run in this process then either schedule a restart of
16335        // the process or kill the client waiting for it if this process has
16336        // gone bad.
16337        boolean restart = false;
16338        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16339            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16340            if (cpr.launchingApp == app) {
16341                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16342                    restart = true;
16343                } else {
16344                    removeDyingProviderLocked(app, cpr, true);
16345                }
16346            }
16347        }
16348        return restart;
16349    }
16350
16351    // =========================================================
16352    // SERVICES
16353    // =========================================================
16354
16355    @Override
16356    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16357            int flags) {
16358        enforceNotIsolatedCaller("getServices");
16359        synchronized (this) {
16360            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16361        }
16362    }
16363
16364    @Override
16365    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16366        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16367        synchronized (this) {
16368            return mServices.getRunningServiceControlPanelLocked(name);
16369        }
16370    }
16371
16372    @Override
16373    public ComponentName startService(IApplicationThread caller, Intent service,
16374            String resolvedType, String callingPackage, int userId)
16375            throws TransactionTooLargeException {
16376        enforceNotIsolatedCaller("startService");
16377        // Refuse possible leaked file descriptors
16378        if (service != null && service.hasFileDescriptors() == true) {
16379            throw new IllegalArgumentException("File descriptors passed in Intent");
16380        }
16381
16382        if (callingPackage == null) {
16383            throw new IllegalArgumentException("callingPackage cannot be null");
16384        }
16385
16386        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16387                "startService: " + service + " type=" + resolvedType);
16388        synchronized(this) {
16389            final int callingPid = Binder.getCallingPid();
16390            final int callingUid = Binder.getCallingUid();
16391            final long origId = Binder.clearCallingIdentity();
16392            ComponentName res = mServices.startServiceLocked(caller, service,
16393                    resolvedType, callingPid, callingUid, callingPackage, userId);
16394            Binder.restoreCallingIdentity(origId);
16395            return res;
16396        }
16397    }
16398
16399    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16400            String callingPackage, int userId)
16401            throws TransactionTooLargeException {
16402        synchronized(this) {
16403            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16404                    "startServiceInPackage: " + service + " type=" + resolvedType);
16405            final long origId = Binder.clearCallingIdentity();
16406            ComponentName res = mServices.startServiceLocked(null, service,
16407                    resolvedType, -1, uid, callingPackage, userId);
16408            Binder.restoreCallingIdentity(origId);
16409            return res;
16410        }
16411    }
16412
16413    @Override
16414    public int stopService(IApplicationThread caller, Intent service,
16415            String resolvedType, int userId) {
16416        enforceNotIsolatedCaller("stopService");
16417        // Refuse possible leaked file descriptors
16418        if (service != null && service.hasFileDescriptors() == true) {
16419            throw new IllegalArgumentException("File descriptors passed in Intent");
16420        }
16421
16422        synchronized(this) {
16423            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16424        }
16425    }
16426
16427    @Override
16428    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16429        enforceNotIsolatedCaller("peekService");
16430        // Refuse possible leaked file descriptors
16431        if (service != null && service.hasFileDescriptors() == true) {
16432            throw new IllegalArgumentException("File descriptors passed in Intent");
16433        }
16434
16435        if (callingPackage == null) {
16436            throw new IllegalArgumentException("callingPackage cannot be null");
16437        }
16438
16439        synchronized(this) {
16440            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16441        }
16442    }
16443
16444    @Override
16445    public boolean stopServiceToken(ComponentName className, IBinder token,
16446            int startId) {
16447        synchronized(this) {
16448            return mServices.stopServiceTokenLocked(className, token, startId);
16449        }
16450    }
16451
16452    @Override
16453    public void setServiceForeground(ComponentName className, IBinder token,
16454            int id, Notification notification, boolean removeNotification) {
16455        synchronized(this) {
16456            mServices.setServiceForegroundLocked(className, token, id, notification,
16457                    removeNotification);
16458        }
16459    }
16460
16461    @Override
16462    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16463            boolean requireFull, String name, String callerPackage) {
16464        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16465                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16466    }
16467
16468    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16469            String className, int flags) {
16470        boolean result = false;
16471        // For apps that don't have pre-defined UIDs, check for permission
16472        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16473            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16474                if (ActivityManager.checkUidPermission(
16475                        INTERACT_ACROSS_USERS,
16476                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16477                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16478                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16479                            + " requests FLAG_SINGLE_USER, but app does not hold "
16480                            + INTERACT_ACROSS_USERS;
16481                    Slog.w(TAG, msg);
16482                    throw new SecurityException(msg);
16483                }
16484                // Permission passed
16485                result = true;
16486            }
16487        } else if ("system".equals(componentProcessName)) {
16488            result = true;
16489        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16490            // Phone app and persistent apps are allowed to export singleuser providers.
16491            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16492                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16493        }
16494        if (DEBUG_MU) Slog.v(TAG_MU,
16495                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16496                + Integer.toHexString(flags) + ") = " + result);
16497        return result;
16498    }
16499
16500    /**
16501     * Checks to see if the caller is in the same app as the singleton
16502     * component, or the component is in a special app. It allows special apps
16503     * to export singleton components but prevents exporting singleton
16504     * components for regular apps.
16505     */
16506    boolean isValidSingletonCall(int callingUid, int componentUid) {
16507        int componentAppId = UserHandle.getAppId(componentUid);
16508        return UserHandle.isSameApp(callingUid, componentUid)
16509                || componentAppId == Process.SYSTEM_UID
16510                || componentAppId == Process.PHONE_UID
16511                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16512                        == PackageManager.PERMISSION_GRANTED;
16513    }
16514
16515    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16516            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16517            int userId) throws TransactionTooLargeException {
16518        enforceNotIsolatedCaller("bindService");
16519
16520        // Refuse possible leaked file descriptors
16521        if (service != null && service.hasFileDescriptors() == true) {
16522            throw new IllegalArgumentException("File descriptors passed in Intent");
16523        }
16524
16525        if (callingPackage == null) {
16526            throw new IllegalArgumentException("callingPackage cannot be null");
16527        }
16528
16529        synchronized(this) {
16530            return mServices.bindServiceLocked(caller, token, service,
16531                    resolvedType, connection, flags, callingPackage, userId);
16532        }
16533    }
16534
16535    public boolean unbindService(IServiceConnection connection) {
16536        synchronized (this) {
16537            return mServices.unbindServiceLocked(connection);
16538        }
16539    }
16540
16541    public void publishService(IBinder token, Intent intent, IBinder service) {
16542        // Refuse possible leaked file descriptors
16543        if (intent != null && intent.hasFileDescriptors() == true) {
16544            throw new IllegalArgumentException("File descriptors passed in Intent");
16545        }
16546
16547        synchronized(this) {
16548            if (!(token instanceof ServiceRecord)) {
16549                throw new IllegalArgumentException("Invalid service token");
16550            }
16551            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16552        }
16553    }
16554
16555    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16556        // Refuse possible leaked file descriptors
16557        if (intent != null && intent.hasFileDescriptors() == true) {
16558            throw new IllegalArgumentException("File descriptors passed in Intent");
16559        }
16560
16561        synchronized(this) {
16562            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16563        }
16564    }
16565
16566    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16567        synchronized(this) {
16568            if (!(token instanceof ServiceRecord)) {
16569                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16570                throw new IllegalArgumentException("Invalid service token");
16571            }
16572            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16573        }
16574    }
16575
16576    // =========================================================
16577    // BACKUP AND RESTORE
16578    // =========================================================
16579
16580    // Cause the target app to be launched if necessary and its backup agent
16581    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16582    // activity manager to announce its creation.
16583    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16584        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16585                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16586        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16587
16588        synchronized(this) {
16589            // !!! TODO: currently no check here that we're already bound
16590            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16591            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16592            synchronized (stats) {
16593                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16594            }
16595
16596            // Backup agent is now in use, its package can't be stopped.
16597            try {
16598                AppGlobals.getPackageManager().setPackageStoppedState(
16599                        app.packageName, false, UserHandle.getUserId(app.uid));
16600            } catch (RemoteException e) {
16601            } catch (IllegalArgumentException e) {
16602                Slog.w(TAG, "Failed trying to unstop package "
16603                        + app.packageName + ": " + e);
16604            }
16605
16606            BackupRecord r = new BackupRecord(ss, app, backupMode);
16607            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16608                    ? new ComponentName(app.packageName, app.backupAgentName)
16609                    : new ComponentName("android", "FullBackupAgent");
16610            // startProcessLocked() returns existing proc's record if it's already running
16611            ProcessRecord proc = startProcessLocked(app.processName, app,
16612                    false, 0, "backup", hostingName, false, false, false);
16613            if (proc == null) {
16614                Slog.e(TAG, "Unable to start backup agent process " + r);
16615                return false;
16616            }
16617
16618            r.app = proc;
16619            mBackupTarget = r;
16620            mBackupAppName = app.packageName;
16621
16622            // Try not to kill the process during backup
16623            updateOomAdjLocked(proc);
16624
16625            // If the process is already attached, schedule the creation of the backup agent now.
16626            // If it is not yet live, this will be done when it attaches to the framework.
16627            if (proc.thread != null) {
16628                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16629                try {
16630                    proc.thread.scheduleCreateBackupAgent(app,
16631                            compatibilityInfoForPackageLocked(app), backupMode);
16632                } catch (RemoteException e) {
16633                    // Will time out on the backup manager side
16634                }
16635            } else {
16636                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16637            }
16638            // Invariants: at this point, the target app process exists and the application
16639            // is either already running or in the process of coming up.  mBackupTarget and
16640            // mBackupAppName describe the app, so that when it binds back to the AM we
16641            // know that it's scheduled for a backup-agent operation.
16642        }
16643
16644        return true;
16645    }
16646
16647    @Override
16648    public void clearPendingBackup() {
16649        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16650        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16651
16652        synchronized (this) {
16653            mBackupTarget = null;
16654            mBackupAppName = null;
16655        }
16656    }
16657
16658    // A backup agent has just come up
16659    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16660        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16661                + " = " + agent);
16662
16663        synchronized(this) {
16664            if (!agentPackageName.equals(mBackupAppName)) {
16665                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16666                return;
16667            }
16668        }
16669
16670        long oldIdent = Binder.clearCallingIdentity();
16671        try {
16672            IBackupManager bm = IBackupManager.Stub.asInterface(
16673                    ServiceManager.getService(Context.BACKUP_SERVICE));
16674            bm.agentConnected(agentPackageName, agent);
16675        } catch (RemoteException e) {
16676            // can't happen; the backup manager service is local
16677        } catch (Exception e) {
16678            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16679            e.printStackTrace();
16680        } finally {
16681            Binder.restoreCallingIdentity(oldIdent);
16682        }
16683    }
16684
16685    // done with this agent
16686    public void unbindBackupAgent(ApplicationInfo appInfo) {
16687        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16688        if (appInfo == null) {
16689            Slog.w(TAG, "unbind backup agent for null app");
16690            return;
16691        }
16692
16693        synchronized(this) {
16694            try {
16695                if (mBackupAppName == null) {
16696                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16697                    return;
16698                }
16699
16700                if (!mBackupAppName.equals(appInfo.packageName)) {
16701                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16702                    return;
16703                }
16704
16705                // Not backing this app up any more; reset its OOM adjustment
16706                final ProcessRecord proc = mBackupTarget.app;
16707                updateOomAdjLocked(proc);
16708
16709                // If the app crashed during backup, 'thread' will be null here
16710                if (proc.thread != null) {
16711                    try {
16712                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16713                                compatibilityInfoForPackageLocked(appInfo));
16714                    } catch (Exception e) {
16715                        Slog.e(TAG, "Exception when unbinding backup agent:");
16716                        e.printStackTrace();
16717                    }
16718                }
16719            } finally {
16720                mBackupTarget = null;
16721                mBackupAppName = null;
16722            }
16723        }
16724    }
16725    // =========================================================
16726    // BROADCASTS
16727    // =========================================================
16728
16729    boolean isPendingBroadcastProcessLocked(int pid) {
16730        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16731                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16732    }
16733
16734    void skipPendingBroadcastLocked(int pid) {
16735            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16736            for (BroadcastQueue queue : mBroadcastQueues) {
16737                queue.skipPendingBroadcastLocked(pid);
16738            }
16739    }
16740
16741    // The app just attached; send any pending broadcasts that it should receive
16742    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16743        boolean didSomething = false;
16744        for (BroadcastQueue queue : mBroadcastQueues) {
16745            didSomething |= queue.sendPendingBroadcastsLocked(app);
16746        }
16747        return didSomething;
16748    }
16749
16750    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16751            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16752        enforceNotIsolatedCaller("registerReceiver");
16753        ArrayList<Intent> stickyIntents = null;
16754        ProcessRecord callerApp = null;
16755        int callingUid;
16756        int callingPid;
16757        synchronized(this) {
16758            if (caller != null) {
16759                callerApp = getRecordForAppLocked(caller);
16760                if (callerApp == null) {
16761                    throw new SecurityException(
16762                            "Unable to find app for caller " + caller
16763                            + " (pid=" + Binder.getCallingPid()
16764                            + ") when registering receiver " + receiver);
16765                }
16766                if (callerApp.info.uid != Process.SYSTEM_UID &&
16767                        !callerApp.pkgList.containsKey(callerPackage) &&
16768                        !"android".equals(callerPackage)) {
16769                    throw new SecurityException("Given caller package " + callerPackage
16770                            + " is not running in process " + callerApp);
16771                }
16772                callingUid = callerApp.info.uid;
16773                callingPid = callerApp.pid;
16774            } else {
16775                callerPackage = null;
16776                callingUid = Binder.getCallingUid();
16777                callingPid = Binder.getCallingPid();
16778            }
16779
16780            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16781                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16782
16783            Iterator<String> actions = filter.actionsIterator();
16784            if (actions == null) {
16785                ArrayList<String> noAction = new ArrayList<String>(1);
16786                noAction.add(null);
16787                actions = noAction.iterator();
16788            }
16789
16790            // Collect stickies of users
16791            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16792            while (actions.hasNext()) {
16793                String action = actions.next();
16794                for (int id : userIds) {
16795                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16796                    if (stickies != null) {
16797                        ArrayList<Intent> intents = stickies.get(action);
16798                        if (intents != null) {
16799                            if (stickyIntents == null) {
16800                                stickyIntents = new ArrayList<Intent>();
16801                            }
16802                            stickyIntents.addAll(intents);
16803                        }
16804                    }
16805                }
16806            }
16807        }
16808
16809        ArrayList<Intent> allSticky = null;
16810        if (stickyIntents != null) {
16811            final ContentResolver resolver = mContext.getContentResolver();
16812            // Look for any matching sticky broadcasts...
16813            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16814                Intent intent = stickyIntents.get(i);
16815                // If intent has scheme "content", it will need to acccess
16816                // provider that needs to lock mProviderMap in ActivityThread
16817                // and also it may need to wait application response, so we
16818                // cannot lock ActivityManagerService here.
16819                if (filter.match(resolver, intent, true, TAG) >= 0) {
16820                    if (allSticky == null) {
16821                        allSticky = new ArrayList<Intent>();
16822                    }
16823                    allSticky.add(intent);
16824                }
16825            }
16826        }
16827
16828        // The first sticky in the list is returned directly back to the client.
16829        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16830        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16831        if (receiver == null) {
16832            return sticky;
16833        }
16834
16835        synchronized (this) {
16836            if (callerApp != null && (callerApp.thread == null
16837                    || callerApp.thread.asBinder() != caller.asBinder())) {
16838                // Original caller already died
16839                return null;
16840            }
16841            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16842            if (rl == null) {
16843                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16844                        userId, receiver);
16845                if (rl.app != null) {
16846                    rl.app.receivers.add(rl);
16847                } else {
16848                    try {
16849                        receiver.asBinder().linkToDeath(rl, 0);
16850                    } catch (RemoteException e) {
16851                        return sticky;
16852                    }
16853                    rl.linkedToDeath = true;
16854                }
16855                mRegisteredReceivers.put(receiver.asBinder(), rl);
16856            } else if (rl.uid != callingUid) {
16857                throw new IllegalArgumentException(
16858                        "Receiver requested to register for uid " + callingUid
16859                        + " was previously registered for uid " + rl.uid);
16860            } else if (rl.pid != callingPid) {
16861                throw new IllegalArgumentException(
16862                        "Receiver requested to register for pid " + callingPid
16863                        + " was previously registered for pid " + rl.pid);
16864            } else if (rl.userId != userId) {
16865                throw new IllegalArgumentException(
16866                        "Receiver requested to register for user " + userId
16867                        + " was previously registered for user " + rl.userId);
16868            }
16869            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16870                    permission, callingUid, userId);
16871            rl.add(bf);
16872            if (!bf.debugCheck()) {
16873                Slog.w(TAG, "==> For Dynamic broadcast");
16874            }
16875            mReceiverResolver.addFilter(bf);
16876
16877            // Enqueue broadcasts for all existing stickies that match
16878            // this filter.
16879            if (allSticky != null) {
16880                ArrayList receivers = new ArrayList();
16881                receivers.add(bf);
16882
16883                final int stickyCount = allSticky.size();
16884                for (int i = 0; i < stickyCount; i++) {
16885                    Intent intent = allSticky.get(i);
16886                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16887                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16888                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16889                            null, 0, null, null, false, true, true, -1);
16890                    queue.enqueueParallelBroadcastLocked(r);
16891                    queue.scheduleBroadcastsLocked();
16892                }
16893            }
16894
16895            return sticky;
16896        }
16897    }
16898
16899    public void unregisterReceiver(IIntentReceiver receiver) {
16900        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16901
16902        final long origId = Binder.clearCallingIdentity();
16903        try {
16904            boolean doTrim = false;
16905
16906            synchronized(this) {
16907                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16908                if (rl != null) {
16909                    final BroadcastRecord r = rl.curBroadcast;
16910                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16911                        final boolean doNext = r.queue.finishReceiverLocked(
16912                                r, r.resultCode, r.resultData, r.resultExtras,
16913                                r.resultAbort, false);
16914                        if (doNext) {
16915                            doTrim = true;
16916                            r.queue.processNextBroadcast(false);
16917                        }
16918                    }
16919
16920                    if (rl.app != null) {
16921                        rl.app.receivers.remove(rl);
16922                    }
16923                    removeReceiverLocked(rl);
16924                    if (rl.linkedToDeath) {
16925                        rl.linkedToDeath = false;
16926                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16927                    }
16928                }
16929            }
16930
16931            // If we actually concluded any broadcasts, we might now be able
16932            // to trim the recipients' apps from our working set
16933            if (doTrim) {
16934                trimApplications();
16935                return;
16936            }
16937
16938        } finally {
16939            Binder.restoreCallingIdentity(origId);
16940        }
16941    }
16942
16943    void removeReceiverLocked(ReceiverList rl) {
16944        mRegisteredReceivers.remove(rl.receiver.asBinder());
16945        for (int i = rl.size() - 1; i >= 0; i--) {
16946            mReceiverResolver.removeFilter(rl.get(i));
16947        }
16948    }
16949
16950    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16951        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16952            ProcessRecord r = mLruProcesses.get(i);
16953            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16954                try {
16955                    r.thread.dispatchPackageBroadcast(cmd, packages);
16956                } catch (RemoteException ex) {
16957                }
16958            }
16959        }
16960    }
16961
16962    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16963            int callingUid, int[] users) {
16964        // TODO: come back and remove this assumption to triage all broadcasts
16965        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16966
16967        List<ResolveInfo> receivers = null;
16968        try {
16969            HashSet<ComponentName> singleUserReceivers = null;
16970            boolean scannedFirstReceivers = false;
16971            for (int user : users) {
16972                // Skip users that have Shell restrictions, with exception of always permitted
16973                // Shell broadcasts
16974                if (callingUid == Process.SHELL_UID
16975                        && mUserController.hasUserRestriction(
16976                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16977                        && !isPermittedShellBroadcast(intent)) {
16978                    continue;
16979                }
16980                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16981                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16982                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16983                    // If this is not the system user, we need to check for
16984                    // any receivers that should be filtered out.
16985                    for (int i=0; i<newReceivers.size(); i++) {
16986                        ResolveInfo ri = newReceivers.get(i);
16987                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16988                            newReceivers.remove(i);
16989                            i--;
16990                        }
16991                    }
16992                }
16993                if (newReceivers != null && newReceivers.size() == 0) {
16994                    newReceivers = null;
16995                }
16996                if (receivers == null) {
16997                    receivers = newReceivers;
16998                } else if (newReceivers != null) {
16999                    // We need to concatenate the additional receivers
17000                    // found with what we have do far.  This would be easy,
17001                    // but we also need to de-dup any receivers that are
17002                    // singleUser.
17003                    if (!scannedFirstReceivers) {
17004                        // Collect any single user receivers we had already retrieved.
17005                        scannedFirstReceivers = true;
17006                        for (int i=0; i<receivers.size(); i++) {
17007                            ResolveInfo ri = receivers.get(i);
17008                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17009                                ComponentName cn = new ComponentName(
17010                                        ri.activityInfo.packageName, ri.activityInfo.name);
17011                                if (singleUserReceivers == null) {
17012                                    singleUserReceivers = new HashSet<ComponentName>();
17013                                }
17014                                singleUserReceivers.add(cn);
17015                            }
17016                        }
17017                    }
17018                    // Add the new results to the existing results, tracking
17019                    // and de-dupping single user receivers.
17020                    for (int i=0; i<newReceivers.size(); i++) {
17021                        ResolveInfo ri = newReceivers.get(i);
17022                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17023                            ComponentName cn = new ComponentName(
17024                                    ri.activityInfo.packageName, ri.activityInfo.name);
17025                            if (singleUserReceivers == null) {
17026                                singleUserReceivers = new HashSet<ComponentName>();
17027                            }
17028                            if (!singleUserReceivers.contains(cn)) {
17029                                singleUserReceivers.add(cn);
17030                                receivers.add(ri);
17031                            }
17032                        } else {
17033                            receivers.add(ri);
17034                        }
17035                    }
17036                }
17037            }
17038        } catch (RemoteException ex) {
17039            // pm is in same process, this will never happen.
17040        }
17041        return receivers;
17042    }
17043
17044    private boolean isPermittedShellBroadcast(Intent intent) {
17045        // remote bugreport should always be allowed to be taken
17046        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17047    }
17048
17049    final int broadcastIntentLocked(ProcessRecord callerApp,
17050            String callerPackage, Intent intent, String resolvedType,
17051            IIntentReceiver resultTo, int resultCode, String resultData,
17052            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17053            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17054        intent = new Intent(intent);
17055
17056        // By default broadcasts do not go to stopped apps.
17057        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17058
17059        // If we have not finished booting, don't allow this to launch new processes.
17060        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17061            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17062        }
17063
17064        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17065                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17066                + " ordered=" + ordered + " userid=" + userId);
17067        if ((resultTo != null) && !ordered) {
17068            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17069        }
17070
17071        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17072                ALLOW_NON_FULL, "broadcast", callerPackage);
17073
17074        // Make sure that the user who is receiving this broadcast is running.
17075        // If not, we will just skip it. Make an exception for shutdown broadcasts
17076        // and upgrade steps.
17077
17078        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17079            if ((callingUid != Process.SYSTEM_UID
17080                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17081                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17082                Slog.w(TAG, "Skipping broadcast of " + intent
17083                        + ": user " + userId + " is stopped");
17084                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17085            }
17086        }
17087
17088        BroadcastOptions brOptions = null;
17089        if (bOptions != null) {
17090            brOptions = new BroadcastOptions(bOptions);
17091            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17092                // See if the caller is allowed to do this.  Note we are checking against
17093                // the actual real caller (not whoever provided the operation as say a
17094                // PendingIntent), because that who is actually supplied the arguments.
17095                if (checkComponentPermission(
17096                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17097                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17098                        != PackageManager.PERMISSION_GRANTED) {
17099                    String msg = "Permission Denial: " + intent.getAction()
17100                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17101                            + ", uid=" + callingUid + ")"
17102                            + " requires "
17103                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17104                    Slog.w(TAG, msg);
17105                    throw new SecurityException(msg);
17106                }
17107            }
17108        }
17109
17110        // Verify that protected broadcasts are only being sent by system code,
17111        // and that system code is only sending protected broadcasts.
17112        final String action = intent.getAction();
17113        final boolean isProtectedBroadcast;
17114        try {
17115            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17116        } catch (RemoteException e) {
17117            Slog.w(TAG, "Remote exception", e);
17118            return ActivityManager.BROADCAST_SUCCESS;
17119        }
17120
17121        final boolean isCallerSystem;
17122        switch (UserHandle.getAppId(callingUid)) {
17123            case Process.ROOT_UID:
17124            case Process.SYSTEM_UID:
17125            case Process.PHONE_UID:
17126            case Process.BLUETOOTH_UID:
17127            case Process.NFC_UID:
17128                isCallerSystem = true;
17129                break;
17130            default:
17131                isCallerSystem = (callerApp != null) && callerApp.persistent;
17132                break;
17133        }
17134
17135        if (isCallerSystem) {
17136            if (isProtectedBroadcast
17137                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17138                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17139                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17140                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17141                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17142                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17143                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17144                // Broadcast is either protected, or it's a public action that
17145                // we've relaxed, so it's fine for system internals to send.
17146            } else {
17147                // The vast majority of broadcasts sent from system internals
17148                // should be protected to avoid security holes, so yell loudly
17149                // to ensure we examine these cases.
17150                Log.wtf(TAG, "Sending non-protected broadcast " + action
17151                        + " from system", new Throwable());
17152            }
17153
17154        } else {
17155            if (isProtectedBroadcast) {
17156                String msg = "Permission Denial: not allowed to send broadcast "
17157                        + action + " from pid="
17158                        + callingPid + ", uid=" + callingUid;
17159                Slog.w(TAG, msg);
17160                throw new SecurityException(msg);
17161
17162            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17163                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17164                // Special case for compatibility: we don't want apps to send this,
17165                // but historically it has not been protected and apps may be using it
17166                // to poke their own app widget.  So, instead of making it protected,
17167                // just limit it to the caller.
17168                if (callerPackage == null) {
17169                    String msg = "Permission Denial: not allowed to send broadcast "
17170                            + action + " from unknown caller.";
17171                    Slog.w(TAG, msg);
17172                    throw new SecurityException(msg);
17173                } else if (intent.getComponent() != null) {
17174                    // They are good enough to send to an explicit component...  verify
17175                    // it is being sent to the calling app.
17176                    if (!intent.getComponent().getPackageName().equals(
17177                            callerPackage)) {
17178                        String msg = "Permission Denial: not allowed to send broadcast "
17179                                + action + " to "
17180                                + intent.getComponent().getPackageName() + " from "
17181                                + callerPackage;
17182                        Slog.w(TAG, msg);
17183                        throw new SecurityException(msg);
17184                    }
17185                } else {
17186                    // Limit broadcast to their own package.
17187                    intent.setPackage(callerPackage);
17188                }
17189            }
17190        }
17191
17192        if (action != null) {
17193            switch (action) {
17194                case Intent.ACTION_UID_REMOVED:
17195                case Intent.ACTION_PACKAGE_REMOVED:
17196                case Intent.ACTION_PACKAGE_CHANGED:
17197                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17198                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17199                case Intent.ACTION_PACKAGES_SUSPENDED:
17200                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17201                    // Handle special intents: if this broadcast is from the package
17202                    // manager about a package being removed, we need to remove all of
17203                    // its activities from the history stack.
17204                    if (checkComponentPermission(
17205                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17206                            callingPid, callingUid, -1, true)
17207                            != PackageManager.PERMISSION_GRANTED) {
17208                        String msg = "Permission Denial: " + intent.getAction()
17209                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17210                                + ", uid=" + callingUid + ")"
17211                                + " requires "
17212                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17213                        Slog.w(TAG, msg);
17214                        throw new SecurityException(msg);
17215                    }
17216                    switch (action) {
17217                        case Intent.ACTION_UID_REMOVED:
17218                            final Bundle intentExtras = intent.getExtras();
17219                            final int uid = intentExtras != null
17220                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17221                            if (uid >= 0) {
17222                                mBatteryStatsService.removeUid(uid);
17223                                mAppOpsService.uidRemoved(uid);
17224                            }
17225                            break;
17226                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17227                            // If resources are unavailable just force stop all those packages
17228                            // and flush the attribute cache as well.
17229                            String list[] =
17230                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17231                            if (list != null && list.length > 0) {
17232                                for (int i = 0; i < list.length; i++) {
17233                                    forceStopPackageLocked(list[i], -1, false, true, true,
17234                                            false, false, userId, "storage unmount");
17235                                }
17236                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17237                                sendPackageBroadcastLocked(
17238                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17239                                        userId);
17240                            }
17241                            break;
17242                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17243                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17244                            break;
17245                        case Intent.ACTION_PACKAGE_REMOVED:
17246                        case Intent.ACTION_PACKAGE_CHANGED:
17247                            Uri data = intent.getData();
17248                            String ssp;
17249                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17250                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17251                                final boolean replacing =
17252                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17253                                final boolean killProcess =
17254                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17255                                final boolean fullUninstall = removed && !replacing;
17256                                if (killProcess) {
17257                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17258                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17259                                            false, true, true, false, fullUninstall, userId,
17260                                            removed ? "pkg removed" : "pkg changed");
17261                                }
17262                                if (removed) {
17263                                    final int cmd = killProcess
17264                                            ? IApplicationThread.PACKAGE_REMOVED
17265                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17266                                    sendPackageBroadcastLocked(cmd,
17267                                            new String[] {ssp}, userId);
17268                                    if (fullUninstall) {
17269                                        mAppOpsService.packageRemoved(
17270                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17271
17272                                        // Remove all permissions granted from/to this package
17273                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17274
17275                                        removeTasksByPackageNameLocked(ssp, userId);
17276                                        mBatteryStatsService.notePackageUninstalled(ssp);
17277                                    }
17278                                } else {
17279                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17280                                            intent.getStringArrayExtra(
17281                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17282                                }
17283                            }
17284                            break;
17285                        case Intent.ACTION_PACKAGES_SUSPENDED:
17286                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17287                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17288                                    intent.getAction());
17289                            final String[] packageNames = intent.getStringArrayExtra(
17290                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17291                            final int userHandle = intent.getIntExtra(
17292                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17293
17294                            synchronized(ActivityManagerService.this) {
17295                                mRecentTasks.onPackagesSuspendedChanged(
17296                                        packageNames, suspended, userHandle);
17297                            }
17298                            break;
17299                    }
17300                    break;
17301                case Intent.ACTION_PACKAGE_REPLACED:
17302                {
17303                    final Uri data = intent.getData();
17304                    final String ssp;
17305                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17306                        final ApplicationInfo aInfo =
17307                                getPackageManagerInternalLocked().getApplicationInfo(
17308                                        ssp,
17309                                        userId);
17310                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17311                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17312                                new String[] {ssp}, userId);
17313                    }
17314                    break;
17315                }
17316                case Intent.ACTION_PACKAGE_ADDED:
17317                {
17318                    // Special case for adding a package: by default turn on compatibility mode.
17319                    Uri data = intent.getData();
17320                    String ssp;
17321                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17322                        final boolean replacing =
17323                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17324                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17325
17326                        try {
17327                            ApplicationInfo ai = AppGlobals.getPackageManager().
17328                                    getApplicationInfo(ssp, 0, 0);
17329                            mBatteryStatsService.notePackageInstalled(ssp,
17330                                    ai != null ? ai.versionCode : 0);
17331                        } catch (RemoteException e) {
17332                        }
17333                    }
17334                    break;
17335                }
17336                case Intent.ACTION_TIMEZONE_CHANGED:
17337                    // If this is the time zone changed action, queue up a message that will reset
17338                    // the timezone of all currently running processes. This message will get
17339                    // queued up before the broadcast happens.
17340                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17341                    break;
17342                case Intent.ACTION_TIME_CHANGED:
17343                    // If the user set the time, let all running processes know.
17344                    final int is24Hour =
17345                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17346                                    : 0;
17347                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17348                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17349                    synchronized (stats) {
17350                        stats.noteCurrentTimeChangedLocked();
17351                    }
17352                    break;
17353                case Intent.ACTION_CLEAR_DNS_CACHE:
17354                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17355                    break;
17356                case Proxy.PROXY_CHANGE_ACTION:
17357                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17358                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17359                    break;
17360                case android.hardware.Camera.ACTION_NEW_PICTURE:
17361                case android.hardware.Camera.ACTION_NEW_VIDEO:
17362                    // These broadcasts are no longer allowed by the system, since they can
17363                    // cause significant thrashing at a crictical point (using the camera).
17364                    // Apps should use JobScehduler to monitor for media provider changes.
17365                    Slog.w(TAG, action + " no longer allowed; dropping from "
17366                            + UserHandle.formatUid(callingUid));
17367                    // Lie; we don't want to crash the app.
17368                    return ActivityManager.BROADCAST_SUCCESS;
17369            }
17370        }
17371
17372        // Add to the sticky list if requested.
17373        if (sticky) {
17374            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17375                    callingPid, callingUid)
17376                    != PackageManager.PERMISSION_GRANTED) {
17377                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17378                        + callingPid + ", uid=" + callingUid
17379                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17380                Slog.w(TAG, msg);
17381                throw new SecurityException(msg);
17382            }
17383            if (requiredPermissions != null && requiredPermissions.length > 0) {
17384                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17385                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17386                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17387            }
17388            if (intent.getComponent() != null) {
17389                throw new SecurityException(
17390                        "Sticky broadcasts can't target a specific component");
17391            }
17392            // We use userId directly here, since the "all" target is maintained
17393            // as a separate set of sticky broadcasts.
17394            if (userId != UserHandle.USER_ALL) {
17395                // But first, if this is not a broadcast to all users, then
17396                // make sure it doesn't conflict with an existing broadcast to
17397                // all users.
17398                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17399                        UserHandle.USER_ALL);
17400                if (stickies != null) {
17401                    ArrayList<Intent> list = stickies.get(intent.getAction());
17402                    if (list != null) {
17403                        int N = list.size();
17404                        int i;
17405                        for (i=0; i<N; i++) {
17406                            if (intent.filterEquals(list.get(i))) {
17407                                throw new IllegalArgumentException(
17408                                        "Sticky broadcast " + intent + " for user "
17409                                        + userId + " conflicts with existing global broadcast");
17410                            }
17411                        }
17412                    }
17413                }
17414            }
17415            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17416            if (stickies == null) {
17417                stickies = new ArrayMap<>();
17418                mStickyBroadcasts.put(userId, stickies);
17419            }
17420            ArrayList<Intent> list = stickies.get(intent.getAction());
17421            if (list == null) {
17422                list = new ArrayList<>();
17423                stickies.put(intent.getAction(), list);
17424            }
17425            final int stickiesCount = list.size();
17426            int i;
17427            for (i = 0; i < stickiesCount; i++) {
17428                if (intent.filterEquals(list.get(i))) {
17429                    // This sticky already exists, replace it.
17430                    list.set(i, new Intent(intent));
17431                    break;
17432                }
17433            }
17434            if (i >= stickiesCount) {
17435                list.add(new Intent(intent));
17436            }
17437        }
17438
17439        int[] users;
17440        if (userId == UserHandle.USER_ALL) {
17441            // Caller wants broadcast to go to all started users.
17442            users = mUserController.getStartedUserArrayLocked();
17443        } else {
17444            // Caller wants broadcast to go to one specific user.
17445            users = new int[] {userId};
17446        }
17447
17448        // Figure out who all will receive this broadcast.
17449        List receivers = null;
17450        List<BroadcastFilter> registeredReceivers = null;
17451        // Need to resolve the intent to interested receivers...
17452        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17453                 == 0) {
17454            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17455        }
17456        if (intent.getComponent() == null) {
17457            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17458                // Query one target user at a time, excluding shell-restricted users
17459                for (int i = 0; i < users.length; i++) {
17460                    if (mUserController.hasUserRestriction(
17461                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17462                        continue;
17463                    }
17464                    List<BroadcastFilter> registeredReceiversForUser =
17465                            mReceiverResolver.queryIntent(intent,
17466                                    resolvedType, false, users[i]);
17467                    if (registeredReceivers == null) {
17468                        registeredReceivers = registeredReceiversForUser;
17469                    } else if (registeredReceiversForUser != null) {
17470                        registeredReceivers.addAll(registeredReceiversForUser);
17471                    }
17472                }
17473            } else {
17474                registeredReceivers = mReceiverResolver.queryIntent(intent,
17475                        resolvedType, false, userId);
17476            }
17477        }
17478
17479        final boolean replacePending =
17480                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17481
17482        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17483                + " replacePending=" + replacePending);
17484
17485        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17486        if (!ordered && NR > 0) {
17487            // If we are not serializing this broadcast, then send the
17488            // registered receivers separately so they don't wait for the
17489            // components to be launched.
17490            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17491            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17492                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17493                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17494                    resultExtras, ordered, sticky, false, userId);
17495            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17496            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17497            if (!replaced) {
17498                queue.enqueueParallelBroadcastLocked(r);
17499                queue.scheduleBroadcastsLocked();
17500            }
17501            registeredReceivers = null;
17502            NR = 0;
17503        }
17504
17505        // Merge into one list.
17506        int ir = 0;
17507        if (receivers != null) {
17508            // A special case for PACKAGE_ADDED: do not allow the package
17509            // being added to see this broadcast.  This prevents them from
17510            // using this as a back door to get run as soon as they are
17511            // installed.  Maybe in the future we want to have a special install
17512            // broadcast or such for apps, but we'd like to deliberately make
17513            // this decision.
17514            String skipPackages[] = null;
17515            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17516                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17517                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17518                Uri data = intent.getData();
17519                if (data != null) {
17520                    String pkgName = data.getSchemeSpecificPart();
17521                    if (pkgName != null) {
17522                        skipPackages = new String[] { pkgName };
17523                    }
17524                }
17525            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17526                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17527            }
17528            if (skipPackages != null && (skipPackages.length > 0)) {
17529                for (String skipPackage : skipPackages) {
17530                    if (skipPackage != null) {
17531                        int NT = receivers.size();
17532                        for (int it=0; it<NT; it++) {
17533                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17534                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17535                                receivers.remove(it);
17536                                it--;
17537                                NT--;
17538                            }
17539                        }
17540                    }
17541                }
17542            }
17543
17544            int NT = receivers != null ? receivers.size() : 0;
17545            int it = 0;
17546            ResolveInfo curt = null;
17547            BroadcastFilter curr = null;
17548            while (it < NT && ir < NR) {
17549                if (curt == null) {
17550                    curt = (ResolveInfo)receivers.get(it);
17551                }
17552                if (curr == null) {
17553                    curr = registeredReceivers.get(ir);
17554                }
17555                if (curr.getPriority() >= curt.priority) {
17556                    // Insert this broadcast record into the final list.
17557                    receivers.add(it, curr);
17558                    ir++;
17559                    curr = null;
17560                    it++;
17561                    NT++;
17562                } else {
17563                    // Skip to the next ResolveInfo in the final list.
17564                    it++;
17565                    curt = null;
17566                }
17567            }
17568        }
17569        while (ir < NR) {
17570            if (receivers == null) {
17571                receivers = new ArrayList();
17572            }
17573            receivers.add(registeredReceivers.get(ir));
17574            ir++;
17575        }
17576
17577        if ((receivers != null && receivers.size() > 0)
17578                || resultTo != null) {
17579            BroadcastQueue queue = broadcastQueueForIntent(intent);
17580            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17581                    callerPackage, callingPid, callingUid, resolvedType,
17582                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17583                    resultData, resultExtras, ordered, sticky, false, userId);
17584
17585            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17586                    + ": prev had " + queue.mOrderedBroadcasts.size());
17587            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17588                    "Enqueueing broadcast " + r.intent.getAction());
17589
17590            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17591            if (!replaced) {
17592                queue.enqueueOrderedBroadcastLocked(r);
17593                queue.scheduleBroadcastsLocked();
17594            }
17595        }
17596
17597        return ActivityManager.BROADCAST_SUCCESS;
17598    }
17599
17600    final Intent verifyBroadcastLocked(Intent intent) {
17601        // Refuse possible leaked file descriptors
17602        if (intent != null && intent.hasFileDescriptors() == true) {
17603            throw new IllegalArgumentException("File descriptors passed in Intent");
17604        }
17605
17606        int flags = intent.getFlags();
17607
17608        if (!mProcessesReady) {
17609            // if the caller really truly claims to know what they're doing, go
17610            // ahead and allow the broadcast without launching any receivers
17611            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17612                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17613            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17614                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17615                        + " before boot completion");
17616                throw new IllegalStateException("Cannot broadcast before boot completed");
17617            }
17618        }
17619
17620        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17621            throw new IllegalArgumentException(
17622                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17623        }
17624
17625        return intent;
17626    }
17627
17628    public final int broadcastIntent(IApplicationThread caller,
17629            Intent intent, String resolvedType, IIntentReceiver resultTo,
17630            int resultCode, String resultData, Bundle resultExtras,
17631            String[] requiredPermissions, int appOp, Bundle bOptions,
17632            boolean serialized, boolean sticky, int userId) {
17633        enforceNotIsolatedCaller("broadcastIntent");
17634        synchronized(this) {
17635            intent = verifyBroadcastLocked(intent);
17636
17637            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17638            final int callingPid = Binder.getCallingPid();
17639            final int callingUid = Binder.getCallingUid();
17640            final long origId = Binder.clearCallingIdentity();
17641            int res = broadcastIntentLocked(callerApp,
17642                    callerApp != null ? callerApp.info.packageName : null,
17643                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17644                    requiredPermissions, appOp, bOptions, serialized, sticky,
17645                    callingPid, callingUid, userId);
17646            Binder.restoreCallingIdentity(origId);
17647            return res;
17648        }
17649    }
17650
17651
17652    int broadcastIntentInPackage(String packageName, int uid,
17653            Intent intent, String resolvedType, IIntentReceiver resultTo,
17654            int resultCode, String resultData, Bundle resultExtras,
17655            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17656            int userId) {
17657        synchronized(this) {
17658            intent = verifyBroadcastLocked(intent);
17659
17660            final long origId = Binder.clearCallingIdentity();
17661            String[] requiredPermissions = requiredPermission == null ? null
17662                    : new String[] {requiredPermission};
17663            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17664                    resultTo, resultCode, resultData, resultExtras,
17665                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17666                    sticky, -1, uid, userId);
17667            Binder.restoreCallingIdentity(origId);
17668            return res;
17669        }
17670    }
17671
17672    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17673        // Refuse possible leaked file descriptors
17674        if (intent != null && intent.hasFileDescriptors() == true) {
17675            throw new IllegalArgumentException("File descriptors passed in Intent");
17676        }
17677
17678        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17679                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17680
17681        synchronized(this) {
17682            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17683                    != PackageManager.PERMISSION_GRANTED) {
17684                String msg = "Permission Denial: unbroadcastIntent() from pid="
17685                        + Binder.getCallingPid()
17686                        + ", uid=" + Binder.getCallingUid()
17687                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17688                Slog.w(TAG, msg);
17689                throw new SecurityException(msg);
17690            }
17691            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17692            if (stickies != null) {
17693                ArrayList<Intent> list = stickies.get(intent.getAction());
17694                if (list != null) {
17695                    int N = list.size();
17696                    int i;
17697                    for (i=0; i<N; i++) {
17698                        if (intent.filterEquals(list.get(i))) {
17699                            list.remove(i);
17700                            break;
17701                        }
17702                    }
17703                    if (list.size() <= 0) {
17704                        stickies.remove(intent.getAction());
17705                    }
17706                }
17707                if (stickies.size() <= 0) {
17708                    mStickyBroadcasts.remove(userId);
17709                }
17710            }
17711        }
17712    }
17713
17714    void backgroundServicesFinishedLocked(int userId) {
17715        for (BroadcastQueue queue : mBroadcastQueues) {
17716            queue.backgroundServicesFinishedLocked(userId);
17717        }
17718    }
17719
17720    public void finishReceiver(IBinder who, int resultCode, String resultData,
17721            Bundle resultExtras, boolean resultAbort, int flags) {
17722        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17723
17724        // Refuse possible leaked file descriptors
17725        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17726            throw new IllegalArgumentException("File descriptors passed in Bundle");
17727        }
17728
17729        final long origId = Binder.clearCallingIdentity();
17730        try {
17731            boolean doNext = false;
17732            BroadcastRecord r;
17733
17734            synchronized(this) {
17735                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17736                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17737                r = queue.getMatchingOrderedReceiver(who);
17738                if (r != null) {
17739                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17740                        resultData, resultExtras, resultAbort, true);
17741                }
17742            }
17743
17744            if (doNext) {
17745                r.queue.processNextBroadcast(false);
17746            }
17747            trimApplications();
17748        } finally {
17749            Binder.restoreCallingIdentity(origId);
17750        }
17751    }
17752
17753    // =========================================================
17754    // INSTRUMENTATION
17755    // =========================================================
17756
17757    public boolean startInstrumentation(ComponentName className,
17758            String profileFile, int flags, Bundle arguments,
17759            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17760            int userId, String abiOverride) {
17761        enforceNotIsolatedCaller("startInstrumentation");
17762        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17763                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17764        // Refuse possible leaked file descriptors
17765        if (arguments != null && arguments.hasFileDescriptors()) {
17766            throw new IllegalArgumentException("File descriptors passed in Bundle");
17767        }
17768
17769        synchronized(this) {
17770            InstrumentationInfo ii = null;
17771            ApplicationInfo ai = null;
17772            try {
17773                ii = mContext.getPackageManager().getInstrumentationInfo(
17774                    className, STOCK_PM_FLAGS);
17775                ai = AppGlobals.getPackageManager().getApplicationInfo(
17776                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17777            } catch (PackageManager.NameNotFoundException e) {
17778            } catch (RemoteException e) {
17779            }
17780            if (ii == null) {
17781                reportStartInstrumentationFailureLocked(watcher, className,
17782                        "Unable to find instrumentation info for: " + className);
17783                return false;
17784            }
17785            if (ai == null) {
17786                reportStartInstrumentationFailureLocked(watcher, className,
17787                        "Unable to find instrumentation target package: " + ii.targetPackage);
17788                return false;
17789            }
17790            if (!ai.hasCode()) {
17791                reportStartInstrumentationFailureLocked(watcher, className,
17792                        "Instrumentation target has no code: " + ii.targetPackage);
17793                return false;
17794            }
17795
17796            int match = mContext.getPackageManager().checkSignatures(
17797                    ii.targetPackage, ii.packageName);
17798            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17799                String msg = "Permission Denial: starting instrumentation "
17800                        + className + " from pid="
17801                        + Binder.getCallingPid()
17802                        + ", uid=" + Binder.getCallingPid()
17803                        + " not allowed because package " + ii.packageName
17804                        + " does not have a signature matching the target "
17805                        + ii.targetPackage;
17806                reportStartInstrumentationFailureLocked(watcher, className, msg);
17807                throw new SecurityException(msg);
17808            }
17809
17810            final long origId = Binder.clearCallingIdentity();
17811            // Instrumentation can kill and relaunch even persistent processes
17812            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17813                    "start instr");
17814            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17815            app.instrumentationClass = className;
17816            app.instrumentationInfo = ai;
17817            app.instrumentationProfileFile = profileFile;
17818            app.instrumentationArguments = arguments;
17819            app.instrumentationWatcher = watcher;
17820            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17821            app.instrumentationResultClass = className;
17822            Binder.restoreCallingIdentity(origId);
17823        }
17824
17825        return true;
17826    }
17827
17828    /**
17829     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17830     * error to the logs, but if somebody is watching, send the report there too.  This enables
17831     * the "am" command to report errors with more information.
17832     *
17833     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17834     * @param cn The component name of the instrumentation.
17835     * @param report The error report.
17836     */
17837    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17838            ComponentName cn, String report) {
17839        Slog.w(TAG, report);
17840        if (watcher != null) {
17841            Bundle results = new Bundle();
17842            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17843            results.putString("Error", report);
17844            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17845        }
17846    }
17847
17848    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17849        if (app.instrumentationWatcher != null) {
17850            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17851                    app.instrumentationClass, resultCode, results);
17852        }
17853
17854        // Can't call out of the system process with a lock held, so post a message.
17855        if (app.instrumentationUiAutomationConnection != null) {
17856            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17857                    app.instrumentationUiAutomationConnection).sendToTarget();
17858        }
17859
17860        app.instrumentationWatcher = null;
17861        app.instrumentationUiAutomationConnection = null;
17862        app.instrumentationClass = null;
17863        app.instrumentationInfo = null;
17864        app.instrumentationProfileFile = null;
17865        app.instrumentationArguments = null;
17866
17867        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17868                "finished inst");
17869    }
17870
17871    public void finishInstrumentation(IApplicationThread target,
17872            int resultCode, Bundle results) {
17873        int userId = UserHandle.getCallingUserId();
17874        // Refuse possible leaked file descriptors
17875        if (results != null && results.hasFileDescriptors()) {
17876            throw new IllegalArgumentException("File descriptors passed in Intent");
17877        }
17878
17879        synchronized(this) {
17880            ProcessRecord app = getRecordForAppLocked(target);
17881            if (app == null) {
17882                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17883                return;
17884            }
17885            final long origId = Binder.clearCallingIdentity();
17886            finishInstrumentationLocked(app, resultCode, results);
17887            Binder.restoreCallingIdentity(origId);
17888        }
17889    }
17890
17891    // =========================================================
17892    // CONFIGURATION
17893    // =========================================================
17894
17895    public ConfigurationInfo getDeviceConfigurationInfo() {
17896        ConfigurationInfo config = new ConfigurationInfo();
17897        synchronized (this) {
17898            config.reqTouchScreen = mConfiguration.touchscreen;
17899            config.reqKeyboardType = mConfiguration.keyboard;
17900            config.reqNavigation = mConfiguration.navigation;
17901            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17902                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17903                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17904            }
17905            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17906                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17907                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17908            }
17909            config.reqGlEsVersion = GL_ES_VERSION;
17910        }
17911        return config;
17912    }
17913
17914    ActivityStack getFocusedStack() {
17915        return mStackSupervisor.getFocusedStack();
17916    }
17917
17918    @Override
17919    public int getFocusedStackId() throws RemoteException {
17920        ActivityStack focusedStack = getFocusedStack();
17921        if (focusedStack != null) {
17922            return focusedStack.getStackId();
17923        }
17924        return -1;
17925    }
17926
17927    public Configuration getConfiguration() {
17928        Configuration ci;
17929        synchronized(this) {
17930            ci = new Configuration(mConfiguration);
17931            ci.userSetLocale = false;
17932        }
17933        return ci;
17934    }
17935
17936    @Override
17937    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17938        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17939        synchronized (this) {
17940            mSuppressResizeConfigChanges = suppress;
17941        }
17942    }
17943
17944    @Override
17945    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17946        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17947        if (fromStackId == HOME_STACK_ID) {
17948            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17949        }
17950        synchronized (this) {
17951            final long origId = Binder.clearCallingIdentity();
17952            try {
17953                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17954            } finally {
17955                Binder.restoreCallingIdentity(origId);
17956            }
17957        }
17958    }
17959
17960    @Override
17961    public void updatePersistentConfiguration(Configuration values) {
17962        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17963                "updateConfiguration()");
17964        enforceWriteSettingsPermission("updateConfiguration()");
17965        if (values == null) {
17966            throw new NullPointerException("Configuration must not be null");
17967        }
17968
17969        int userId = UserHandle.getCallingUserId();
17970
17971        synchronized(this) {
17972            final long origId = Binder.clearCallingIdentity();
17973            updateConfigurationLocked(values, null, false, true, userId);
17974            Binder.restoreCallingIdentity(origId);
17975        }
17976    }
17977
17978    private void updateFontScaleIfNeeded() {
17979        final int currentUserId;
17980        synchronized(this) {
17981            currentUserId = mUserController.getCurrentUserIdLocked();
17982        }
17983        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17984                FONT_SCALE, 1.0f, currentUserId);
17985        if (mConfiguration.fontScale != scaleFactor) {
17986            final Configuration configuration = mWindowManager.computeNewConfiguration();
17987            configuration.fontScale = scaleFactor;
17988            updatePersistentConfiguration(configuration);
17989        }
17990    }
17991
17992    private void enforceWriteSettingsPermission(String func) {
17993        int uid = Binder.getCallingUid();
17994        if (uid == Process.ROOT_UID) {
17995            return;
17996        }
17997
17998        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17999                Settings.getPackageNameForUid(mContext, uid), false)) {
18000            return;
18001        }
18002
18003        String msg = "Permission Denial: " + func + " from pid="
18004                + Binder.getCallingPid()
18005                + ", uid=" + uid
18006                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18007        Slog.w(TAG, msg);
18008        throw new SecurityException(msg);
18009    }
18010
18011    public void updateConfiguration(Configuration values) {
18012        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18013                "updateConfiguration()");
18014
18015        synchronized(this) {
18016            if (values == null && mWindowManager != null) {
18017                // sentinel: fetch the current configuration from the window manager
18018                values = mWindowManager.computeNewConfiguration();
18019            }
18020
18021            if (mWindowManager != null) {
18022                mProcessList.applyDisplaySize(mWindowManager);
18023            }
18024
18025            final long origId = Binder.clearCallingIdentity();
18026            if (values != null) {
18027                Settings.System.clearConfiguration(values);
18028            }
18029            updateConfigurationLocked(values, null, false);
18030            Binder.restoreCallingIdentity(origId);
18031        }
18032    }
18033
18034    void updateUserConfigurationLocked() {
18035        Configuration configuration = new Configuration(mConfiguration);
18036        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18037                mUserController.getCurrentUserIdLocked());
18038        updateConfigurationLocked(configuration, null, false);
18039    }
18040
18041    boolean updateConfigurationLocked(Configuration values,
18042            ActivityRecord starting, boolean initLocale) {
18043        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18044        return updateConfigurationLocked(values, starting, initLocale, false,
18045                UserHandle.USER_NULL);
18046    }
18047
18048    // To cache the list of supported system locales
18049    private String[] mSupportedSystemLocales = null;
18050
18051    /**
18052     * Do either or both things: (1) change the current configuration, and (2)
18053     * make sure the given activity is running with the (now) current
18054     * configuration.  Returns true if the activity has been left running, or
18055     * false if <var>starting</var> is being destroyed to match the new
18056     * configuration.
18057     *
18058     * @param userId is only used when persistent parameter is set to true to persist configuration
18059     *               for that particular user
18060     */
18061    private boolean updateConfigurationLocked(Configuration values,
18062            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18063        int changes = 0;
18064
18065        if (mWindowManager != null) {
18066            mWindowManager.deferSurfaceLayout();
18067        }
18068        if (values != null) {
18069            Configuration newConfig = new Configuration(mConfiguration);
18070            changes = newConfig.updateFrom(values);
18071            if (changes != 0) {
18072                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18073                        "Updating configuration to: " + values);
18074
18075                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18076
18077                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18078                    final Locale locale;
18079                    if (values.getLocales().size() == 1) {
18080                        // This is an optimization to avoid the JNI call when the result of
18081                        // getFirstMatch() does not depend on the supported locales.
18082                        locale = values.getLocales().get(0);
18083                    } else {
18084                        if (mSupportedSystemLocales == null) {
18085                            mSupportedSystemLocales =
18086                                    Resources.getSystem().getAssets().getLocales();
18087                        }
18088                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18089                    }
18090                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18091                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18092                            locale));
18093                }
18094
18095                mConfigurationSeq++;
18096                if (mConfigurationSeq <= 0) {
18097                    mConfigurationSeq = 1;
18098                }
18099                newConfig.seq = mConfigurationSeq;
18100                mConfiguration = newConfig;
18101                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18102                mUsageStatsService.reportConfigurationChange(newConfig,
18103                        mUserController.getCurrentUserIdLocked());
18104                //mUsageStatsService.noteStartConfig(newConfig);
18105
18106                final Configuration configCopy = new Configuration(mConfiguration);
18107
18108                // TODO: If our config changes, should we auto dismiss any currently
18109                // showing dialogs?
18110                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18111
18112                AttributeCache ac = AttributeCache.instance();
18113                if (ac != null) {
18114                    ac.updateConfiguration(configCopy);
18115                }
18116
18117                // Make sure all resources in our process are updated
18118                // right now, so that anyone who is going to retrieve
18119                // resource values after we return will be sure to get
18120                // the new ones.  This is especially important during
18121                // boot, where the first config change needs to guarantee
18122                // all resources have that config before following boot
18123                // code is executed.
18124                mSystemThread.applyConfigurationToResources(configCopy);
18125
18126                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18127                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18128                    msg.obj = new Configuration(configCopy);
18129                    msg.arg1 = userId;
18130                    mHandler.sendMessage(msg);
18131                }
18132
18133                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18134                if (isDensityChange) {
18135                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18136                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18137                }
18138
18139                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18140                    ProcessRecord app = mLruProcesses.get(i);
18141                    try {
18142                        if (app.thread != null) {
18143                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18144                                    + app.processName + " new config " + mConfiguration);
18145                            app.thread.scheduleConfigurationChanged(configCopy);
18146                        }
18147                    } catch (Exception e) {
18148                    }
18149                }
18150                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18151                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18152                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18153                        | Intent.FLAG_RECEIVER_FOREGROUND);
18154                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18155                        null, AppOpsManager.OP_NONE, null, false, false,
18156                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18157                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18158                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18159                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18160                    if (!mProcessesReady) {
18161                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18162                    }
18163                    broadcastIntentLocked(null, null, intent,
18164                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18165                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18166                }
18167            }
18168            // Update the configuration with WM first and check if any of the stacks need to be
18169            // resized due to the configuration change. If so, resize the stacks now and do any
18170            // relaunches if necessary. This way we don't need to relaunch again below in
18171            // ensureActivityConfigurationLocked().
18172            if (mWindowManager != null) {
18173                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18174                if (resizedStacks != null) {
18175                    for (int stackId : resizedStacks) {
18176                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18177                        mStackSupervisor.resizeStackLocked(
18178                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18179                    }
18180                }
18181            }
18182        }
18183
18184        boolean kept = true;
18185        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18186        // mainStack is null during startup.
18187        if (mainStack != null) {
18188            if (changes != 0 && starting == null) {
18189                // If the configuration changed, and the caller is not already
18190                // in the process of starting an activity, then find the top
18191                // activity to check if its configuration needs to change.
18192                starting = mainStack.topRunningActivityLocked();
18193            }
18194
18195            if (starting != null) {
18196                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18197                // And we need to make sure at this point that all other activities
18198                // are made visible with the correct configuration.
18199                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18200                        !PRESERVE_WINDOWS);
18201            }
18202        }
18203        if (mWindowManager != null) {
18204            mWindowManager.continueSurfaceLayout();
18205        }
18206        return kept;
18207    }
18208
18209    /**
18210     * Decide based on the configuration whether we should shouw the ANR,
18211     * crash, etc dialogs.  The idea is that if there is no affordnace to
18212     * press the on-screen buttons, we shouldn't show the dialog.
18213     *
18214     * A thought: SystemUI might also want to get told about this, the Power
18215     * dialog / global actions also might want different behaviors.
18216     */
18217    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18218        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18219                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18220                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18221        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18222                                    == Configuration.UI_MODE_TYPE_CAR);
18223        return inputMethodExists && uiIsNotCarType && !inVrMode;
18224    }
18225
18226    @Override
18227    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18228        synchronized (this) {
18229            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18230            if (srec != null) {
18231                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18232            }
18233        }
18234        return false;
18235    }
18236
18237    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18238            Intent resultData) {
18239
18240        synchronized (this) {
18241            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18242            if (r != null) {
18243                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18244            }
18245            return false;
18246        }
18247    }
18248
18249    public int getLaunchedFromUid(IBinder activityToken) {
18250        ActivityRecord srec;
18251        synchronized (this) {
18252            srec = ActivityRecord.forTokenLocked(activityToken);
18253        }
18254        if (srec == null) {
18255            return -1;
18256        }
18257        return srec.launchedFromUid;
18258    }
18259
18260    public String getLaunchedFromPackage(IBinder activityToken) {
18261        ActivityRecord srec;
18262        synchronized (this) {
18263            srec = ActivityRecord.forTokenLocked(activityToken);
18264        }
18265        if (srec == null) {
18266            return null;
18267        }
18268        return srec.launchedFromPackage;
18269    }
18270
18271    // =========================================================
18272    // LIFETIME MANAGEMENT
18273    // =========================================================
18274
18275    // Returns which broadcast queue the app is the current [or imminent] receiver
18276    // on, or 'null' if the app is not an active broadcast recipient.
18277    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18278        BroadcastRecord r = app.curReceiver;
18279        if (r != null) {
18280            return r.queue;
18281        }
18282
18283        // It's not the current receiver, but it might be starting up to become one
18284        synchronized (this) {
18285            for (BroadcastQueue queue : mBroadcastQueues) {
18286                r = queue.mPendingBroadcast;
18287                if (r != null && r.curApp == app) {
18288                    // found it; report which queue it's in
18289                    return queue;
18290                }
18291            }
18292        }
18293
18294        return null;
18295    }
18296
18297    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18298            int targetUid, ComponentName targetComponent, String targetProcess) {
18299        if (!mTrackingAssociations) {
18300            return null;
18301        }
18302        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18303                = mAssociations.get(targetUid);
18304        if (components == null) {
18305            components = new ArrayMap<>();
18306            mAssociations.put(targetUid, components);
18307        }
18308        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18309        if (sourceUids == null) {
18310            sourceUids = new SparseArray<>();
18311            components.put(targetComponent, sourceUids);
18312        }
18313        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18314        if (sourceProcesses == null) {
18315            sourceProcesses = new ArrayMap<>();
18316            sourceUids.put(sourceUid, sourceProcesses);
18317        }
18318        Association ass = sourceProcesses.get(sourceProcess);
18319        if (ass == null) {
18320            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18321                    targetProcess);
18322            sourceProcesses.put(sourceProcess, ass);
18323        }
18324        ass.mCount++;
18325        ass.mNesting++;
18326        if (ass.mNesting == 1) {
18327            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18328            ass.mLastState = sourceState;
18329        }
18330        return ass;
18331    }
18332
18333    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18334            ComponentName targetComponent) {
18335        if (!mTrackingAssociations) {
18336            return;
18337        }
18338        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18339                = mAssociations.get(targetUid);
18340        if (components == null) {
18341            return;
18342        }
18343        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18344        if (sourceUids == null) {
18345            return;
18346        }
18347        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18348        if (sourceProcesses == null) {
18349            return;
18350        }
18351        Association ass = sourceProcesses.get(sourceProcess);
18352        if (ass == null || ass.mNesting <= 0) {
18353            return;
18354        }
18355        ass.mNesting--;
18356        if (ass.mNesting == 0) {
18357            long uptime = SystemClock.uptimeMillis();
18358            ass.mTime += uptime - ass.mStartTime;
18359            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18360                    += uptime - ass.mLastStateUptime;
18361            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18362        }
18363    }
18364
18365    private void noteUidProcessState(final int uid, final int state) {
18366        mBatteryStatsService.noteUidProcessState(uid, state);
18367        if (mTrackingAssociations) {
18368            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18369                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18370                        = mAssociations.valueAt(i1);
18371                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18372                    SparseArray<ArrayMap<String, Association>> sourceUids
18373                            = targetComponents.valueAt(i2);
18374                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18375                    if (sourceProcesses != null) {
18376                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18377                            Association ass = sourceProcesses.valueAt(i4);
18378                            if (ass.mNesting >= 1) {
18379                                // currently associated
18380                                long uptime = SystemClock.uptimeMillis();
18381                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18382                                        += uptime - ass.mLastStateUptime;
18383                                ass.mLastState = state;
18384                                ass.mLastStateUptime = uptime;
18385                            }
18386                        }
18387                    }
18388                }
18389            }
18390        }
18391    }
18392
18393    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18394            boolean doingAll, long now) {
18395        if (mAdjSeq == app.adjSeq) {
18396            // This adjustment has already been computed.
18397            return app.curRawAdj;
18398        }
18399
18400        if (app.thread == null) {
18401            app.adjSeq = mAdjSeq;
18402            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18403            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18404            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18405        }
18406
18407        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18408        app.adjSource = null;
18409        app.adjTarget = null;
18410        app.empty = false;
18411        app.cached = false;
18412
18413        final int activitiesSize = app.activities.size();
18414
18415        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18416            // The max adjustment doesn't allow this app to be anything
18417            // below foreground, so it is not worth doing work for it.
18418            app.adjType = "fixed";
18419            app.adjSeq = mAdjSeq;
18420            app.curRawAdj = app.maxAdj;
18421            app.foregroundActivities = false;
18422            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18423            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18424            // System processes can do UI, and when they do we want to have
18425            // them trim their memory after the user leaves the UI.  To
18426            // facilitate this, here we need to determine whether or not it
18427            // is currently showing UI.
18428            app.systemNoUi = true;
18429            if (app == TOP_APP) {
18430                app.systemNoUi = false;
18431            } else if (activitiesSize > 0) {
18432                for (int j = 0; j < activitiesSize; j++) {
18433                    final ActivityRecord r = app.activities.get(j);
18434                    if (r.visible) {
18435                        app.systemNoUi = false;
18436                    }
18437                }
18438            }
18439            if (!app.systemNoUi) {
18440                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18441            }
18442            return (app.curAdj=app.maxAdj);
18443        }
18444
18445        app.systemNoUi = false;
18446
18447        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18448
18449        // Determine the importance of the process, starting with most
18450        // important to least, and assign an appropriate OOM adjustment.
18451        int adj;
18452        int schedGroup;
18453        int procState;
18454        boolean foregroundActivities = false;
18455        BroadcastQueue queue;
18456        if (app == TOP_APP) {
18457            // The last app on the list is the foreground app.
18458            adj = ProcessList.FOREGROUND_APP_ADJ;
18459            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18460            app.adjType = "top-activity";
18461            foregroundActivities = true;
18462            procState = PROCESS_STATE_CUR_TOP;
18463        } else if (app.instrumentationClass != null) {
18464            // Don't want to kill running instrumentation.
18465            adj = ProcessList.FOREGROUND_APP_ADJ;
18466            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18467            app.adjType = "instrumentation";
18468            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18469        } else if ((queue = isReceivingBroadcast(app)) != null) {
18470            // An app that is currently receiving a broadcast also
18471            // counts as being in the foreground for OOM killer purposes.
18472            // It's placed in a sched group based on the nature of the
18473            // broadcast as reflected by which queue it's active in.
18474            adj = ProcessList.FOREGROUND_APP_ADJ;
18475            schedGroup = (queue == mFgBroadcastQueue)
18476                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18477            app.adjType = "broadcast";
18478            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18479        } else if (app.executingServices.size() > 0) {
18480            // An app that is currently executing a service callback also
18481            // counts as being in the foreground.
18482            adj = ProcessList.FOREGROUND_APP_ADJ;
18483            schedGroup = app.execServicesFg ?
18484                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18485            app.adjType = "exec-service";
18486            procState = ActivityManager.PROCESS_STATE_SERVICE;
18487            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18488        } else {
18489            // As far as we know the process is empty.  We may change our mind later.
18490            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18491            // At this point we don't actually know the adjustment.  Use the cached adj
18492            // value that the caller wants us to.
18493            adj = cachedAdj;
18494            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18495            app.cached = true;
18496            app.empty = true;
18497            app.adjType = "cch-empty";
18498        }
18499
18500        // Examine all activities if not already foreground.
18501        if (!foregroundActivities && activitiesSize > 0) {
18502            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18503            for (int j = 0; j < activitiesSize; j++) {
18504                final ActivityRecord r = app.activities.get(j);
18505                if (r.app != app) {
18506                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18507                            + " instead of expected " + app);
18508                    if (r.app == null || (r.app.uid == app.uid)) {
18509                        // Only fix things up when they look sane
18510                        r.app = app;
18511                    } else {
18512                        continue;
18513                    }
18514                }
18515                if (r.visible) {
18516                    // App has a visible activity; only upgrade adjustment.
18517                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18518                        adj = ProcessList.VISIBLE_APP_ADJ;
18519                        app.adjType = "visible";
18520                    }
18521                    if (procState > PROCESS_STATE_CUR_TOP) {
18522                        procState = PROCESS_STATE_CUR_TOP;
18523                    }
18524                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18525                    app.cached = false;
18526                    app.empty = false;
18527                    foregroundActivities = true;
18528                    if (r.task != null && minLayer > 0) {
18529                        final int layer = r.task.mLayerRank;
18530                        if (layer >= 0 && minLayer > layer) {
18531                            minLayer = layer;
18532                        }
18533                    }
18534                    break;
18535                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18536                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18537                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18538                        app.adjType = "pausing";
18539                    }
18540                    if (procState > PROCESS_STATE_CUR_TOP) {
18541                        procState = PROCESS_STATE_CUR_TOP;
18542                    }
18543                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18544                    app.cached = false;
18545                    app.empty = false;
18546                    foregroundActivities = true;
18547                } else if (r.state == ActivityState.STOPPING) {
18548                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18549                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18550                        app.adjType = "stopping";
18551                    }
18552                    // For the process state, we will at this point consider the
18553                    // process to be cached.  It will be cached either as an activity
18554                    // or empty depending on whether the activity is finishing.  We do
18555                    // this so that we can treat the process as cached for purposes of
18556                    // memory trimming (determing current memory level, trim command to
18557                    // send to process) since there can be an arbitrary number of stopping
18558                    // processes and they should soon all go into the cached state.
18559                    if (!r.finishing) {
18560                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18561                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18562                        }
18563                    }
18564                    app.cached = false;
18565                    app.empty = false;
18566                    foregroundActivities = true;
18567                } else {
18568                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18569                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18570                        app.adjType = "cch-act";
18571                    }
18572                }
18573            }
18574            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18575                adj += minLayer;
18576            }
18577        }
18578
18579        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18580                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18581            if (app.foregroundServices) {
18582                // The user is aware of this app, so make it visible.
18583                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18584                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18585                app.cached = false;
18586                app.adjType = "fg-service";
18587                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18588            } else if (app.forcingToForeground != null) {
18589                // The user is aware of this app, so make it visible.
18590                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18591                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18592                app.cached = false;
18593                app.adjType = "force-fg";
18594                app.adjSource = app.forcingToForeground;
18595                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18596            }
18597        }
18598
18599        if (app == mHeavyWeightProcess) {
18600            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18601                // We don't want to kill the current heavy-weight process.
18602                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18603                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18604                app.cached = false;
18605                app.adjType = "heavy";
18606            }
18607            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18608                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18609            }
18610        }
18611
18612        if (app == mHomeProcess) {
18613            if (adj > ProcessList.HOME_APP_ADJ) {
18614                // This process is hosting what we currently consider to be the
18615                // home app, so we don't want to let it go into the background.
18616                adj = ProcessList.HOME_APP_ADJ;
18617                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18618                app.cached = false;
18619                app.adjType = "home";
18620            }
18621            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18622                procState = ActivityManager.PROCESS_STATE_HOME;
18623            }
18624        }
18625
18626        if (app == mPreviousProcess && app.activities.size() > 0) {
18627            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18628                // This was the previous process that showed UI to the user.
18629                // We want to try to keep it around more aggressively, to give
18630                // a good experience around switching between two apps.
18631                adj = ProcessList.PREVIOUS_APP_ADJ;
18632                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18633                app.cached = false;
18634                app.adjType = "previous";
18635            }
18636            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18637                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18638            }
18639        }
18640
18641        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18642                + " reason=" + app.adjType);
18643
18644        // By default, we use the computed adjustment.  It may be changed if
18645        // there are applications dependent on our services or providers, but
18646        // this gives us a baseline and makes sure we don't get into an
18647        // infinite recursion.
18648        app.adjSeq = mAdjSeq;
18649        app.curRawAdj = adj;
18650        app.hasStartedServices = false;
18651
18652        if (mBackupTarget != null && app == mBackupTarget.app) {
18653            // If possible we want to avoid killing apps while they're being backed up
18654            if (adj > ProcessList.BACKUP_APP_ADJ) {
18655                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18656                adj = ProcessList.BACKUP_APP_ADJ;
18657                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18658                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18659                }
18660                app.adjType = "backup";
18661                app.cached = false;
18662            }
18663            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18664                procState = ActivityManager.PROCESS_STATE_BACKUP;
18665            }
18666        }
18667
18668        boolean mayBeTop = false;
18669
18670        for (int is = app.services.size()-1;
18671                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18672                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18673                        || procState > ActivityManager.PROCESS_STATE_TOP);
18674                is--) {
18675            ServiceRecord s = app.services.valueAt(is);
18676            if (s.startRequested) {
18677                app.hasStartedServices = true;
18678                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18679                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18680                }
18681                if (app.hasShownUi && app != mHomeProcess) {
18682                    // If this process has shown some UI, let it immediately
18683                    // go to the LRU list because it may be pretty heavy with
18684                    // UI stuff.  We'll tag it with a label just to help
18685                    // debug and understand what is going on.
18686                    if (adj > ProcessList.SERVICE_ADJ) {
18687                        app.adjType = "cch-started-ui-services";
18688                    }
18689                } else {
18690                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18691                        // This service has seen some activity within
18692                        // recent memory, so we will keep its process ahead
18693                        // of the background processes.
18694                        if (adj > ProcessList.SERVICE_ADJ) {
18695                            adj = ProcessList.SERVICE_ADJ;
18696                            app.adjType = "started-services";
18697                            app.cached = false;
18698                        }
18699                    }
18700                    // If we have let the service slide into the background
18701                    // state, still have some text describing what it is doing
18702                    // even though the service no longer has an impact.
18703                    if (adj > ProcessList.SERVICE_ADJ) {
18704                        app.adjType = "cch-started-services";
18705                    }
18706                }
18707            }
18708            for (int conni = s.connections.size()-1;
18709                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18710                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18711                            || procState > ActivityManager.PROCESS_STATE_TOP);
18712                    conni--) {
18713                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18714                for (int i = 0;
18715                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18716                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18717                                || procState > ActivityManager.PROCESS_STATE_TOP);
18718                        i++) {
18719                    // XXX should compute this based on the max of
18720                    // all connected clients.
18721                    ConnectionRecord cr = clist.get(i);
18722                    if (cr.binding.client == app) {
18723                        // Binding to ourself is not interesting.
18724                        continue;
18725                    }
18726                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18727                        ProcessRecord client = cr.binding.client;
18728                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18729                                TOP_APP, doingAll, now);
18730                        int clientProcState = client.curProcState;
18731                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18732                            // If the other app is cached for any reason, for purposes here
18733                            // we are going to consider it empty.  The specific cached state
18734                            // doesn't propagate except under certain conditions.
18735                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18736                        }
18737                        String adjType = null;
18738                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18739                            // Not doing bind OOM management, so treat
18740                            // this guy more like a started service.
18741                            if (app.hasShownUi && app != mHomeProcess) {
18742                                // If this process has shown some UI, let it immediately
18743                                // go to the LRU list because it may be pretty heavy with
18744                                // UI stuff.  We'll tag it with a label just to help
18745                                // debug and understand what is going on.
18746                                if (adj > clientAdj) {
18747                                    adjType = "cch-bound-ui-services";
18748                                }
18749                                app.cached = false;
18750                                clientAdj = adj;
18751                                clientProcState = procState;
18752                            } else {
18753                                if (now >= (s.lastActivity
18754                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18755                                    // This service has not seen activity within
18756                                    // recent memory, so allow it to drop to the
18757                                    // LRU list if there is no other reason to keep
18758                                    // it around.  We'll also tag it with a label just
18759                                    // to help debug and undertand what is going on.
18760                                    if (adj > clientAdj) {
18761                                        adjType = "cch-bound-services";
18762                                    }
18763                                    clientAdj = adj;
18764                                }
18765                            }
18766                        }
18767                        if (adj > clientAdj) {
18768                            // If this process has recently shown UI, and
18769                            // the process that is binding to it is less
18770                            // important than being visible, then we don't
18771                            // care about the binding as much as we care
18772                            // about letting this process get into the LRU
18773                            // list to be killed and restarted if needed for
18774                            // memory.
18775                            if (app.hasShownUi && app != mHomeProcess
18776                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18777                                adjType = "cch-bound-ui-services";
18778                            } else {
18779                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18780                                        |Context.BIND_IMPORTANT)) != 0) {
18781                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18782                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18783                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18784                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18785                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18786                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18787                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18788                                    adj = clientAdj;
18789                                } else {
18790                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18791                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18792                                    }
18793                                }
18794                                if (!client.cached) {
18795                                    app.cached = false;
18796                                }
18797                                adjType = "service";
18798                            }
18799                        }
18800                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18801                            // This will treat important bound services identically to
18802                            // the top app, which may behave differently than generic
18803                            // foreground work.
18804                            if (client.curSchedGroup > schedGroup) {
18805                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18806                                    schedGroup = client.curSchedGroup;
18807                                } else {
18808                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18809                                }
18810                            }
18811                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18812                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18813                                    // Special handling of clients who are in the top state.
18814                                    // We *may* want to consider this process to be in the
18815                                    // top state as well, but only if there is not another
18816                                    // reason for it to be running.  Being on the top is a
18817                                    // special state, meaning you are specifically running
18818                                    // for the current top app.  If the process is already
18819                                    // running in the background for some other reason, it
18820                                    // is more important to continue considering it to be
18821                                    // in the background state.
18822                                    mayBeTop = true;
18823                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18824                                } else {
18825                                    // Special handling for above-top states (persistent
18826                                    // processes).  These should not bring the current process
18827                                    // into the top state, since they are not on top.  Instead
18828                                    // give them the best state after that.
18829                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18830                                        clientProcState =
18831                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18832                                    } else if (mWakefulness
18833                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18834                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18835                                                    != 0) {
18836                                        clientProcState =
18837                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18838                                    } else {
18839                                        clientProcState =
18840                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18841                                    }
18842                                }
18843                            }
18844                        } else {
18845                            if (clientProcState <
18846                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18847                                clientProcState =
18848                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18849                            }
18850                        }
18851                        if (procState > clientProcState) {
18852                            procState = clientProcState;
18853                        }
18854                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18855                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18856                            app.pendingUiClean = true;
18857                        }
18858                        if (adjType != null) {
18859                            app.adjType = adjType;
18860                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18861                                    .REASON_SERVICE_IN_USE;
18862                            app.adjSource = cr.binding.client;
18863                            app.adjSourceProcState = clientProcState;
18864                            app.adjTarget = s.name;
18865                        }
18866                    }
18867                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18868                        app.treatLikeActivity = true;
18869                    }
18870                    final ActivityRecord a = cr.activity;
18871                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18872                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18873                            (a.visible || a.state == ActivityState.RESUMED ||
18874                             a.state == ActivityState.PAUSING)) {
18875                            adj = ProcessList.FOREGROUND_APP_ADJ;
18876                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18877                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18878                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18879                                } else {
18880                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18881                                }
18882                            }
18883                            app.cached = false;
18884                            app.adjType = "service";
18885                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18886                                    .REASON_SERVICE_IN_USE;
18887                            app.adjSource = a;
18888                            app.adjSourceProcState = procState;
18889                            app.adjTarget = s.name;
18890                        }
18891                    }
18892                }
18893            }
18894        }
18895
18896        for (int provi = app.pubProviders.size()-1;
18897                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18898                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18899                        || procState > ActivityManager.PROCESS_STATE_TOP);
18900                provi--) {
18901            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18902            for (int i = cpr.connections.size()-1;
18903                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18904                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18905                            || procState > ActivityManager.PROCESS_STATE_TOP);
18906                    i--) {
18907                ContentProviderConnection conn = cpr.connections.get(i);
18908                ProcessRecord client = conn.client;
18909                if (client == app) {
18910                    // Being our own client is not interesting.
18911                    continue;
18912                }
18913                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18914                int clientProcState = client.curProcState;
18915                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18916                    // If the other app is cached for any reason, for purposes here
18917                    // we are going to consider it empty.
18918                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18919                }
18920                if (adj > clientAdj) {
18921                    if (app.hasShownUi && app != mHomeProcess
18922                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18923                        app.adjType = "cch-ui-provider";
18924                    } else {
18925                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18926                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18927                        app.adjType = "provider";
18928                    }
18929                    app.cached &= client.cached;
18930                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18931                            .REASON_PROVIDER_IN_USE;
18932                    app.adjSource = client;
18933                    app.adjSourceProcState = clientProcState;
18934                    app.adjTarget = cpr.name;
18935                }
18936                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18937                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18938                        // Special handling of clients who are in the top state.
18939                        // We *may* want to consider this process to be in the
18940                        // top state as well, but only if there is not another
18941                        // reason for it to be running.  Being on the top is a
18942                        // special state, meaning you are specifically running
18943                        // for the current top app.  If the process is already
18944                        // running in the background for some other reason, it
18945                        // is more important to continue considering it to be
18946                        // in the background state.
18947                        mayBeTop = true;
18948                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18949                    } else {
18950                        // Special handling for above-top states (persistent
18951                        // processes).  These should not bring the current process
18952                        // into the top state, since they are not on top.  Instead
18953                        // give them the best state after that.
18954                        clientProcState =
18955                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18956                    }
18957                }
18958                if (procState > clientProcState) {
18959                    procState = clientProcState;
18960                }
18961                if (client.curSchedGroup > schedGroup) {
18962                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18963                }
18964            }
18965            // If the provider has external (non-framework) process
18966            // dependencies, ensure that its adjustment is at least
18967            // FOREGROUND_APP_ADJ.
18968            if (cpr.hasExternalProcessHandles()) {
18969                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18970                    adj = ProcessList.FOREGROUND_APP_ADJ;
18971                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18972                    app.cached = false;
18973                    app.adjType = "provider";
18974                    app.adjTarget = cpr.name;
18975                }
18976                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18977                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18978                }
18979            }
18980        }
18981
18982        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18983            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18984                adj = ProcessList.PREVIOUS_APP_ADJ;
18985                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18986                app.cached = false;
18987                app.adjType = "provider";
18988            }
18989            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18990                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18991            }
18992        }
18993
18994        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18995            // A client of one of our services or providers is in the top state.  We
18996            // *may* want to be in the top state, but not if we are already running in
18997            // the background for some other reason.  For the decision here, we are going
18998            // to pick out a few specific states that we want to remain in when a client
18999            // is top (states that tend to be longer-term) and otherwise allow it to go
19000            // to the top state.
19001            switch (procState) {
19002                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19003                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19004                case ActivityManager.PROCESS_STATE_SERVICE:
19005                    // These all are longer-term states, so pull them up to the top
19006                    // of the background states, but not all the way to the top state.
19007                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19008                    break;
19009                default:
19010                    // Otherwise, top is a better choice, so take it.
19011                    procState = ActivityManager.PROCESS_STATE_TOP;
19012                    break;
19013            }
19014        }
19015
19016        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19017            if (app.hasClientActivities) {
19018                // This is a cached process, but with client activities.  Mark it so.
19019                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19020                app.adjType = "cch-client-act";
19021            } else if (app.treatLikeActivity) {
19022                // This is a cached process, but somebody wants us to treat it like it has
19023                // an activity, okay!
19024                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19025                app.adjType = "cch-as-act";
19026            }
19027        }
19028
19029        if (adj == ProcessList.SERVICE_ADJ) {
19030            if (doingAll) {
19031                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19032                mNewNumServiceProcs++;
19033                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19034                if (!app.serviceb) {
19035                    // This service isn't far enough down on the LRU list to
19036                    // normally be a B service, but if we are low on RAM and it
19037                    // is large we want to force it down since we would prefer to
19038                    // keep launcher over it.
19039                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19040                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19041                        app.serviceHighRam = true;
19042                        app.serviceb = true;
19043                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19044                    } else {
19045                        mNewNumAServiceProcs++;
19046                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19047                    }
19048                } else {
19049                    app.serviceHighRam = false;
19050                }
19051            }
19052            if (app.serviceb) {
19053                adj = ProcessList.SERVICE_B_ADJ;
19054            }
19055        }
19056
19057        app.curRawAdj = adj;
19058
19059        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19060        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19061        if (adj > app.maxAdj) {
19062            adj = app.maxAdj;
19063            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19064                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19065            }
19066        }
19067
19068        // Do final modification to adj.  Everything we do between here and applying
19069        // the final setAdj must be done in this function, because we will also use
19070        // it when computing the final cached adj later.  Note that we don't need to
19071        // worry about this for max adj above, since max adj will always be used to
19072        // keep it out of the cached vaues.
19073        app.curAdj = app.modifyRawOomAdj(adj);
19074        app.curSchedGroup = schedGroup;
19075        app.curProcState = procState;
19076        app.foregroundActivities = foregroundActivities;
19077
19078        return app.curRawAdj;
19079    }
19080
19081    /**
19082     * Record new PSS sample for a process.
19083     */
19084    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19085            long now) {
19086        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19087                swapPss * 1024);
19088        proc.lastPssTime = now;
19089        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19090        if (DEBUG_PSS) Slog.d(TAG_PSS,
19091                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19092                + " state=" + ProcessList.makeProcStateString(procState));
19093        if (proc.initialIdlePss == 0) {
19094            proc.initialIdlePss = pss;
19095        }
19096        proc.lastPss = pss;
19097        proc.lastSwapPss = swapPss;
19098        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19099            proc.lastCachedPss = pss;
19100            proc.lastCachedSwapPss = swapPss;
19101        }
19102
19103        final SparseArray<Pair<Long, String>> watchUids
19104                = mMemWatchProcesses.getMap().get(proc.processName);
19105        Long check = null;
19106        if (watchUids != null) {
19107            Pair<Long, String> val = watchUids.get(proc.uid);
19108            if (val == null) {
19109                val = watchUids.get(0);
19110            }
19111            if (val != null) {
19112                check = val.first;
19113            }
19114        }
19115        if (check != null) {
19116            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19117                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19118                if (!isDebuggable) {
19119                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19120                        isDebuggable = true;
19121                    }
19122                }
19123                if (isDebuggable) {
19124                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19125                    final ProcessRecord myProc = proc;
19126                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19127                    mMemWatchDumpProcName = proc.processName;
19128                    mMemWatchDumpFile = heapdumpFile.toString();
19129                    mMemWatchDumpPid = proc.pid;
19130                    mMemWatchDumpUid = proc.uid;
19131                    BackgroundThread.getHandler().post(new Runnable() {
19132                        @Override
19133                        public void run() {
19134                            revokeUriPermission(ActivityThread.currentActivityThread()
19135                                            .getApplicationThread(),
19136                                    DumpHeapActivity.JAVA_URI,
19137                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19138                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19139                                    UserHandle.myUserId());
19140                            ParcelFileDescriptor fd = null;
19141                            try {
19142                                heapdumpFile.delete();
19143                                fd = ParcelFileDescriptor.open(heapdumpFile,
19144                                        ParcelFileDescriptor.MODE_CREATE |
19145                                                ParcelFileDescriptor.MODE_TRUNCATE |
19146                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19147                                                ParcelFileDescriptor.MODE_APPEND);
19148                                IApplicationThread thread = myProc.thread;
19149                                if (thread != null) {
19150                                    try {
19151                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19152                                                "Requesting dump heap from "
19153                                                + myProc + " to " + heapdumpFile);
19154                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19155                                    } catch (RemoteException e) {
19156                                    }
19157                                }
19158                            } catch (FileNotFoundException e) {
19159                                e.printStackTrace();
19160                            } finally {
19161                                if (fd != null) {
19162                                    try {
19163                                        fd.close();
19164                                    } catch (IOException e) {
19165                                    }
19166                                }
19167                            }
19168                        }
19169                    });
19170                } else {
19171                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19172                            + ", but debugging not enabled");
19173                }
19174            }
19175        }
19176    }
19177
19178    /**
19179     * Schedule PSS collection of a process.
19180     */
19181    void requestPssLocked(ProcessRecord proc, int procState) {
19182        if (mPendingPssProcesses.contains(proc)) {
19183            return;
19184        }
19185        if (mPendingPssProcesses.size() == 0) {
19186            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19187        }
19188        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19189        proc.pssProcState = procState;
19190        mPendingPssProcesses.add(proc);
19191    }
19192
19193    /**
19194     * Schedule PSS collection of all processes.
19195     */
19196    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19197        if (!always) {
19198            if (now < (mLastFullPssTime +
19199                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19200                return;
19201            }
19202        }
19203        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19204        mLastFullPssTime = now;
19205        mFullPssPending = true;
19206        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19207        mPendingPssProcesses.clear();
19208        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19209            ProcessRecord app = mLruProcesses.get(i);
19210            if (app.thread == null
19211                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19212                continue;
19213            }
19214            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19215                app.pssProcState = app.setProcState;
19216                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19217                        mTestPssMode, isSleeping(), now);
19218                mPendingPssProcesses.add(app);
19219            }
19220        }
19221        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19222    }
19223
19224    public void setTestPssMode(boolean enabled) {
19225        synchronized (this) {
19226            mTestPssMode = enabled;
19227            if (enabled) {
19228                // Whenever we enable the mode, we want to take a snapshot all of current
19229                // process mem use.
19230                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19231            }
19232        }
19233    }
19234
19235    /**
19236     * Ask a given process to GC right now.
19237     */
19238    final void performAppGcLocked(ProcessRecord app) {
19239        try {
19240            app.lastRequestedGc = SystemClock.uptimeMillis();
19241            if (app.thread != null) {
19242                if (app.reportLowMemory) {
19243                    app.reportLowMemory = false;
19244                    app.thread.scheduleLowMemory();
19245                } else {
19246                    app.thread.processInBackground();
19247                }
19248            }
19249        } catch (Exception e) {
19250            // whatever.
19251        }
19252    }
19253
19254    /**
19255     * Returns true if things are idle enough to perform GCs.
19256     */
19257    private final boolean canGcNowLocked() {
19258        boolean processingBroadcasts = false;
19259        for (BroadcastQueue q : mBroadcastQueues) {
19260            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19261                processingBroadcasts = true;
19262            }
19263        }
19264        return !processingBroadcasts
19265                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19266    }
19267
19268    /**
19269     * Perform GCs on all processes that are waiting for it, but only
19270     * if things are idle.
19271     */
19272    final void performAppGcsLocked() {
19273        final int N = mProcessesToGc.size();
19274        if (N <= 0) {
19275            return;
19276        }
19277        if (canGcNowLocked()) {
19278            while (mProcessesToGc.size() > 0) {
19279                ProcessRecord proc = mProcessesToGc.remove(0);
19280                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19281                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19282                            <= SystemClock.uptimeMillis()) {
19283                        // To avoid spamming the system, we will GC processes one
19284                        // at a time, waiting a few seconds between each.
19285                        performAppGcLocked(proc);
19286                        scheduleAppGcsLocked();
19287                        return;
19288                    } else {
19289                        // It hasn't been long enough since we last GCed this
19290                        // process...  put it in the list to wait for its time.
19291                        addProcessToGcListLocked(proc);
19292                        break;
19293                    }
19294                }
19295            }
19296
19297            scheduleAppGcsLocked();
19298        }
19299    }
19300
19301    /**
19302     * If all looks good, perform GCs on all processes waiting for them.
19303     */
19304    final void performAppGcsIfAppropriateLocked() {
19305        if (canGcNowLocked()) {
19306            performAppGcsLocked();
19307            return;
19308        }
19309        // Still not idle, wait some more.
19310        scheduleAppGcsLocked();
19311    }
19312
19313    /**
19314     * Schedule the execution of all pending app GCs.
19315     */
19316    final void scheduleAppGcsLocked() {
19317        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19318
19319        if (mProcessesToGc.size() > 0) {
19320            // Schedule a GC for the time to the next process.
19321            ProcessRecord proc = mProcessesToGc.get(0);
19322            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19323
19324            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19325            long now = SystemClock.uptimeMillis();
19326            if (when < (now+GC_TIMEOUT)) {
19327                when = now + GC_TIMEOUT;
19328            }
19329            mHandler.sendMessageAtTime(msg, when);
19330        }
19331    }
19332
19333    /**
19334     * Add a process to the array of processes waiting to be GCed.  Keeps the
19335     * list in sorted order by the last GC time.  The process can't already be
19336     * on the list.
19337     */
19338    final void addProcessToGcListLocked(ProcessRecord proc) {
19339        boolean added = false;
19340        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19341            if (mProcessesToGc.get(i).lastRequestedGc <
19342                    proc.lastRequestedGc) {
19343                added = true;
19344                mProcessesToGc.add(i+1, proc);
19345                break;
19346            }
19347        }
19348        if (!added) {
19349            mProcessesToGc.add(0, proc);
19350        }
19351    }
19352
19353    /**
19354     * Set up to ask a process to GC itself.  This will either do it
19355     * immediately, or put it on the list of processes to gc the next
19356     * time things are idle.
19357     */
19358    final void scheduleAppGcLocked(ProcessRecord app) {
19359        long now = SystemClock.uptimeMillis();
19360        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19361            return;
19362        }
19363        if (!mProcessesToGc.contains(app)) {
19364            addProcessToGcListLocked(app);
19365            scheduleAppGcsLocked();
19366        }
19367    }
19368
19369    final void checkExcessivePowerUsageLocked(boolean doKills) {
19370        updateCpuStatsNow();
19371
19372        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19373        boolean doWakeKills = doKills;
19374        boolean doCpuKills = doKills;
19375        if (mLastPowerCheckRealtime == 0) {
19376            doWakeKills = false;
19377        }
19378        if (mLastPowerCheckUptime == 0) {
19379            doCpuKills = false;
19380        }
19381        if (stats.isScreenOn()) {
19382            doWakeKills = false;
19383        }
19384        final long curRealtime = SystemClock.elapsedRealtime();
19385        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19386        final long curUptime = SystemClock.uptimeMillis();
19387        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19388        mLastPowerCheckRealtime = curRealtime;
19389        mLastPowerCheckUptime = curUptime;
19390        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19391            doWakeKills = false;
19392        }
19393        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19394            doCpuKills = false;
19395        }
19396        int i = mLruProcesses.size();
19397        while (i > 0) {
19398            i--;
19399            ProcessRecord app = mLruProcesses.get(i);
19400            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19401                long wtime;
19402                synchronized (stats) {
19403                    wtime = stats.getProcessWakeTime(app.info.uid,
19404                            app.pid, curRealtime);
19405                }
19406                long wtimeUsed = wtime - app.lastWakeTime;
19407                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19408                if (DEBUG_POWER) {
19409                    StringBuilder sb = new StringBuilder(128);
19410                    sb.append("Wake for ");
19411                    app.toShortString(sb);
19412                    sb.append(": over ");
19413                    TimeUtils.formatDuration(realtimeSince, sb);
19414                    sb.append(" used ");
19415                    TimeUtils.formatDuration(wtimeUsed, sb);
19416                    sb.append(" (");
19417                    sb.append((wtimeUsed*100)/realtimeSince);
19418                    sb.append("%)");
19419                    Slog.i(TAG_POWER, sb.toString());
19420                    sb.setLength(0);
19421                    sb.append("CPU for ");
19422                    app.toShortString(sb);
19423                    sb.append(": over ");
19424                    TimeUtils.formatDuration(uptimeSince, sb);
19425                    sb.append(" used ");
19426                    TimeUtils.formatDuration(cputimeUsed, sb);
19427                    sb.append(" (");
19428                    sb.append((cputimeUsed*100)/uptimeSince);
19429                    sb.append("%)");
19430                    Slog.i(TAG_POWER, sb.toString());
19431                }
19432                // If a process has held a wake lock for more
19433                // than 50% of the time during this period,
19434                // that sounds bad.  Kill!
19435                if (doWakeKills && realtimeSince > 0
19436                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19437                    synchronized (stats) {
19438                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19439                                realtimeSince, wtimeUsed);
19440                    }
19441                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19442                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19443                } else if (doCpuKills && uptimeSince > 0
19444                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19445                    synchronized (stats) {
19446                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19447                                uptimeSince, cputimeUsed);
19448                    }
19449                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19450                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19451                } else {
19452                    app.lastWakeTime = wtime;
19453                    app.lastCpuTime = app.curCpuTime;
19454                }
19455            }
19456        }
19457    }
19458
19459    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19460            long nowElapsed) {
19461        boolean success = true;
19462
19463        if (app.curRawAdj != app.setRawAdj) {
19464            app.setRawAdj = app.curRawAdj;
19465        }
19466
19467        int changes = 0;
19468
19469        if (app.curAdj != app.setAdj) {
19470            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19471            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19472                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19473                    + app.adjType);
19474            app.setAdj = app.curAdj;
19475        }
19476
19477        if (app.setSchedGroup != app.curSchedGroup) {
19478            app.setSchedGroup = app.curSchedGroup;
19479            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19480                    "Setting sched group of " + app.processName
19481                    + " to " + app.curSchedGroup);
19482            if (app.waitingToKill != null && app.curReceiver == null
19483                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19484                app.kill(app.waitingToKill, true);
19485                success = false;
19486            } else {
19487                int processGroup;
19488                switch (app.curSchedGroup) {
19489                    case ProcessList.SCHED_GROUP_BACKGROUND:
19490                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19491                        break;
19492                    case ProcessList.SCHED_GROUP_TOP_APP:
19493                        processGroup = Process.THREAD_GROUP_TOP_APP;
19494                        break;
19495                    default:
19496                        processGroup = Process.THREAD_GROUP_DEFAULT;
19497                        break;
19498                }
19499                if (true) {
19500                    long oldId = Binder.clearCallingIdentity();
19501                    try {
19502                        Process.setProcessGroup(app.pid, processGroup);
19503                    } catch (Exception e) {
19504                        Slog.w(TAG, "Failed setting process group of " + app.pid
19505                                + " to " + app.curSchedGroup);
19506                        e.printStackTrace();
19507                    } finally {
19508                        Binder.restoreCallingIdentity(oldId);
19509                    }
19510                } else {
19511                    if (app.thread != null) {
19512                        try {
19513                            app.thread.setSchedulingGroup(processGroup);
19514                        } catch (RemoteException e) {
19515                        }
19516                    }
19517                }
19518            }
19519        }
19520        if (app.repForegroundActivities != app.foregroundActivities) {
19521            app.repForegroundActivities = app.foregroundActivities;
19522            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19523        }
19524        if (app.repProcState != app.curProcState) {
19525            app.repProcState = app.curProcState;
19526            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19527            if (app.thread != null) {
19528                try {
19529                    if (false) {
19530                        //RuntimeException h = new RuntimeException("here");
19531                        Slog.i(TAG, "Sending new process state " + app.repProcState
19532                                + " to " + app /*, h*/);
19533                    }
19534                    app.thread.setProcessState(app.repProcState);
19535                } catch (RemoteException e) {
19536                }
19537            }
19538        }
19539        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19540                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19541            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19542                // Experimental code to more aggressively collect pss while
19543                // running test...  the problem is that this tends to collect
19544                // the data right when a process is transitioning between process
19545                // states, which well tend to give noisy data.
19546                long start = SystemClock.uptimeMillis();
19547                long pss = Debug.getPss(app.pid, mTmpLong, null);
19548                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19549                mPendingPssProcesses.remove(app);
19550                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19551                        + " to " + app.curProcState + ": "
19552                        + (SystemClock.uptimeMillis()-start) + "ms");
19553            }
19554            app.lastStateTime = now;
19555            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19556                    mTestPssMode, isSleeping(), now);
19557            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19558                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19559                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19560                    + (app.nextPssTime-now) + ": " + app);
19561        } else {
19562            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19563                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19564                    mTestPssMode)))) {
19565                requestPssLocked(app, app.setProcState);
19566                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19567                        mTestPssMode, isSleeping(), now);
19568            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19569                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19570        }
19571        if (app.setProcState != app.curProcState) {
19572            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19573                    "Proc state change of " + app.processName
19574                            + " to " + app.curProcState);
19575            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19576            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19577            if (setImportant && !curImportant) {
19578                // This app is no longer something we consider important enough to allow to
19579                // use arbitrary amounts of battery power.  Note
19580                // its current wake lock time to later know to kill it if
19581                // it is not behaving well.
19582                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19583                synchronized (stats) {
19584                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19585                            app.pid, nowElapsed);
19586                }
19587                app.lastCpuTime = app.curCpuTime;
19588
19589            }
19590            // Inform UsageStats of important process state change
19591            // Must be called before updating setProcState
19592            maybeUpdateUsageStatsLocked(app, nowElapsed);
19593
19594            app.setProcState = app.curProcState;
19595            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19596                app.notCachedSinceIdle = false;
19597            }
19598            if (!doingAll) {
19599                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19600            } else {
19601                app.procStateChanged = true;
19602            }
19603        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19604                > USAGE_STATS_INTERACTION_INTERVAL) {
19605            // For apps that sit around for a long time in the interactive state, we need
19606            // to report this at least once a day so they don't go idle.
19607            maybeUpdateUsageStatsLocked(app, nowElapsed);
19608        }
19609
19610        if (changes != 0) {
19611            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19612                    "Changes in " + app + ": " + changes);
19613            int i = mPendingProcessChanges.size()-1;
19614            ProcessChangeItem item = null;
19615            while (i >= 0) {
19616                item = mPendingProcessChanges.get(i);
19617                if (item.pid == app.pid) {
19618                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19619                            "Re-using existing item: " + item);
19620                    break;
19621                }
19622                i--;
19623            }
19624            if (i < 0) {
19625                // No existing item in pending changes; need a new one.
19626                final int NA = mAvailProcessChanges.size();
19627                if (NA > 0) {
19628                    item = mAvailProcessChanges.remove(NA-1);
19629                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19630                            "Retrieving available item: " + item);
19631                } else {
19632                    item = new ProcessChangeItem();
19633                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19634                            "Allocating new item: " + item);
19635                }
19636                item.changes = 0;
19637                item.pid = app.pid;
19638                item.uid = app.info.uid;
19639                if (mPendingProcessChanges.size() == 0) {
19640                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19641                            "*** Enqueueing dispatch processes changed!");
19642                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19643                }
19644                mPendingProcessChanges.add(item);
19645            }
19646            item.changes |= changes;
19647            item.processState = app.repProcState;
19648            item.foregroundActivities = app.repForegroundActivities;
19649            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19650                    "Item " + Integer.toHexString(System.identityHashCode(item))
19651                    + " " + app.toShortString() + ": changes=" + item.changes
19652                    + " procState=" + item.processState
19653                    + " foreground=" + item.foregroundActivities
19654                    + " type=" + app.adjType + " source=" + app.adjSource
19655                    + " target=" + app.adjTarget);
19656        }
19657
19658        return success;
19659    }
19660
19661    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19662        final UidRecord.ChangeItem pendingChange;
19663        if (uidRec == null || uidRec.pendingChange == null) {
19664            if (mPendingUidChanges.size() == 0) {
19665                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19666                        "*** Enqueueing dispatch uid changed!");
19667                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19668            }
19669            final int NA = mAvailUidChanges.size();
19670            if (NA > 0) {
19671                pendingChange = mAvailUidChanges.remove(NA-1);
19672                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19673                        "Retrieving available item: " + pendingChange);
19674            } else {
19675                pendingChange = new UidRecord.ChangeItem();
19676                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19677                        "Allocating new item: " + pendingChange);
19678            }
19679            if (uidRec != null) {
19680                uidRec.pendingChange = pendingChange;
19681                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19682                    // If this uid is going away, and we haven't yet reported it is gone,
19683                    // then do so now.
19684                    change = UidRecord.CHANGE_GONE_IDLE;
19685                }
19686            } else if (uid < 0) {
19687                throw new IllegalArgumentException("No UidRecord or uid");
19688            }
19689            pendingChange.uidRecord = uidRec;
19690            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19691            mPendingUidChanges.add(pendingChange);
19692        } else {
19693            pendingChange = uidRec.pendingChange;
19694            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19695                change = UidRecord.CHANGE_GONE_IDLE;
19696            }
19697        }
19698        pendingChange.change = change;
19699        pendingChange.processState = uidRec != null
19700                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19701    }
19702
19703    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19704            String authority) {
19705        if (app == null) return;
19706        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19707            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19708            if (userState == null) return;
19709            final long now = SystemClock.elapsedRealtime();
19710            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19711            if (lastReported == null || lastReported < now - 60 * 1000L) {
19712                mUsageStatsService.reportContentProviderUsage(
19713                        authority, providerPkgName, app.userId);
19714                userState.mProviderLastReportedFg.put(authority, now);
19715            }
19716        }
19717    }
19718
19719    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19720        if (DEBUG_USAGE_STATS) {
19721            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19722                    + "] state changes: old = " + app.setProcState + ", new = "
19723                    + app.curProcState);
19724        }
19725        if (mUsageStatsService == null) {
19726            return;
19727        }
19728        boolean isInteraction;
19729        // To avoid some abuse patterns, we are going to be careful about what we consider
19730        // to be an app interaction.  Being the top activity doesn't count while the display
19731        // is sleeping, nor do short foreground services.
19732        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19733            isInteraction = true;
19734            app.fgInteractionTime = 0;
19735        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19736            if (app.fgInteractionTime == 0) {
19737                app.fgInteractionTime = nowElapsed;
19738                isInteraction = false;
19739            } else {
19740                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19741            }
19742        } else {
19743            isInteraction = app.curProcState
19744                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19745            app.fgInteractionTime = 0;
19746        }
19747        if (isInteraction && (!app.reportedInteraction
19748                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19749            app.interactionEventTime = nowElapsed;
19750            String[] packages = app.getPackageList();
19751            if (packages != null) {
19752                for (int i = 0; i < packages.length; i++) {
19753                    mUsageStatsService.reportEvent(packages[i], app.userId,
19754                            UsageEvents.Event.SYSTEM_INTERACTION);
19755                }
19756            }
19757        }
19758        app.reportedInteraction = isInteraction;
19759        if (!isInteraction) {
19760            app.interactionEventTime = 0;
19761        }
19762    }
19763
19764    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19765        if (proc.thread != null) {
19766            if (proc.baseProcessTracker != null) {
19767                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19768            }
19769        }
19770    }
19771
19772    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19773            ProcessRecord TOP_APP, boolean doingAll, long now) {
19774        if (app.thread == null) {
19775            return false;
19776        }
19777
19778        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19779
19780        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19781    }
19782
19783    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19784            boolean oomAdj) {
19785        if (isForeground != proc.foregroundServices) {
19786            proc.foregroundServices = isForeground;
19787            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19788                    proc.info.uid);
19789            if (isForeground) {
19790                if (curProcs == null) {
19791                    curProcs = new ArrayList<ProcessRecord>();
19792                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19793                }
19794                if (!curProcs.contains(proc)) {
19795                    curProcs.add(proc);
19796                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19797                            proc.info.packageName, proc.info.uid);
19798                }
19799            } else {
19800                if (curProcs != null) {
19801                    if (curProcs.remove(proc)) {
19802                        mBatteryStatsService.noteEvent(
19803                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19804                                proc.info.packageName, proc.info.uid);
19805                        if (curProcs.size() <= 0) {
19806                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19807                        }
19808                    }
19809                }
19810            }
19811            if (oomAdj) {
19812                updateOomAdjLocked();
19813            }
19814        }
19815    }
19816
19817    private final ActivityRecord resumedAppLocked() {
19818        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19819        String pkg;
19820        int uid;
19821        if (act != null) {
19822            pkg = act.packageName;
19823            uid = act.info.applicationInfo.uid;
19824        } else {
19825            pkg = null;
19826            uid = -1;
19827        }
19828        // Has the UID or resumed package name changed?
19829        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19830                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19831            if (mCurResumedPackage != null) {
19832                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19833                        mCurResumedPackage, mCurResumedUid);
19834            }
19835            mCurResumedPackage = pkg;
19836            mCurResumedUid = uid;
19837            if (mCurResumedPackage != null) {
19838                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19839                        mCurResumedPackage, mCurResumedUid);
19840            }
19841        }
19842        return act;
19843    }
19844
19845    final boolean updateOomAdjLocked(ProcessRecord app) {
19846        final ActivityRecord TOP_ACT = resumedAppLocked();
19847        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19848        final boolean wasCached = app.cached;
19849
19850        mAdjSeq++;
19851
19852        // This is the desired cached adjusment we want to tell it to use.
19853        // If our app is currently cached, we know it, and that is it.  Otherwise,
19854        // we don't know it yet, and it needs to now be cached we will then
19855        // need to do a complete oom adj.
19856        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19857                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19858        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19859                SystemClock.uptimeMillis());
19860        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19861            // Changed to/from cached state, so apps after it in the LRU
19862            // list may also be changed.
19863            updateOomAdjLocked();
19864        }
19865        return success;
19866    }
19867
19868    final void updateOomAdjLocked() {
19869        final ActivityRecord TOP_ACT = resumedAppLocked();
19870        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19871        final long now = SystemClock.uptimeMillis();
19872        final long nowElapsed = SystemClock.elapsedRealtime();
19873        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19874        final int N = mLruProcesses.size();
19875
19876        if (false) {
19877            RuntimeException e = new RuntimeException();
19878            e.fillInStackTrace();
19879            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19880        }
19881
19882        // Reset state in all uid records.
19883        for (int i=mActiveUids.size()-1; i>=0; i--) {
19884            final UidRecord uidRec = mActiveUids.valueAt(i);
19885            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19886                    "Starting update of " + uidRec);
19887            uidRec.reset();
19888        }
19889
19890        mStackSupervisor.rankTaskLayersIfNeeded();
19891
19892        mAdjSeq++;
19893        mNewNumServiceProcs = 0;
19894        mNewNumAServiceProcs = 0;
19895
19896        final int emptyProcessLimit;
19897        final int cachedProcessLimit;
19898        if (mProcessLimit <= 0) {
19899            emptyProcessLimit = cachedProcessLimit = 0;
19900        } else if (mProcessLimit == 1) {
19901            emptyProcessLimit = 1;
19902            cachedProcessLimit = 0;
19903        } else {
19904            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19905            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19906        }
19907
19908        // Let's determine how many processes we have running vs.
19909        // how many slots we have for background processes; we may want
19910        // to put multiple processes in a slot of there are enough of
19911        // them.
19912        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19913                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19914        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19915        if (numEmptyProcs > cachedProcessLimit) {
19916            // If there are more empty processes than our limit on cached
19917            // processes, then use the cached process limit for the factor.
19918            // This ensures that the really old empty processes get pushed
19919            // down to the bottom, so if we are running low on memory we will
19920            // have a better chance at keeping around more cached processes
19921            // instead of a gazillion empty processes.
19922            numEmptyProcs = cachedProcessLimit;
19923        }
19924        int emptyFactor = numEmptyProcs/numSlots;
19925        if (emptyFactor < 1) emptyFactor = 1;
19926        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19927        if (cachedFactor < 1) cachedFactor = 1;
19928        int stepCached = 0;
19929        int stepEmpty = 0;
19930        int numCached = 0;
19931        int numEmpty = 0;
19932        int numTrimming = 0;
19933
19934        mNumNonCachedProcs = 0;
19935        mNumCachedHiddenProcs = 0;
19936
19937        // First update the OOM adjustment for each of the
19938        // application processes based on their current state.
19939        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19940        int nextCachedAdj = curCachedAdj+1;
19941        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19942        int nextEmptyAdj = curEmptyAdj+2;
19943        for (int i=N-1; i>=0; i--) {
19944            ProcessRecord app = mLruProcesses.get(i);
19945            if (!app.killedByAm && app.thread != null) {
19946                app.procStateChanged = false;
19947                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19948
19949                // If we haven't yet assigned the final cached adj
19950                // to the process, do that now.
19951                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19952                    switch (app.curProcState) {
19953                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19954                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19955                            // This process is a cached process holding activities...
19956                            // assign it the next cached value for that type, and then
19957                            // step that cached level.
19958                            app.curRawAdj = curCachedAdj;
19959                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19960                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19961                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19962                                    + ")");
19963                            if (curCachedAdj != nextCachedAdj) {
19964                                stepCached++;
19965                                if (stepCached >= cachedFactor) {
19966                                    stepCached = 0;
19967                                    curCachedAdj = nextCachedAdj;
19968                                    nextCachedAdj += 2;
19969                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19970                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19971                                    }
19972                                }
19973                            }
19974                            break;
19975                        default:
19976                            // For everything else, assign next empty cached process
19977                            // level and bump that up.  Note that this means that
19978                            // long-running services that have dropped down to the
19979                            // cached level will be treated as empty (since their process
19980                            // state is still as a service), which is what we want.
19981                            app.curRawAdj = curEmptyAdj;
19982                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19983                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19984                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19985                                    + ")");
19986                            if (curEmptyAdj != nextEmptyAdj) {
19987                                stepEmpty++;
19988                                if (stepEmpty >= emptyFactor) {
19989                                    stepEmpty = 0;
19990                                    curEmptyAdj = nextEmptyAdj;
19991                                    nextEmptyAdj += 2;
19992                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19993                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19994                                    }
19995                                }
19996                            }
19997                            break;
19998                    }
19999                }
20000
20001                applyOomAdjLocked(app, true, now, nowElapsed);
20002
20003                // Count the number of process types.
20004                switch (app.curProcState) {
20005                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20006                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20007                        mNumCachedHiddenProcs++;
20008                        numCached++;
20009                        if (numCached > cachedProcessLimit) {
20010                            app.kill("cached #" + numCached, true);
20011                        }
20012                        break;
20013                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20014                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20015                                && app.lastActivityTime < oldTime) {
20016                            app.kill("empty for "
20017                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20018                                    / 1000) + "s", true);
20019                        } else {
20020                            numEmpty++;
20021                            if (numEmpty > emptyProcessLimit) {
20022                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20023                            }
20024                        }
20025                        break;
20026                    default:
20027                        mNumNonCachedProcs++;
20028                        break;
20029                }
20030
20031                if (app.isolated && app.services.size() <= 0) {
20032                    // If this is an isolated process, and there are no
20033                    // services running in it, then the process is no longer
20034                    // needed.  We agressively kill these because we can by
20035                    // definition not re-use the same process again, and it is
20036                    // good to avoid having whatever code was running in them
20037                    // left sitting around after no longer needed.
20038                    app.kill("isolated not needed", true);
20039                } else {
20040                    // Keeping this process, update its uid.
20041                    final UidRecord uidRec = app.uidRecord;
20042                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20043                        uidRec.curProcState = app.curProcState;
20044                    }
20045                }
20046
20047                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20048                        && !app.killedByAm) {
20049                    numTrimming++;
20050                }
20051            }
20052        }
20053
20054        mNumServiceProcs = mNewNumServiceProcs;
20055
20056        // Now determine the memory trimming level of background processes.
20057        // Unfortunately we need to start at the back of the list to do this
20058        // properly.  We only do this if the number of background apps we
20059        // are managing to keep around is less than half the maximum we desire;
20060        // if we are keeping a good number around, we'll let them use whatever
20061        // memory they want.
20062        final int numCachedAndEmpty = numCached + numEmpty;
20063        int memFactor;
20064        if (numCached <= ProcessList.TRIM_CACHED_APPS
20065                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20066            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20067                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20068            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20069                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20070            } else {
20071                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20072            }
20073        } else {
20074            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20075        }
20076        // We always allow the memory level to go up (better).  We only allow it to go
20077        // down if we are in a state where that is allowed, *and* the total number of processes
20078        // has gone down since last time.
20079        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20080                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20081                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20082        if (memFactor > mLastMemoryLevel) {
20083            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20084                memFactor = mLastMemoryLevel;
20085                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20086            }
20087        }
20088        mLastMemoryLevel = memFactor;
20089        mLastNumProcesses = mLruProcesses.size();
20090        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20091        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20092        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20093            if (mLowRamStartTime == 0) {
20094                mLowRamStartTime = now;
20095            }
20096            int step = 0;
20097            int fgTrimLevel;
20098            switch (memFactor) {
20099                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20100                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20101                    break;
20102                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20103                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20104                    break;
20105                default:
20106                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20107                    break;
20108            }
20109            int factor = numTrimming/3;
20110            int minFactor = 2;
20111            if (mHomeProcess != null) minFactor++;
20112            if (mPreviousProcess != null) minFactor++;
20113            if (factor < minFactor) factor = minFactor;
20114            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20115            for (int i=N-1; i>=0; i--) {
20116                ProcessRecord app = mLruProcesses.get(i);
20117                if (allChanged || app.procStateChanged) {
20118                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20119                    app.procStateChanged = false;
20120                }
20121                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20122                        && !app.killedByAm) {
20123                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20124                        try {
20125                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20126                                    "Trimming memory of " + app.processName + " to " + curLevel);
20127                            app.thread.scheduleTrimMemory(curLevel);
20128                        } catch (RemoteException e) {
20129                        }
20130                        if (false) {
20131                            // For now we won't do this; our memory trimming seems
20132                            // to be good enough at this point that destroying
20133                            // activities causes more harm than good.
20134                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20135                                    && app != mHomeProcess && app != mPreviousProcess) {
20136                                // Need to do this on its own message because the stack may not
20137                                // be in a consistent state at this point.
20138                                // For these apps we will also finish their activities
20139                                // to help them free memory.
20140                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20141                            }
20142                        }
20143                    }
20144                    app.trimMemoryLevel = curLevel;
20145                    step++;
20146                    if (step >= factor) {
20147                        step = 0;
20148                        switch (curLevel) {
20149                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20150                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20151                                break;
20152                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20153                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20154                                break;
20155                        }
20156                    }
20157                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20158                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20159                            && app.thread != null) {
20160                        try {
20161                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20162                                    "Trimming memory of heavy-weight " + app.processName
20163                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20164                            app.thread.scheduleTrimMemory(
20165                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20166                        } catch (RemoteException e) {
20167                        }
20168                    }
20169                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20170                } else {
20171                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20172                            || app.systemNoUi) && app.pendingUiClean) {
20173                        // If this application is now in the background and it
20174                        // had done UI, then give it the special trim level to
20175                        // have it free UI resources.
20176                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20177                        if (app.trimMemoryLevel < level && app.thread != null) {
20178                            try {
20179                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20180                                        "Trimming memory of bg-ui " + app.processName
20181                                        + " to " + level);
20182                                app.thread.scheduleTrimMemory(level);
20183                            } catch (RemoteException e) {
20184                            }
20185                        }
20186                        app.pendingUiClean = false;
20187                    }
20188                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20189                        try {
20190                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20191                                    "Trimming memory of fg " + app.processName
20192                                    + " to " + fgTrimLevel);
20193                            app.thread.scheduleTrimMemory(fgTrimLevel);
20194                        } catch (RemoteException e) {
20195                        }
20196                    }
20197                    app.trimMemoryLevel = fgTrimLevel;
20198                }
20199            }
20200        } else {
20201            if (mLowRamStartTime != 0) {
20202                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20203                mLowRamStartTime = 0;
20204            }
20205            for (int i=N-1; i>=0; i--) {
20206                ProcessRecord app = mLruProcesses.get(i);
20207                if (allChanged || app.procStateChanged) {
20208                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20209                    app.procStateChanged = false;
20210                }
20211                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20212                        || app.systemNoUi) && app.pendingUiClean) {
20213                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20214                            && app.thread != null) {
20215                        try {
20216                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20217                                    "Trimming memory of ui hidden " + app.processName
20218                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20219                            app.thread.scheduleTrimMemory(
20220                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20221                        } catch (RemoteException e) {
20222                        }
20223                    }
20224                    app.pendingUiClean = false;
20225                }
20226                app.trimMemoryLevel = 0;
20227            }
20228        }
20229
20230        if (mAlwaysFinishActivities) {
20231            // Need to do this on its own message because the stack may not
20232            // be in a consistent state at this point.
20233            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20234        }
20235
20236        if (allChanged) {
20237            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20238        }
20239
20240        // Update from any uid changes.
20241        for (int i=mActiveUids.size()-1; i>=0; i--) {
20242            final UidRecord uidRec = mActiveUids.valueAt(i);
20243            int uidChange = UidRecord.CHANGE_PROCSTATE;
20244            if (uidRec.setProcState != uidRec.curProcState) {
20245                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20246                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20247                        + " to " + uidRec.curProcState);
20248                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20249                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20250                        uidRec.lastBackgroundTime = nowElapsed;
20251                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20252                            // Note: the background settle time is in elapsed realtime, while
20253                            // the handler time base is uptime.  All this means is that we may
20254                            // stop background uids later than we had intended, but that only
20255                            // happens because the device was sleeping so we are okay anyway.
20256                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20257                        }
20258                    }
20259                } else {
20260                    if (uidRec.idle) {
20261                        uidChange = UidRecord.CHANGE_ACTIVE;
20262                        uidRec.idle = false;
20263                    }
20264                    uidRec.lastBackgroundTime = 0;
20265                }
20266                uidRec.setProcState = uidRec.curProcState;
20267                enqueueUidChangeLocked(uidRec, -1, uidChange);
20268                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20269            }
20270        }
20271
20272        if (mProcessStats.shouldWriteNowLocked(now)) {
20273            mHandler.post(new Runnable() {
20274                @Override public void run() {
20275                    synchronized (ActivityManagerService.this) {
20276                        mProcessStats.writeStateAsyncLocked();
20277                    }
20278                }
20279            });
20280        }
20281
20282        if (DEBUG_OOM_ADJ) {
20283            final long duration = SystemClock.uptimeMillis() - now;
20284            if (false) {
20285                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20286                        new RuntimeException("here").fillInStackTrace());
20287            } else {
20288                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20289            }
20290        }
20291    }
20292
20293    final void idleUids() {
20294        synchronized (this) {
20295            final long nowElapsed = SystemClock.elapsedRealtime();
20296            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20297            long nextTime = 0;
20298            for (int i=mActiveUids.size()-1; i>=0; i--) {
20299                final UidRecord uidRec = mActiveUids.valueAt(i);
20300                final long bgTime = uidRec.lastBackgroundTime;
20301                if (bgTime > 0 && !uidRec.idle) {
20302                    if (bgTime <= maxBgTime) {
20303                        uidRec.idle = true;
20304                        doStopUidLocked(uidRec.uid, uidRec);
20305                    } else {
20306                        if (nextTime == 0 || nextTime > bgTime) {
20307                            nextTime = bgTime;
20308                        }
20309                    }
20310                }
20311            }
20312            if (nextTime > 0) {
20313                mHandler.removeMessages(IDLE_UIDS_MSG);
20314                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20315                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20316            }
20317        }
20318    }
20319
20320    final void runInBackgroundDisabled(int uid) {
20321        synchronized (this) {
20322            UidRecord uidRec = mActiveUids.get(uid);
20323            if (uidRec != null) {
20324                // This uid is actually running...  should it be considered background now?
20325                if (uidRec.idle) {
20326                    doStopUidLocked(uidRec.uid, uidRec);
20327                }
20328            } else {
20329                // This uid isn't actually running...  still send a report about it being "stopped".
20330                doStopUidLocked(uid, null);
20331            }
20332        }
20333    }
20334
20335    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20336        mServices.stopInBackgroundLocked(uid);
20337        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20338    }
20339
20340    final void trimApplications() {
20341        synchronized (this) {
20342            int i;
20343
20344            // First remove any unused application processes whose package
20345            // has been removed.
20346            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20347                final ProcessRecord app = mRemovedProcesses.get(i);
20348                if (app.activities.size() == 0
20349                        && app.curReceiver == null && app.services.size() == 0) {
20350                    Slog.i(
20351                        TAG, "Exiting empty application process "
20352                        + app.processName + " ("
20353                        + (app.thread != null ? app.thread.asBinder() : null)
20354                        + ")\n");
20355                    if (app.pid > 0 && app.pid != MY_PID) {
20356                        app.kill("empty", false);
20357                    } else {
20358                        try {
20359                            app.thread.scheduleExit();
20360                        } catch (Exception e) {
20361                            // Ignore exceptions.
20362                        }
20363                    }
20364                    cleanUpApplicationRecordLocked(app, false, true, -1);
20365                    mRemovedProcesses.remove(i);
20366
20367                    if (app.persistent) {
20368                        addAppLocked(app.info, false, null /* ABI override */);
20369                    }
20370                }
20371            }
20372
20373            // Now update the oom adj for all processes.
20374            updateOomAdjLocked();
20375        }
20376    }
20377
20378    /** This method sends the specified signal to each of the persistent apps */
20379    public void signalPersistentProcesses(int sig) throws RemoteException {
20380        if (sig != Process.SIGNAL_USR1) {
20381            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20382        }
20383
20384        synchronized (this) {
20385            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20386                    != PackageManager.PERMISSION_GRANTED) {
20387                throw new SecurityException("Requires permission "
20388                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20389            }
20390
20391            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20392                ProcessRecord r = mLruProcesses.get(i);
20393                if (r.thread != null && r.persistent) {
20394                    Process.sendSignal(r.pid, sig);
20395                }
20396            }
20397        }
20398    }
20399
20400    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20401        if (proc == null || proc == mProfileProc) {
20402            proc = mProfileProc;
20403            profileType = mProfileType;
20404            clearProfilerLocked();
20405        }
20406        if (proc == null) {
20407            return;
20408        }
20409        try {
20410            proc.thread.profilerControl(false, null, profileType);
20411        } catch (RemoteException e) {
20412            throw new IllegalStateException("Process disappeared");
20413        }
20414    }
20415
20416    private void clearProfilerLocked() {
20417        if (mProfileFd != null) {
20418            try {
20419                mProfileFd.close();
20420            } catch (IOException e) {
20421            }
20422        }
20423        mProfileApp = null;
20424        mProfileProc = null;
20425        mProfileFile = null;
20426        mProfileType = 0;
20427        mAutoStopProfiler = false;
20428        mSamplingInterval = 0;
20429    }
20430
20431    public boolean profileControl(String process, int userId, boolean start,
20432            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20433
20434        try {
20435            synchronized (this) {
20436                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20437                // its own permission.
20438                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20439                        != PackageManager.PERMISSION_GRANTED) {
20440                    throw new SecurityException("Requires permission "
20441                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20442                }
20443
20444                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20445                    throw new IllegalArgumentException("null profile info or fd");
20446                }
20447
20448                ProcessRecord proc = null;
20449                if (process != null) {
20450                    proc = findProcessLocked(process, userId, "profileControl");
20451                }
20452
20453                if (start && (proc == null || proc.thread == null)) {
20454                    throw new IllegalArgumentException("Unknown process: " + process);
20455                }
20456
20457                if (start) {
20458                    stopProfilerLocked(null, 0);
20459                    setProfileApp(proc.info, proc.processName, profilerInfo);
20460                    mProfileProc = proc;
20461                    mProfileType = profileType;
20462                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20463                    try {
20464                        fd = fd.dup();
20465                    } catch (IOException e) {
20466                        fd = null;
20467                    }
20468                    profilerInfo.profileFd = fd;
20469                    proc.thread.profilerControl(start, profilerInfo, profileType);
20470                    fd = null;
20471                    mProfileFd = null;
20472                } else {
20473                    stopProfilerLocked(proc, profileType);
20474                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20475                        try {
20476                            profilerInfo.profileFd.close();
20477                        } catch (IOException e) {
20478                        }
20479                    }
20480                }
20481
20482                return true;
20483            }
20484        } catch (RemoteException e) {
20485            throw new IllegalStateException("Process disappeared");
20486        } finally {
20487            if (profilerInfo != null && profilerInfo.profileFd != null) {
20488                try {
20489                    profilerInfo.profileFd.close();
20490                } catch (IOException e) {
20491                }
20492            }
20493        }
20494    }
20495
20496    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20497        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20498                userId, true, ALLOW_FULL_ONLY, callName, null);
20499        ProcessRecord proc = null;
20500        try {
20501            int pid = Integer.parseInt(process);
20502            synchronized (mPidsSelfLocked) {
20503                proc = mPidsSelfLocked.get(pid);
20504            }
20505        } catch (NumberFormatException e) {
20506        }
20507
20508        if (proc == null) {
20509            ArrayMap<String, SparseArray<ProcessRecord>> all
20510                    = mProcessNames.getMap();
20511            SparseArray<ProcessRecord> procs = all.get(process);
20512            if (procs != null && procs.size() > 0) {
20513                proc = procs.valueAt(0);
20514                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20515                    for (int i=1; i<procs.size(); i++) {
20516                        ProcessRecord thisProc = procs.valueAt(i);
20517                        if (thisProc.userId == userId) {
20518                            proc = thisProc;
20519                            break;
20520                        }
20521                    }
20522                }
20523            }
20524        }
20525
20526        return proc;
20527    }
20528
20529    public boolean dumpHeap(String process, int userId, boolean managed,
20530            String path, ParcelFileDescriptor fd) throws RemoteException {
20531
20532        try {
20533            synchronized (this) {
20534                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20535                // its own permission (same as profileControl).
20536                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20537                        != PackageManager.PERMISSION_GRANTED) {
20538                    throw new SecurityException("Requires permission "
20539                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20540                }
20541
20542                if (fd == null) {
20543                    throw new IllegalArgumentException("null fd");
20544                }
20545
20546                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20547                if (proc == null || proc.thread == null) {
20548                    throw new IllegalArgumentException("Unknown process: " + process);
20549                }
20550
20551                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20552                if (!isDebuggable) {
20553                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20554                        throw new SecurityException("Process not debuggable: " + proc);
20555                    }
20556                }
20557
20558                proc.thread.dumpHeap(managed, path, fd);
20559                fd = null;
20560                return true;
20561            }
20562        } catch (RemoteException e) {
20563            throw new IllegalStateException("Process disappeared");
20564        } finally {
20565            if (fd != null) {
20566                try {
20567                    fd.close();
20568                } catch (IOException e) {
20569                }
20570            }
20571        }
20572    }
20573
20574    @Override
20575    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20576            String reportPackage) {
20577        if (processName != null) {
20578            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20579                    "setDumpHeapDebugLimit()");
20580        } else {
20581            synchronized (mPidsSelfLocked) {
20582                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20583                if (proc == null) {
20584                    throw new SecurityException("No process found for calling pid "
20585                            + Binder.getCallingPid());
20586                }
20587                if (!Build.IS_DEBUGGABLE
20588                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20589                    throw new SecurityException("Not running a debuggable build");
20590                }
20591                processName = proc.processName;
20592                uid = proc.uid;
20593                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20594                    throw new SecurityException("Package " + reportPackage + " is not running in "
20595                            + proc);
20596                }
20597            }
20598        }
20599        synchronized (this) {
20600            if (maxMemSize > 0) {
20601                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20602            } else {
20603                if (uid != 0) {
20604                    mMemWatchProcesses.remove(processName, uid);
20605                } else {
20606                    mMemWatchProcesses.getMap().remove(processName);
20607                }
20608            }
20609        }
20610    }
20611
20612    @Override
20613    public void dumpHeapFinished(String path) {
20614        synchronized (this) {
20615            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20616                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20617                        + " does not match last pid " + mMemWatchDumpPid);
20618                return;
20619            }
20620            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20621                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20622                        + " does not match last path " + mMemWatchDumpFile);
20623                return;
20624            }
20625            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20626            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20627        }
20628    }
20629
20630    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20631    public void monitor() {
20632        synchronized (this) { }
20633    }
20634
20635    void onCoreSettingsChange(Bundle settings) {
20636        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20637            ProcessRecord processRecord = mLruProcesses.get(i);
20638            try {
20639                if (processRecord.thread != null) {
20640                    processRecord.thread.setCoreSettings(settings);
20641                }
20642            } catch (RemoteException re) {
20643                /* ignore */
20644            }
20645        }
20646    }
20647
20648    // Multi-user methods
20649
20650    /**
20651     * Start user, if its not already running, but don't bring it to foreground.
20652     */
20653    @Override
20654    public boolean startUserInBackground(final int userId) {
20655        return mUserController.startUser(userId, /* foreground */ false);
20656    }
20657
20658    @Override
20659    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20660        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20661    }
20662
20663    @Override
20664    public boolean switchUser(final int targetUserId) {
20665        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20666        UserInfo currentUserInfo;
20667        UserInfo targetUserInfo;
20668        synchronized (this) {
20669            int currentUserId = mUserController.getCurrentUserIdLocked();
20670            currentUserInfo = mUserController.getUserInfo(currentUserId);
20671            targetUserInfo = mUserController.getUserInfo(targetUserId);
20672            if (targetUserInfo == null) {
20673                Slog.w(TAG, "No user info for user #" + targetUserId);
20674                return false;
20675            }
20676            if (!targetUserInfo.supportsSwitchTo()) {
20677                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20678                return false;
20679            }
20680            if (targetUserInfo.isManagedProfile()) {
20681                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20682                return false;
20683            }
20684            mUserController.setTargetUserIdLocked(targetUserId);
20685        }
20686        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20687        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20688        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20689        return true;
20690    }
20691
20692    void scheduleStartProfilesLocked() {
20693        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20694            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20695                    DateUtils.SECOND_IN_MILLIS);
20696        }
20697    }
20698
20699    @Override
20700    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20701        return mUserController.stopUser(userId, force, callback);
20702    }
20703
20704    @Override
20705    public UserInfo getCurrentUser() {
20706        return mUserController.getCurrentUser();
20707    }
20708
20709    @Override
20710    public boolean isUserRunning(int userId, int flags) {
20711        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20712                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20713            String msg = "Permission Denial: isUserRunning() from pid="
20714                    + Binder.getCallingPid()
20715                    + ", uid=" + Binder.getCallingUid()
20716                    + " requires " + INTERACT_ACROSS_USERS;
20717            Slog.w(TAG, msg);
20718            throw new SecurityException(msg);
20719        }
20720        synchronized (this) {
20721            return mUserController.isUserRunningLocked(userId, flags);
20722        }
20723    }
20724
20725    @Override
20726    public int[] getRunningUserIds() {
20727        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20728                != PackageManager.PERMISSION_GRANTED) {
20729            String msg = "Permission Denial: isUserRunning() from pid="
20730                    + Binder.getCallingPid()
20731                    + ", uid=" + Binder.getCallingUid()
20732                    + " requires " + INTERACT_ACROSS_USERS;
20733            Slog.w(TAG, msg);
20734            throw new SecurityException(msg);
20735        }
20736        synchronized (this) {
20737            return mUserController.getStartedUserArrayLocked();
20738        }
20739    }
20740
20741    @Override
20742    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20743        mUserController.registerUserSwitchObserver(observer);
20744    }
20745
20746    @Override
20747    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20748        mUserController.unregisterUserSwitchObserver(observer);
20749    }
20750
20751    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20752        if (info == null) return null;
20753        ApplicationInfo newInfo = new ApplicationInfo(info);
20754        newInfo.initForUser(userId);
20755        return newInfo;
20756    }
20757
20758    public boolean isUserStopped(int userId) {
20759        synchronized (this) {
20760            return mUserController.getStartedUserStateLocked(userId) == null;
20761        }
20762    }
20763
20764    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20765        if (aInfo == null
20766                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20767            return aInfo;
20768        }
20769
20770        ActivityInfo info = new ActivityInfo(aInfo);
20771        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20772        return info;
20773    }
20774
20775    private boolean processSanityChecksLocked(ProcessRecord process) {
20776        if (process == null || process.thread == null) {
20777            return false;
20778        }
20779
20780        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20781        if (!isDebuggable) {
20782            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20783                return false;
20784            }
20785        }
20786
20787        return true;
20788    }
20789
20790    public boolean startBinderTracking() throws RemoteException {
20791        synchronized (this) {
20792            mBinderTransactionTrackingEnabled = true;
20793            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20794            // permission (same as profileControl).
20795            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20796                    != PackageManager.PERMISSION_GRANTED) {
20797                throw new SecurityException("Requires permission "
20798                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20799            }
20800
20801            for (int i = 0; i < mLruProcesses.size(); i++) {
20802                ProcessRecord process = mLruProcesses.get(i);
20803                if (!processSanityChecksLocked(process)) {
20804                    continue;
20805                }
20806                try {
20807                    process.thread.startBinderTracking();
20808                } catch (RemoteException e) {
20809                    Log.v(TAG, "Process disappared");
20810                }
20811            }
20812            return true;
20813        }
20814    }
20815
20816    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20817        try {
20818            synchronized (this) {
20819                mBinderTransactionTrackingEnabled = false;
20820                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20821                // permission (same as profileControl).
20822                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20823                        != PackageManager.PERMISSION_GRANTED) {
20824                    throw new SecurityException("Requires permission "
20825                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20826                }
20827
20828                if (fd == null) {
20829                    throw new IllegalArgumentException("null fd");
20830                }
20831
20832                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20833                pw.println("Binder transaction traces for all processes.\n");
20834                for (ProcessRecord process : mLruProcesses) {
20835                    if (!processSanityChecksLocked(process)) {
20836                        continue;
20837                    }
20838
20839                    pw.println("Traces for process: " + process.processName);
20840                    pw.flush();
20841                    try {
20842                        TransferPipe tp = new TransferPipe();
20843                        try {
20844                            process.thread.stopBinderTrackingAndDump(
20845                                    tp.getWriteFd().getFileDescriptor());
20846                            tp.go(fd.getFileDescriptor());
20847                        } finally {
20848                            tp.kill();
20849                        }
20850                    } catch (IOException e) {
20851                        pw.println("Failure while dumping IPC traces from " + process +
20852                                ".  Exception: " + e);
20853                        pw.flush();
20854                    } catch (RemoteException e) {
20855                        pw.println("Got a RemoteException while dumping IPC traces from " +
20856                                process + ".  Exception: " + e);
20857                        pw.flush();
20858                    }
20859                }
20860                fd = null;
20861                return true;
20862            }
20863        } finally {
20864            if (fd != null) {
20865                try {
20866                    fd.close();
20867                } catch (IOException e) {
20868                }
20869            }
20870        }
20871    }
20872
20873    private final class LocalService extends ActivityManagerInternal {
20874        @Override
20875        public void onWakefulnessChanged(int wakefulness) {
20876            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20877        }
20878
20879        @Override
20880        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20881                String processName, String abiOverride, int uid, Runnable crashHandler) {
20882            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20883                    processName, abiOverride, uid, crashHandler);
20884        }
20885
20886        @Override
20887        public SleepToken acquireSleepToken(String tag) {
20888            Preconditions.checkNotNull(tag);
20889
20890            synchronized (ActivityManagerService.this) {
20891                SleepTokenImpl token = new SleepTokenImpl(tag);
20892                mSleepTokens.add(token);
20893                updateSleepIfNeededLocked();
20894                return token;
20895            }
20896        }
20897
20898        @Override
20899        public ComponentName getHomeActivityForUser(int userId) {
20900            synchronized (ActivityManagerService.this) {
20901                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20902                return homeActivity == null ? null : homeActivity.realActivity;
20903            }
20904        }
20905
20906        @Override
20907        public void onUserRemoved(int userId) {
20908            synchronized (ActivityManagerService.this) {
20909                ActivityManagerService.this.onUserStoppedLocked(userId);
20910            }
20911        }
20912
20913        @Override
20914        public void onLocalVoiceInteractionStarted(IBinder activity,
20915                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20916            synchronized (ActivityManagerService.this) {
20917                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20918                        voiceSession, voiceInteractor);
20919            }
20920        }
20921
20922        @Override
20923        public void notifyStartingWindowDrawn() {
20924            synchronized (ActivityManagerService.this) {
20925                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20926            }
20927        }
20928
20929        @Override
20930        public void notifyAppTransitionStarting(int reason) {
20931            synchronized (ActivityManagerService.this) {
20932                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20933            }
20934        }
20935
20936        @Override
20937        public void notifyAppTransitionFinished() {
20938            synchronized (ActivityManagerService.this) {
20939                mStackSupervisor.notifyAppTransitionDone();
20940            }
20941        }
20942
20943        @Override
20944        public void notifyAppTransitionCancelled() {
20945            synchronized (ActivityManagerService.this) {
20946                mStackSupervisor.notifyAppTransitionDone();
20947            }
20948        }
20949
20950        @Override
20951        public List<IBinder> getTopVisibleActivities() {
20952            synchronized (ActivityManagerService.this) {
20953                return mStackSupervisor.getTopVisibleActivities();
20954            }
20955        }
20956    }
20957
20958    private final class SleepTokenImpl extends SleepToken {
20959        private final String mTag;
20960        private final long mAcquireTime;
20961
20962        public SleepTokenImpl(String tag) {
20963            mTag = tag;
20964            mAcquireTime = SystemClock.uptimeMillis();
20965        }
20966
20967        @Override
20968        public void release() {
20969            synchronized (ActivityManagerService.this) {
20970                if (mSleepTokens.remove(this)) {
20971                    updateSleepIfNeededLocked();
20972                }
20973            }
20974        }
20975
20976        @Override
20977        public String toString() {
20978            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20979        }
20980    }
20981
20982    /**
20983     * An implementation of IAppTask, that allows an app to manage its own tasks via
20984     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20985     * only the process that calls getAppTasks() can call the AppTask methods.
20986     */
20987    class AppTaskImpl extends IAppTask.Stub {
20988        private int mTaskId;
20989        private int mCallingUid;
20990
20991        public AppTaskImpl(int taskId, int callingUid) {
20992            mTaskId = taskId;
20993            mCallingUid = callingUid;
20994        }
20995
20996        private void checkCaller() {
20997            if (mCallingUid != Binder.getCallingUid()) {
20998                throw new SecurityException("Caller " + mCallingUid
20999                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21000            }
21001        }
21002
21003        @Override
21004        public void finishAndRemoveTask() {
21005            checkCaller();
21006
21007            synchronized (ActivityManagerService.this) {
21008                long origId = Binder.clearCallingIdentity();
21009                try {
21010                    // We remove the task from recents to preserve backwards
21011                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21012                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21013                    }
21014                } finally {
21015                    Binder.restoreCallingIdentity(origId);
21016                }
21017            }
21018        }
21019
21020        @Override
21021        public ActivityManager.RecentTaskInfo getTaskInfo() {
21022            checkCaller();
21023
21024            synchronized (ActivityManagerService.this) {
21025                long origId = Binder.clearCallingIdentity();
21026                try {
21027                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21028                    if (tr == null) {
21029                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21030                    }
21031                    return createRecentTaskInfoFromTaskRecord(tr);
21032                } finally {
21033                    Binder.restoreCallingIdentity(origId);
21034                }
21035            }
21036        }
21037
21038        @Override
21039        public void moveToFront() {
21040            checkCaller();
21041            // Will bring task to front if it already has a root activity.
21042            final long origId = Binder.clearCallingIdentity();
21043            try {
21044                synchronized (this) {
21045                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21046                }
21047            } finally {
21048                Binder.restoreCallingIdentity(origId);
21049            }
21050        }
21051
21052        @Override
21053        public int startActivity(IBinder whoThread, String callingPackage,
21054                Intent intent, String resolvedType, Bundle bOptions) {
21055            checkCaller();
21056
21057            int callingUser = UserHandle.getCallingUserId();
21058            TaskRecord tr;
21059            IApplicationThread appThread;
21060            synchronized (ActivityManagerService.this) {
21061                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21062                if (tr == null) {
21063                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21064                }
21065                appThread = ApplicationThreadNative.asInterface(whoThread);
21066                if (appThread == null) {
21067                    throw new IllegalArgumentException("Bad app thread " + appThread);
21068                }
21069            }
21070            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21071                    resolvedType, null, null, null, null, 0, 0, null, null,
21072                    null, bOptions, false, callingUser, null, tr);
21073        }
21074
21075        @Override
21076        public void setExcludeFromRecents(boolean exclude) {
21077            checkCaller();
21078
21079            synchronized (ActivityManagerService.this) {
21080                long origId = Binder.clearCallingIdentity();
21081                try {
21082                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21083                    if (tr == null) {
21084                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21085                    }
21086                    Intent intent = tr.getBaseIntent();
21087                    if (exclude) {
21088                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21089                    } else {
21090                        intent.setFlags(intent.getFlags()
21091                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21092                    }
21093                } finally {
21094                    Binder.restoreCallingIdentity(origId);
21095                }
21096            }
21097        }
21098    }
21099
21100    /**
21101     * Kill processes for the user with id userId and that depend on the package named packageName
21102     */
21103    @Override
21104    public void killPackageDependents(String packageName, int userId) {
21105        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21106        if (packageName == null) {
21107            throw new NullPointerException(
21108                    "Cannot kill the dependents of a package without its name.");
21109        }
21110
21111        long callingId = Binder.clearCallingIdentity();
21112        IPackageManager pm = AppGlobals.getPackageManager();
21113        int pkgUid = -1;
21114        try {
21115            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21116        } catch (RemoteException e) {
21117        }
21118        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21119            throw new IllegalArgumentException(
21120                    "Cannot kill dependents of non-existing package " + packageName);
21121        }
21122        try {
21123            synchronized(this) {
21124                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21125                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21126                        "dep: " + packageName);
21127            }
21128        } finally {
21129            Binder.restoreCallingIdentity(callingId);
21130        }
21131    }
21132}
21133