ActivityManagerService.java revision 2c11dc99632354836281cbe3000b911e72a30d14
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.FORCE_FOCUS;
345import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
346import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
347import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
348import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
352import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
353import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
354import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
355import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
357import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
358import static org.xmlpull.v1.XmlPullParser.START_TAG;
359
360public final class ActivityManagerService extends ActivityManagerNative
361        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
362
363    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
364    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
365    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
366    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
367    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
368    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
369    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
370    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
371    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
372    private static final String TAG_LRU = TAG + POSTFIX_LRU;
373    private static final String TAG_MU = TAG + POSTFIX_MU;
374    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
375    private static final String TAG_POWER = TAG + POSTFIX_POWER;
376    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
377    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
378    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
379    private static final String TAG_PSS = TAG + POSTFIX_PSS;
380    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
381    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
382    private static final String TAG_STACK = TAG + POSTFIX_STACK;
383    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
384    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
385    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
386    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
387    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
388
389    /** Control over CPU and battery monitoring */
390    // write battery stats every 30 minutes.
391    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
392    static final boolean MONITOR_CPU_USAGE = true;
393    // don't sample cpu less than every 5 seconds.
394    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
395    // wait possibly forever for next cpu sample.
396    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
397    static final boolean MONITOR_THREAD_CPU_USAGE = false;
398
399    // The flags that are set for all calls we make to the package manager.
400    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
401
402    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
403
404    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
405
406    // Amount of time after a call to stopAppSwitches() during which we will
407    // prevent further untrusted switches from happening.
408    static final long APP_SWITCH_DELAY_TIME = 5*1000;
409
410    // How long we wait for a launched process to attach to the activity manager
411    // before we decide it's never going to come up for real.
412    static final int PROC_START_TIMEOUT = 10*1000;
413    // How long we wait for an attached process to publish its content providers
414    // before we decide it must be hung.
415    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
416
417    // How long we will retain processes hosting content providers in the "last activity"
418    // state before allowing them to drop down to the regular cached LRU list.  This is
419    // to avoid thrashing of provider processes under low memory situations.
420    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
421
422    // How long we wait for a launched process to attach to the activity manager
423    // before we decide it's never going to come up for real, when the process was
424    // started with a wrapper for instrumentation (such as Valgrind) because it
425    // could take much longer than usual.
426    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
427
428    // How long to wait after going idle before forcing apps to GC.
429    static final int GC_TIMEOUT = 5*1000;
430
431    // The minimum amount of time between successive GC requests for a process.
432    static final int GC_MIN_INTERVAL = 60*1000;
433
434    // The minimum amount of time between successive PSS requests for a process.
435    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process
438    // when the request is due to the memory state being lowered.
439    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
440
441    // The rate at which we check for apps using excessive power -- 15 mins.
442    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
443
444    // The minimum sample duration we will allow before deciding we have
445    // enough data on wake locks to start killing things.
446    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
447
448    // The minimum sample duration we will allow before deciding we have
449    // enough data on CPU usage to start killing things.
450    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
451
452    // How long we allow a receiver to run before giving up on it.
453    static final int BROADCAST_FG_TIMEOUT = 10*1000;
454    static final int BROADCAST_BG_TIMEOUT = 60*1000;
455
456    // How long we wait until we timeout on key dispatching.
457    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
458
459    // How long we wait until we timeout on key dispatching during instrumentation.
460    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
461
462    // This is the amount of time an app needs to be running a foreground service before
463    // we will consider it to be doing interaction for usage stats.
464    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
465
466    // Maximum amount of time we will allow to elapse before re-reporting usage stats
467    // interaction with foreground processes.
468    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
469
470    // This is the amount of time we allow an app to settle after it goes into the background,
471    // before we start restricting what it can do.
472    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
473
474    // How long to wait in getAssistContextExtras for the activity and foreground services
475    // to respond with the result.
476    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
477
478    // How long top wait when going through the modern assist (which doesn't need to block
479    // on getting this result before starting to launch its UI).
480    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
481
482    // Maximum number of persisted Uri grants a package is allowed
483    static final int MAX_PERSISTED_URI_GRANTS = 128;
484
485    static final int MY_PID = Process.myPid();
486
487    static final String[] EMPTY_STRING_ARRAY = new String[0];
488
489    // How many bytes to write into the dropbox log before truncating
490    static final int DROPBOX_MAX_SIZE = 256 * 1024;
491
492    // Access modes for handleIncomingUser.
493    static final int ALLOW_NON_FULL = 0;
494    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
495    static final int ALLOW_FULL_ONLY = 2;
496
497    // Delay in notifying task stack change listeners (in millis)
498    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
499
500    // Necessary ApplicationInfo flags to mark an app as persistent
501    private static final int PERSISTENT_MASK =
502            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
503
504    // Intent sent when remote bugreport collection has been completed
505    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
506            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
507
508    // Delay to disable app launch boost
509    static final int APP_BOOST_MESSAGE_DELAY = 3000;
510    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
511    static final int APP_BOOST_TIMEOUT = 2500;
512
513    // Used to indicate that a task is removed it should also be removed from recents.
514    private static final boolean REMOVE_FROM_RECENTS = true;
515    // Used to indicate that an app transition should be animated.
516    static final boolean ANIMATE = true;
517
518    // Determines whether to take full screen screenshots
519    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
520    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
521
522    private static native int nativeMigrateToBoost();
523    private static native int nativeMigrateFromBoost();
524    private boolean mIsBoosted = false;
525    private long mBoostStartTime = 0;
526
527    /** All system services */
528    SystemServiceManager mSystemServiceManager;
529
530    private Installer mInstaller;
531
532    /** Run all ActivityStacks through this */
533    final ActivityStackSupervisor mStackSupervisor;
534
535    final ActivityStarter mActivityStarter;
536
537    /** Task stack change listeners. */
538    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
539            new RemoteCallbackList<ITaskStackListener>();
540
541    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
542
543    public IntentFirewall mIntentFirewall;
544
545    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
546    // default actuion automatically.  Important for devices without direct input
547    // devices.
548    private boolean mShowDialogs = true;
549    private boolean mInVrMode = false;
550
551    BroadcastQueue mFgBroadcastQueue;
552    BroadcastQueue mBgBroadcastQueue;
553    // Convenient for easy iteration over the queues. Foreground is first
554    // so that dispatch of foreground broadcasts gets precedence.
555    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
556
557    BroadcastQueue broadcastQueueForIntent(Intent intent) {
558        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
559        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
560                "Broadcast intent " + intent + " on "
561                + (isFg ? "foreground" : "background") + " queue");
562        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
563    }
564
565    /**
566     * Activity we have told the window manager to have key focus.
567     */
568    ActivityRecord mFocusedActivity = null;
569
570    /**
571     * User id of the last activity mFocusedActivity was set to.
572     */
573    private int mLastFocusedUserId;
574
575    /**
576     * If non-null, we are tracking the time the user spends in the currently focused app.
577     */
578    private AppTimeTracker mCurAppTimeTracker;
579
580    /**
581     * List of intents that were used to start the most recent tasks.
582     */
583    final RecentTasks mRecentTasks;
584
585    /**
586     * For addAppTask: cached of the last activity component that was added.
587     */
588    ComponentName mLastAddedTaskComponent;
589
590    /**
591     * For addAppTask: cached of the last activity uid that was added.
592     */
593    int mLastAddedTaskUid;
594
595    /**
596     * For addAppTask: cached of the last ActivityInfo that was added.
597     */
598    ActivityInfo mLastAddedTaskActivity;
599
600    /**
601     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
602     */
603    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
604
605    /**
606     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
607     */
608    String mDeviceOwnerName;
609
610    final UserController mUserController;
611
612    final AppErrors mAppErrors;
613
614    boolean mDoingSetFocusedActivity;
615
616    public boolean canShowErrorDialogs() {
617        return mShowDialogs && !mSleeping && !mShuttingDown;
618    }
619
620    public class PendingAssistExtras extends Binder implements Runnable {
621        public final ActivityRecord activity;
622        public final Bundle extras;
623        public final Intent intent;
624        public final String hint;
625        public final IResultReceiver receiver;
626        public final int userHandle;
627        public boolean haveResult = false;
628        public Bundle result = null;
629        public AssistStructure structure = null;
630        public AssistContent content = null;
631        public Bundle receiverExtras;
632
633        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
634                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
635            activity = _activity;
636            extras = _extras;
637            intent = _intent;
638            hint = _hint;
639            receiver = _receiver;
640            receiverExtras = _receiverExtras;
641            userHandle = _userHandle;
642        }
643        @Override
644        public void run() {
645            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
646            synchronized (this) {
647                haveResult = true;
648                notifyAll();
649            }
650            pendingAssistExtrasTimedOut(this);
651        }
652    }
653
654    final ArrayList<PendingAssistExtras> mPendingAssistExtras
655            = new ArrayList<PendingAssistExtras>();
656
657    /**
658     * Process management.
659     */
660    final ProcessList mProcessList = new ProcessList();
661
662    /**
663     * All of the applications we currently have running organized by name.
664     * The keys are strings of the application package name (as
665     * returned by the package manager), and the keys are ApplicationRecord
666     * objects.
667     */
668    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
669
670    /**
671     * Tracking long-term execution of processes to look for abuse and other
672     * bad app behavior.
673     */
674    final ProcessStatsService mProcessStats;
675
676    /**
677     * The currently running isolated processes.
678     */
679    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
680
681    /**
682     * Counter for assigning isolated process uids, to avoid frequently reusing the
683     * same ones.
684     */
685    int mNextIsolatedProcessUid = 0;
686
687    /**
688     * The currently running heavy-weight process, if any.
689     */
690    ProcessRecord mHeavyWeightProcess = null;
691
692    /**
693     * All of the processes we currently have running organized by pid.
694     * The keys are the pid running the application.
695     *
696     * <p>NOTE: This object is protected by its own lock, NOT the global
697     * activity manager lock!
698     */
699    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
700
701    /**
702     * All of the processes that have been forced to be foreground.  The key
703     * is the pid of the caller who requested it (we hold a death
704     * link on it).
705     */
706    abstract class ForegroundToken implements IBinder.DeathRecipient {
707        int pid;
708        IBinder token;
709    }
710    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
711
712    /**
713     * List of records for processes that someone had tried to start before the
714     * system was ready.  We don't start them at that point, but ensure they
715     * are started by the time booting is complete.
716     */
717    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
718
719    /**
720     * List of persistent applications that are in the process
721     * of being started.
722     */
723    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
724
725    /**
726     * Processes that are being forcibly torn down.
727     */
728    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
729
730    /**
731     * List of running applications, sorted by recent usage.
732     * The first entry in the list is the least recently used.
733     */
734    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
735
736    /**
737     * Where in mLruProcesses that the processes hosting activities start.
738     */
739    int mLruProcessActivityStart = 0;
740
741    /**
742     * Where in mLruProcesses that the processes hosting services start.
743     * This is after (lower index) than mLruProcessesActivityStart.
744     */
745    int mLruProcessServiceStart = 0;
746
747    /**
748     * List of processes that should gc as soon as things are idle.
749     */
750    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
751
752    /**
753     * Processes we want to collect PSS data from.
754     */
755    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
756
757    private boolean mBinderTransactionTrackingEnabled = false;
758
759    /**
760     * Last time we requested PSS data of all processes.
761     */
762    long mLastFullPssTime = SystemClock.uptimeMillis();
763
764    /**
765     * If set, the next time we collect PSS data we should do a full collection
766     * with data from native processes and the kernel.
767     */
768    boolean mFullPssPending = false;
769
770    /**
771     * This is the process holding what we currently consider to be
772     * the "home" activity.
773     */
774    ProcessRecord mHomeProcess;
775
776    /**
777     * This is the process holding the activity the user last visited that
778     * is in a different process from the one they are currently in.
779     */
780    ProcessRecord mPreviousProcess;
781
782    /**
783     * The time at which the previous process was last visible.
784     */
785    long mPreviousProcessVisibleTime;
786
787    /**
788     * Track all uids that have actively running processes.
789     */
790    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
791
792    /**
793     * This is for verifying the UID report flow.
794     */
795    static final boolean VALIDATE_UID_STATES = true;
796    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
797
798    /**
799     * Packages that the user has asked to have run in screen size
800     * compatibility mode instead of filling the screen.
801     */
802    final CompatModePackages mCompatModePackages;
803
804    /**
805     * Set of IntentSenderRecord objects that are currently active.
806     */
807    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
808            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
809
810    /**
811     * Fingerprints (hashCode()) of stack traces that we've
812     * already logged DropBox entries for.  Guarded by itself.  If
813     * something (rogue user app) forces this over
814     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
815     */
816    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
817    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
818
819    /**
820     * Strict Mode background batched logging state.
821     *
822     * The string buffer is guarded by itself, and its lock is also
823     * used to determine if another batched write is already
824     * in-flight.
825     */
826    private final StringBuilder mStrictModeBuffer = new StringBuilder();
827
828    /**
829     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
830     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
831     */
832    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
833
834    /**
835     * Resolver for broadcast intents to registered receivers.
836     * Holds BroadcastFilter (subclass of IntentFilter).
837     */
838    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
839            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
840        @Override
841        protected boolean allowFilterResult(
842                BroadcastFilter filter, List<BroadcastFilter> dest) {
843            IBinder target = filter.receiverList.receiver.asBinder();
844            for (int i = dest.size() - 1; i >= 0; i--) {
845                if (dest.get(i).receiverList.receiver.asBinder() == target) {
846                    return false;
847                }
848            }
849            return true;
850        }
851
852        @Override
853        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
854            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
855                    || userId == filter.owningUserId) {
856                return super.newResult(filter, match, userId);
857            }
858            return null;
859        }
860
861        @Override
862        protected BroadcastFilter[] newArray(int size) {
863            return new BroadcastFilter[size];
864        }
865
866        @Override
867        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
868            return packageName.equals(filter.packageName);
869        }
870    };
871
872    /**
873     * State of all active sticky broadcasts per user.  Keys are the action of the
874     * sticky Intent, values are an ArrayList of all broadcasted intents with
875     * that action (which should usually be one).  The SparseArray is keyed
876     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
877     * for stickies that are sent to all users.
878     */
879    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
880            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
881
882    final ActiveServices mServices;
883
884    final static class Association {
885        final int mSourceUid;
886        final String mSourceProcess;
887        final int mTargetUid;
888        final ComponentName mTargetComponent;
889        final String mTargetProcess;
890
891        int mCount;
892        long mTime;
893
894        int mNesting;
895        long mStartTime;
896
897        // states of the source process when the bind occurred.
898        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
899        long mLastStateUptime;
900        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
901                - ActivityManager.MIN_PROCESS_STATE+1];
902
903        Association(int sourceUid, String sourceProcess, int targetUid,
904                ComponentName targetComponent, String targetProcess) {
905            mSourceUid = sourceUid;
906            mSourceProcess = sourceProcess;
907            mTargetUid = targetUid;
908            mTargetComponent = targetComponent;
909            mTargetProcess = targetProcess;
910        }
911    }
912
913    /**
914     * When service association tracking is enabled, this is all of the associations we
915     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
916     * -> association data.
917     */
918    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
919            mAssociations = new SparseArray<>();
920    boolean mTrackingAssociations;
921
922    /**
923     * Backup/restore process management
924     */
925    String mBackupAppName = null;
926    BackupRecord mBackupTarget = null;
927
928    final ProviderMap mProviderMap;
929
930    /**
931     * List of content providers who have clients waiting for them.  The
932     * application is currently being launched and the provider will be
933     * removed from this list once it is published.
934     */
935    final ArrayList<ContentProviderRecord> mLaunchingProviders
936            = new ArrayList<ContentProviderRecord>();
937
938    /**
939     * File storing persisted {@link #mGrantedUriPermissions}.
940     */
941    private final AtomicFile mGrantFile;
942
943    /** XML constants used in {@link #mGrantFile} */
944    private static final String TAG_URI_GRANTS = "uri-grants";
945    private static final String TAG_URI_GRANT = "uri-grant";
946    private static final String ATTR_USER_HANDLE = "userHandle";
947    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
948    private static final String ATTR_TARGET_USER_ID = "targetUserId";
949    private static final String ATTR_SOURCE_PKG = "sourcePkg";
950    private static final String ATTR_TARGET_PKG = "targetPkg";
951    private static final String ATTR_URI = "uri";
952    private static final String ATTR_MODE_FLAGS = "modeFlags";
953    private static final String ATTR_CREATED_TIME = "createdTime";
954    private static final String ATTR_PREFIX = "prefix";
955
956    /**
957     * Global set of specific {@link Uri} permissions that have been granted.
958     * This optimized lookup structure maps from {@link UriPermission#targetUid}
959     * to {@link UriPermission#uri} to {@link UriPermission}.
960     */
961    @GuardedBy("this")
962    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
963            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
964
965    public static class GrantUri {
966        public final int sourceUserId;
967        public final Uri uri;
968        public boolean prefix;
969
970        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
971            this.sourceUserId = sourceUserId;
972            this.uri = uri;
973            this.prefix = prefix;
974        }
975
976        @Override
977        public int hashCode() {
978            int hashCode = 1;
979            hashCode = 31 * hashCode + sourceUserId;
980            hashCode = 31 * hashCode + uri.hashCode();
981            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
982            return hashCode;
983        }
984
985        @Override
986        public boolean equals(Object o) {
987            if (o instanceof GrantUri) {
988                GrantUri other = (GrantUri) o;
989                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
990                        && prefix == other.prefix;
991            }
992            return false;
993        }
994
995        @Override
996        public String toString() {
997            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
998            if (prefix) result += " [prefix]";
999            return result;
1000        }
1001
1002        public String toSafeString() {
1003            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1004            if (prefix) result += " [prefix]";
1005            return result;
1006        }
1007
1008        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1009            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1010                    ContentProvider.getUriWithoutUserId(uri), false);
1011        }
1012    }
1013
1014    CoreSettingsObserver mCoreSettingsObserver;
1015
1016    FontScaleSettingObserver mFontScaleSettingObserver;
1017
1018    private final class FontScaleSettingObserver extends ContentObserver {
1019        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1020
1021        public FontScaleSettingObserver() {
1022            super(mHandler);
1023            ContentResolver resolver = mContext.getContentResolver();
1024            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1025        }
1026
1027        @Override
1028        public void onChange(boolean selfChange, Uri uri) {
1029            if (mFontScaleUri.equals(uri)) {
1030                updateFontScaleIfNeeded();
1031            }
1032        }
1033    }
1034
1035    /**
1036     * Thread-local storage used to carry caller permissions over through
1037     * indirect content-provider access.
1038     */
1039    private class Identity {
1040        public final IBinder token;
1041        public final int pid;
1042        public final int uid;
1043
1044        Identity(IBinder _token, int _pid, int _uid) {
1045            token = _token;
1046            pid = _pid;
1047            uid = _uid;
1048        }
1049    }
1050
1051    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1052
1053    /**
1054     * All information we have collected about the runtime performance of
1055     * any user id that can impact battery performance.
1056     */
1057    final BatteryStatsService mBatteryStatsService;
1058
1059    /**
1060     * Information about component usage
1061     */
1062    UsageStatsManagerInternal mUsageStatsService;
1063
1064    /**
1065     * Access to DeviceIdleController service.
1066     */
1067    DeviceIdleController.LocalService mLocalDeviceIdleController;
1068
1069    /**
1070     * Information about and control over application operations
1071     */
1072    final AppOpsService mAppOpsService;
1073
1074    /**
1075     * Current configuration information.  HistoryRecord objects are given
1076     * a reference to this object to indicate which configuration they are
1077     * currently running in, so this object must be kept immutable.
1078     */
1079    Configuration mConfiguration = new Configuration();
1080
1081    /**
1082     * Current sequencing integer of the configuration, for skipping old
1083     * configurations.
1084     */
1085    int mConfigurationSeq = 0;
1086
1087    boolean mSuppressResizeConfigChanges = false;
1088
1089    /**
1090     * Hardware-reported OpenGLES version.
1091     */
1092    final int GL_ES_VERSION;
1093
1094    /**
1095     * List of initialization arguments to pass to all processes when binding applications to them.
1096     * For example, references to the commonly used services.
1097     */
1098    HashMap<String, IBinder> mAppBindArgs;
1099
1100    /**
1101     * Temporary to avoid allocations.  Protected by main lock.
1102     */
1103    final StringBuilder mStringBuilder = new StringBuilder(256);
1104
1105    /**
1106     * Used to control how we initialize the service.
1107     */
1108    ComponentName mTopComponent;
1109    String mTopAction = Intent.ACTION_MAIN;
1110    String mTopData;
1111
1112    volatile boolean mProcessesReady = false;
1113    volatile boolean mSystemReady = false;
1114    volatile boolean mOnBattery = false;
1115    volatile int mFactoryTest;
1116
1117    @GuardedBy("this") boolean mBooting = false;
1118    @GuardedBy("this") boolean mCallFinishBooting = false;
1119    @GuardedBy("this") boolean mBootAnimationComplete = false;
1120    @GuardedBy("this") boolean mLaunchWarningShown = false;
1121    @GuardedBy("this") boolean mCheckedForSetup = false;
1122
1123    Context mContext;
1124
1125    /**
1126     * The time at which we will allow normal application switches again,
1127     * after a call to {@link #stopAppSwitches()}.
1128     */
1129    long mAppSwitchesAllowedTime;
1130
1131    /**
1132     * This is set to true after the first switch after mAppSwitchesAllowedTime
1133     * is set; any switches after that will clear the time.
1134     */
1135    boolean mDidAppSwitch;
1136
1137    /**
1138     * Last time (in realtime) at which we checked for power usage.
1139     */
1140    long mLastPowerCheckRealtime;
1141
1142    /**
1143     * Last time (in uptime) at which we checked for power usage.
1144     */
1145    long mLastPowerCheckUptime;
1146
1147    /**
1148     * Set while we are wanting to sleep, to prevent any
1149     * activities from being started/resumed.
1150     */
1151    private boolean mSleeping = false;
1152
1153    /**
1154     * The process state used for processes that are running the top activities.
1155     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1156     */
1157    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1158
1159    /**
1160     * Set while we are running a voice interaction.  This overrides
1161     * sleeping while it is active.
1162     */
1163    private IVoiceInteractionSession mRunningVoice;
1164
1165    /**
1166     * For some direct access we need to power manager.
1167     */
1168    PowerManagerInternal mLocalPowerManager;
1169
1170    /**
1171     * We want to hold a wake lock while running a voice interaction session, since
1172     * this may happen with the screen off and we need to keep the CPU running to
1173     * be able to continue to interact with the user.
1174     */
1175    PowerManager.WakeLock mVoiceWakeLock;
1176
1177    /**
1178     * State of external calls telling us if the device is awake or asleep.
1179     */
1180    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1181
1182    /**
1183     * A list of tokens that cause the top activity to be put to sleep.
1184     * They are used by components that may hide and block interaction with underlying
1185     * activities.
1186     */
1187    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1188
1189    static final int LOCK_SCREEN_HIDDEN = 0;
1190    static final int LOCK_SCREEN_LEAVING = 1;
1191    static final int LOCK_SCREEN_SHOWN = 2;
1192    /**
1193     * State of external call telling us if the lock screen is shown.
1194     */
1195    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1196
1197    /**
1198     * Set if we are shutting down the system, similar to sleeping.
1199     */
1200    boolean mShuttingDown = false;
1201
1202    /**
1203     * Current sequence id for oom_adj computation traversal.
1204     */
1205    int mAdjSeq = 0;
1206
1207    /**
1208     * Current sequence id for process LRU updating.
1209     */
1210    int mLruSeq = 0;
1211
1212    /**
1213     * Keep track of the non-cached/empty process we last found, to help
1214     * determine how to distribute cached/empty processes next time.
1215     */
1216    int mNumNonCachedProcs = 0;
1217
1218    /**
1219     * Keep track of the number of cached hidden procs, to balance oom adj
1220     * distribution between those and empty procs.
1221     */
1222    int mNumCachedHiddenProcs = 0;
1223
1224    /**
1225     * Keep track of the number of service processes we last found, to
1226     * determine on the next iteration which should be B services.
1227     */
1228    int mNumServiceProcs = 0;
1229    int mNewNumAServiceProcs = 0;
1230    int mNewNumServiceProcs = 0;
1231
1232    /**
1233     * Allow the current computed overall memory level of the system to go down?
1234     * This is set to false when we are killing processes for reasons other than
1235     * memory management, so that the now smaller process list will not be taken as
1236     * an indication that memory is tighter.
1237     */
1238    boolean mAllowLowerMemLevel = false;
1239
1240    /**
1241     * The last computed memory level, for holding when we are in a state that
1242     * processes are going away for other reasons.
1243     */
1244    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1245
1246    /**
1247     * The last total number of process we have, to determine if changes actually look
1248     * like a shrinking number of process due to lower RAM.
1249     */
1250    int mLastNumProcesses;
1251
1252    /**
1253     * The uptime of the last time we performed idle maintenance.
1254     */
1255    long mLastIdleTime = SystemClock.uptimeMillis();
1256
1257    /**
1258     * Total time spent with RAM that has been added in the past since the last idle time.
1259     */
1260    long mLowRamTimeSinceLastIdle = 0;
1261
1262    /**
1263     * If RAM is currently low, when that horrible situation started.
1264     */
1265    long mLowRamStartTime = 0;
1266
1267    /**
1268     * For reporting to battery stats the current top application.
1269     */
1270    private String mCurResumedPackage = null;
1271    private int mCurResumedUid = -1;
1272
1273    /**
1274     * For reporting to battery stats the apps currently running foreground
1275     * service.  The ProcessMap is package/uid tuples; each of these contain
1276     * an array of the currently foreground processes.
1277     */
1278    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1279            = new ProcessMap<ArrayList<ProcessRecord>>();
1280
1281    /**
1282     * This is set if we had to do a delayed dexopt of an app before launching
1283     * it, to increase the ANR timeouts in that case.
1284     */
1285    boolean mDidDexOpt;
1286
1287    /**
1288     * Set if the systemServer made a call to enterSafeMode.
1289     */
1290    boolean mSafeMode;
1291
1292    /**
1293     * If true, we are running under a test environment so will sample PSS from processes
1294     * much more rapidly to try to collect better data when the tests are rapidly
1295     * running through apps.
1296     */
1297    boolean mTestPssMode = false;
1298
1299    String mDebugApp = null;
1300    boolean mWaitForDebugger = false;
1301    boolean mDebugTransient = false;
1302    String mOrigDebugApp = null;
1303    boolean mOrigWaitForDebugger = false;
1304    boolean mAlwaysFinishActivities = false;
1305    boolean mLenientBackgroundCheck = false;
1306    boolean mForceResizableActivities;
1307    boolean mSupportsMultiWindow;
1308    boolean mSupportsFreeformWindowManagement;
1309    boolean mSupportsPictureInPicture;
1310    Rect mDefaultPinnedStackBounds;
1311    IActivityController mController = null;
1312    boolean mControllerIsAMonkey = false;
1313    String mProfileApp = null;
1314    ProcessRecord mProfileProc = null;
1315    String mProfileFile;
1316    ParcelFileDescriptor mProfileFd;
1317    int mSamplingInterval = 0;
1318    boolean mAutoStopProfiler = false;
1319    int mProfileType = 0;
1320    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1321    String mMemWatchDumpProcName;
1322    String mMemWatchDumpFile;
1323    int mMemWatchDumpPid;
1324    int mMemWatchDumpUid;
1325    String mTrackAllocationApp = null;
1326    String mNativeDebuggingApp = null;
1327
1328    final long[] mTmpLong = new long[2];
1329
1330    static final class ProcessChangeItem {
1331        static final int CHANGE_ACTIVITIES = 1<<0;
1332        static final int CHANGE_PROCESS_STATE = 1<<1;
1333        int changes;
1334        int uid;
1335        int pid;
1336        int processState;
1337        boolean foregroundActivities;
1338    }
1339
1340    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1341    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1342
1343    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1344    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1345
1346    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1347    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1348
1349    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1350    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1351
1352    /**
1353     * Runtime CPU use collection thread.  This object's lock is used to
1354     * perform synchronization with the thread (notifying it to run).
1355     */
1356    final Thread mProcessCpuThread;
1357
1358    /**
1359     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1360     * Must acquire this object's lock when accessing it.
1361     * NOTE: this lock will be held while doing long operations (trawling
1362     * through all processes in /proc), so it should never be acquired by
1363     * any critical paths such as when holding the main activity manager lock.
1364     */
1365    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1366            MONITOR_THREAD_CPU_USAGE);
1367    final AtomicLong mLastCpuTime = new AtomicLong(0);
1368    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1369
1370    long mLastWriteTime = 0;
1371
1372    /**
1373     * Used to retain an update lock when the foreground activity is in
1374     * immersive mode.
1375     */
1376    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1377
1378    /**
1379     * Set to true after the system has finished booting.
1380     */
1381    boolean mBooted = false;
1382
1383    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1384    int mProcessLimitOverride = -1;
1385
1386    WindowManagerService mWindowManager;
1387    final ActivityThread mSystemThread;
1388
1389    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1390        final ProcessRecord mApp;
1391        final int mPid;
1392        final IApplicationThread mAppThread;
1393
1394        AppDeathRecipient(ProcessRecord app, int pid,
1395                IApplicationThread thread) {
1396            if (DEBUG_ALL) Slog.v(
1397                TAG, "New death recipient " + this
1398                + " for thread " + thread.asBinder());
1399            mApp = app;
1400            mPid = pid;
1401            mAppThread = thread;
1402        }
1403
1404        @Override
1405        public void binderDied() {
1406            if (DEBUG_ALL) Slog.v(
1407                TAG, "Death received in " + this
1408                + " for thread " + mAppThread.asBinder());
1409            synchronized(ActivityManagerService.this) {
1410                appDiedLocked(mApp, mPid, mAppThread, true);
1411            }
1412        }
1413    }
1414
1415    static final int SHOW_ERROR_UI_MSG = 1;
1416    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1417    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1418    static final int UPDATE_CONFIGURATION_MSG = 4;
1419    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1420    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1421    static final int SERVICE_TIMEOUT_MSG = 12;
1422    static final int UPDATE_TIME_ZONE = 13;
1423    static final int SHOW_UID_ERROR_UI_MSG = 14;
1424    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1425    static final int PROC_START_TIMEOUT_MSG = 20;
1426    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1427    static final int KILL_APPLICATION_MSG = 22;
1428    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1429    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1430    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1431    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1432    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1433    static final int CLEAR_DNS_CACHE_MSG = 28;
1434    static final int UPDATE_HTTP_PROXY_MSG = 29;
1435    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1436    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1437    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1438    static final int REPORT_MEM_USAGE_MSG = 33;
1439    static final int REPORT_USER_SWITCH_MSG = 34;
1440    static final int CONTINUE_USER_SWITCH_MSG = 35;
1441    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1442    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1443    static final int PERSIST_URI_GRANTS_MSG = 38;
1444    static final int REQUEST_ALL_PSS_MSG = 39;
1445    static final int START_PROFILES_MSG = 40;
1446    static final int UPDATE_TIME = 41;
1447    static final int SYSTEM_USER_START_MSG = 42;
1448    static final int SYSTEM_USER_CURRENT_MSG = 43;
1449    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1450    static final int FINISH_BOOTING_MSG = 45;
1451    static final int START_USER_SWITCH_UI_MSG = 46;
1452    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1453    static final int DISMISS_DIALOG_UI_MSG = 48;
1454    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1455    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1456    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1457    static final int DELETE_DUMPHEAP_MSG = 52;
1458    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1459    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1460    static final int REPORT_TIME_TRACKER_MSG = 55;
1461    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1462    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1463    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1464    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1465    static final int IDLE_UIDS_MSG = 60;
1466    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1467    static final int LOG_STACK_STATE = 62;
1468    static final int VR_MODE_CHANGE_MSG = 63;
1469    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1470    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1471    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1472    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1473    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1474    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
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            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2246                final ActivityRecord r = (ActivityRecord) msg.obj;
2247                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2248                if (needsVrMode) {
2249                    VrManagerInternal vrService =
2250                            LocalServices.getService(VrManagerInternal.class);
2251                    boolean enable = msg.arg1 == 1;
2252                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2253                            r.info.getComponentName());
2254                }
2255            } break;
2256            }
2257        }
2258    };
2259
2260    static final int COLLECT_PSS_BG_MSG = 1;
2261
2262    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2263        @Override
2264        public void handleMessage(Message msg) {
2265            switch (msg.what) {
2266            case COLLECT_PSS_BG_MSG: {
2267                long start = SystemClock.uptimeMillis();
2268                MemInfoReader memInfo = null;
2269                synchronized (ActivityManagerService.this) {
2270                    if (mFullPssPending) {
2271                        mFullPssPending = false;
2272                        memInfo = new MemInfoReader();
2273                    }
2274                }
2275                if (memInfo != null) {
2276                    updateCpuStatsNow();
2277                    long nativeTotalPss = 0;
2278                    synchronized (mProcessCpuTracker) {
2279                        final int N = mProcessCpuTracker.countStats();
2280                        for (int j=0; j<N; j++) {
2281                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2282                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2283                                // This is definitely an application process; skip it.
2284                                continue;
2285                            }
2286                            synchronized (mPidsSelfLocked) {
2287                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2288                                    // This is one of our own processes; skip it.
2289                                    continue;
2290                                }
2291                            }
2292                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2293                        }
2294                    }
2295                    memInfo.readMemInfo();
2296                    synchronized (ActivityManagerService.this) {
2297                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2298                                + (SystemClock.uptimeMillis()-start) + "ms");
2299                        final long cachedKb = memInfo.getCachedSizeKb();
2300                        final long freeKb = memInfo.getFreeSizeKb();
2301                        final long zramKb = memInfo.getZramTotalSizeKb();
2302                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2303                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2304                                kernelKb*1024, nativeTotalPss*1024);
2305                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2306                                nativeTotalPss);
2307                    }
2308                }
2309
2310                int num = 0;
2311                long[] tmp = new long[2];
2312                do {
2313                    ProcessRecord proc;
2314                    int procState;
2315                    int pid;
2316                    long lastPssTime;
2317                    synchronized (ActivityManagerService.this) {
2318                        if (mPendingPssProcesses.size() <= 0) {
2319                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2320                                    "Collected PSS of " + num + " processes in "
2321                                    + (SystemClock.uptimeMillis() - start) + "ms");
2322                            mPendingPssProcesses.clear();
2323                            return;
2324                        }
2325                        proc = mPendingPssProcesses.remove(0);
2326                        procState = proc.pssProcState;
2327                        lastPssTime = proc.lastPssTime;
2328                        if (proc.thread != null && procState == proc.setProcState
2329                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2330                                        < SystemClock.uptimeMillis()) {
2331                            pid = proc.pid;
2332                        } else {
2333                            proc = null;
2334                            pid = 0;
2335                        }
2336                    }
2337                    if (proc != null) {
2338                        long pss = Debug.getPss(pid, tmp, null);
2339                        synchronized (ActivityManagerService.this) {
2340                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2341                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2342                                num++;
2343                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2344                                        SystemClock.uptimeMillis());
2345                            }
2346                        }
2347                    }
2348                } while (true);
2349            }
2350            }
2351        }
2352    };
2353
2354    public void setSystemProcess() {
2355        try {
2356            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2357            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2358            ServiceManager.addService("meminfo", new MemBinder(this));
2359            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2360            ServiceManager.addService("dbinfo", new DbBinder(this));
2361            if (MONITOR_CPU_USAGE) {
2362                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2363            }
2364            ServiceManager.addService("permission", new PermissionController(this));
2365            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2366
2367            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2368                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2369            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2370
2371            synchronized (this) {
2372                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2373                app.persistent = true;
2374                app.pid = MY_PID;
2375                app.maxAdj = ProcessList.SYSTEM_ADJ;
2376                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2377                synchronized (mPidsSelfLocked) {
2378                    mPidsSelfLocked.put(app.pid, app);
2379                }
2380                updateLruProcessLocked(app, false, null);
2381                updateOomAdjLocked();
2382            }
2383        } catch (PackageManager.NameNotFoundException e) {
2384            throw new RuntimeException(
2385                    "Unable to find android system package", e);
2386        }
2387    }
2388
2389    public void setWindowManager(WindowManagerService wm) {
2390        mWindowManager = wm;
2391        mStackSupervisor.setWindowManager(wm);
2392        mActivityStarter.setWindowManager(wm);
2393    }
2394
2395    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2396        mUsageStatsService = usageStatsManager;
2397    }
2398
2399    public void startObservingNativeCrashes() {
2400        final NativeCrashListener ncl = new NativeCrashListener(this);
2401        ncl.start();
2402    }
2403
2404    public IAppOpsService getAppOpsService() {
2405        return mAppOpsService;
2406    }
2407
2408    static class MemBinder extends Binder {
2409        ActivityManagerService mActivityManagerService;
2410        MemBinder(ActivityManagerService activityManagerService) {
2411            mActivityManagerService = activityManagerService;
2412        }
2413
2414        @Override
2415        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2416            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2417                    != PackageManager.PERMISSION_GRANTED) {
2418                pw.println("Permission Denial: can't dump meminfo from from pid="
2419                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2420                        + " without permission " + android.Manifest.permission.DUMP);
2421                return;
2422            }
2423
2424            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2425        }
2426    }
2427
2428    static class GraphicsBinder extends Binder {
2429        ActivityManagerService mActivityManagerService;
2430        GraphicsBinder(ActivityManagerService activityManagerService) {
2431            mActivityManagerService = activityManagerService;
2432        }
2433
2434        @Override
2435        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2436            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2437                    != PackageManager.PERMISSION_GRANTED) {
2438                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2439                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2440                        + " without permission " + android.Manifest.permission.DUMP);
2441                return;
2442            }
2443
2444            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2445        }
2446    }
2447
2448    static class DbBinder extends Binder {
2449        ActivityManagerService mActivityManagerService;
2450        DbBinder(ActivityManagerService activityManagerService) {
2451            mActivityManagerService = activityManagerService;
2452        }
2453
2454        @Override
2455        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2456            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2457                    != PackageManager.PERMISSION_GRANTED) {
2458                pw.println("Permission Denial: can't dump dbinfo from from pid="
2459                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2460                        + " without permission " + android.Manifest.permission.DUMP);
2461                return;
2462            }
2463
2464            mActivityManagerService.dumpDbInfo(fd, pw, args);
2465        }
2466    }
2467
2468    static class CpuBinder extends Binder {
2469        ActivityManagerService mActivityManagerService;
2470        CpuBinder(ActivityManagerService activityManagerService) {
2471            mActivityManagerService = activityManagerService;
2472        }
2473
2474        @Override
2475        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2476            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2477                    != PackageManager.PERMISSION_GRANTED) {
2478                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2479                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2480                        + " without permission " + android.Manifest.permission.DUMP);
2481                return;
2482            }
2483
2484            synchronized (mActivityManagerService.mProcessCpuTracker) {
2485                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2486                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2487                        SystemClock.uptimeMillis()));
2488            }
2489        }
2490    }
2491
2492    public static final class Lifecycle extends SystemService {
2493        private final ActivityManagerService mService;
2494
2495        public Lifecycle(Context context) {
2496            super(context);
2497            mService = new ActivityManagerService(context);
2498        }
2499
2500        @Override
2501        public void onStart() {
2502            mService.start();
2503        }
2504
2505        public ActivityManagerService getService() {
2506            return mService;
2507        }
2508    }
2509
2510    // Note: This method is invoked on the main thread but may need to attach various
2511    // handlers to other threads.  So take care to be explicit about the looper.
2512    public ActivityManagerService(Context systemContext) {
2513        mContext = systemContext;
2514        mFactoryTest = FactoryTest.getMode();
2515        mSystemThread = ActivityThread.currentActivityThread();
2516
2517        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2518
2519        mHandlerThread = new ServiceThread(TAG,
2520                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2521        mHandlerThread.start();
2522        mHandler = new MainHandler(mHandlerThread.getLooper());
2523        mUiHandler = new UiHandler();
2524
2525        /* static; one-time init here */
2526        if (sKillHandler == null) {
2527            sKillThread = new ServiceThread(TAG + ":kill",
2528                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2529            sKillThread.start();
2530            sKillHandler = new KillHandler(sKillThread.getLooper());
2531        }
2532
2533        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2534                "foreground", BROADCAST_FG_TIMEOUT, false);
2535        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2536                "background", BROADCAST_BG_TIMEOUT, true);
2537        mBroadcastQueues[0] = mFgBroadcastQueue;
2538        mBroadcastQueues[1] = mBgBroadcastQueue;
2539
2540        mServices = new ActiveServices(this);
2541        mProviderMap = new ProviderMap(this);
2542        mAppErrors = new AppErrors(mContext, this);
2543
2544        // TODO: Move creation of battery stats service outside of activity manager service.
2545        File dataDir = Environment.getDataDirectory();
2546        File systemDir = new File(dataDir, "system");
2547        systemDir.mkdirs();
2548        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2549        mBatteryStatsService.getActiveStatistics().readLocked();
2550        mBatteryStatsService.scheduleWriteToDisk();
2551        mOnBattery = DEBUG_POWER ? true
2552                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2553        mBatteryStatsService.getActiveStatistics().setCallback(this);
2554
2555        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2556
2557        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2558        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2559                new IAppOpsCallback.Stub() {
2560                    @Override public void opChanged(int op, int uid, String packageName) {
2561                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2562                            if (mAppOpsService.checkOperation(op, uid, packageName)
2563                                    != AppOpsManager.MODE_ALLOWED) {
2564                                runInBackgroundDisabled(uid);
2565                            }
2566                        }
2567                    }
2568                });
2569
2570        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2571
2572        mUserController = new UserController(this);
2573
2574        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2575            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2576
2577        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2578
2579        mConfiguration.setToDefaults();
2580        mConfiguration.setLocales(LocaleList.getDefault());
2581
2582        mConfigurationSeq = mConfiguration.seq = 1;
2583        mProcessCpuTracker.init();
2584
2585        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2586        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2587        mStackSupervisor = new ActivityStackSupervisor(this);
2588        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2589        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2590
2591        mProcessCpuThread = new Thread("CpuTracker") {
2592            @Override
2593            public void run() {
2594                while (true) {
2595                    try {
2596                        try {
2597                            synchronized(this) {
2598                                final long now = SystemClock.uptimeMillis();
2599                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2600                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2601                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2602                                //        + ", write delay=" + nextWriteDelay);
2603                                if (nextWriteDelay < nextCpuDelay) {
2604                                    nextCpuDelay = nextWriteDelay;
2605                                }
2606                                if (nextCpuDelay > 0) {
2607                                    mProcessCpuMutexFree.set(true);
2608                                    this.wait(nextCpuDelay);
2609                                }
2610                            }
2611                        } catch (InterruptedException e) {
2612                        }
2613                        updateCpuStatsNow();
2614                    } catch (Exception e) {
2615                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2616                    }
2617                }
2618            }
2619        };
2620
2621        Watchdog.getInstance().addMonitor(this);
2622        Watchdog.getInstance().addThread(mHandler);
2623    }
2624
2625    public void setSystemServiceManager(SystemServiceManager mgr) {
2626        mSystemServiceManager = mgr;
2627    }
2628
2629    public void setInstaller(Installer installer) {
2630        mInstaller = installer;
2631    }
2632
2633    private void start() {
2634        Process.removeAllProcessGroups();
2635        mProcessCpuThread.start();
2636
2637        mBatteryStatsService.publish(mContext);
2638        mAppOpsService.publish(mContext);
2639        Slog.d("AppOps", "AppOpsService published");
2640        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2641    }
2642
2643    void onUserStoppedLocked(int userId) {
2644        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2645    }
2646
2647    public void initPowerManagement() {
2648        mStackSupervisor.initPowerManagement();
2649        mBatteryStatsService.initPowerManagement();
2650        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2651        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2652        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2653        mVoiceWakeLock.setReferenceCounted(false);
2654    }
2655
2656    @Override
2657    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2658            throws RemoteException {
2659        if (code == SYSPROPS_TRANSACTION) {
2660            // We need to tell all apps about the system property change.
2661            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2662            synchronized(this) {
2663                final int NP = mProcessNames.getMap().size();
2664                for (int ip=0; ip<NP; ip++) {
2665                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2666                    final int NA = apps.size();
2667                    for (int ia=0; ia<NA; ia++) {
2668                        ProcessRecord app = apps.valueAt(ia);
2669                        if (app.thread != null) {
2670                            procs.add(app.thread.asBinder());
2671                        }
2672                    }
2673                }
2674            }
2675
2676            int N = procs.size();
2677            for (int i=0; i<N; i++) {
2678                Parcel data2 = Parcel.obtain();
2679                try {
2680                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2681                } catch (RemoteException e) {
2682                }
2683                data2.recycle();
2684            }
2685        }
2686        try {
2687            return super.onTransact(code, data, reply, flags);
2688        } catch (RuntimeException e) {
2689            // The activity manager only throws security exceptions, so let's
2690            // log all others.
2691            if (!(e instanceof SecurityException)) {
2692                Slog.wtf(TAG, "Activity Manager Crash", e);
2693            }
2694            throw e;
2695        }
2696    }
2697
2698    void updateCpuStats() {
2699        final long now = SystemClock.uptimeMillis();
2700        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2701            return;
2702        }
2703        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2704            synchronized (mProcessCpuThread) {
2705                mProcessCpuThread.notify();
2706            }
2707        }
2708    }
2709
2710    void updateCpuStatsNow() {
2711        synchronized (mProcessCpuTracker) {
2712            mProcessCpuMutexFree.set(false);
2713            final long now = SystemClock.uptimeMillis();
2714            boolean haveNewCpuStats = false;
2715
2716            if (MONITOR_CPU_USAGE &&
2717                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2718                mLastCpuTime.set(now);
2719                mProcessCpuTracker.update();
2720                if (mProcessCpuTracker.hasGoodLastStats()) {
2721                    haveNewCpuStats = true;
2722                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2723                    //Slog.i(TAG, "Total CPU usage: "
2724                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2725
2726                    // Slog the cpu usage if the property is set.
2727                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2728                        int user = mProcessCpuTracker.getLastUserTime();
2729                        int system = mProcessCpuTracker.getLastSystemTime();
2730                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2731                        int irq = mProcessCpuTracker.getLastIrqTime();
2732                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2733                        int idle = mProcessCpuTracker.getLastIdleTime();
2734
2735                        int total = user + system + iowait + irq + softIrq + idle;
2736                        if (total == 0) total = 1;
2737
2738                        EventLog.writeEvent(EventLogTags.CPU,
2739                                ((user+system+iowait+irq+softIrq) * 100) / total,
2740                                (user * 100) / total,
2741                                (system * 100) / total,
2742                                (iowait * 100) / total,
2743                                (irq * 100) / total,
2744                                (softIrq * 100) / total);
2745                    }
2746                }
2747            }
2748
2749            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2750            synchronized(bstats) {
2751                synchronized(mPidsSelfLocked) {
2752                    if (haveNewCpuStats) {
2753                        if (bstats.startAddingCpuLocked()) {
2754                            int totalUTime = 0;
2755                            int totalSTime = 0;
2756                            final int N = mProcessCpuTracker.countStats();
2757                            for (int i=0; i<N; i++) {
2758                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2759                                if (!st.working) {
2760                                    continue;
2761                                }
2762                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2763                                totalUTime += st.rel_utime;
2764                                totalSTime += st.rel_stime;
2765                                if (pr != null) {
2766                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2767                                    if (ps == null || !ps.isActive()) {
2768                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2769                                                pr.info.uid, pr.processName);
2770                                    }
2771                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2772                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2773                                } else {
2774                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2775                                    if (ps == null || !ps.isActive()) {
2776                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2777                                                bstats.mapUid(st.uid), st.name);
2778                                    }
2779                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2780                                }
2781                            }
2782                            final int userTime = mProcessCpuTracker.getLastUserTime();
2783                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2784                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2785                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2786                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2787                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2788                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2789                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2790                        }
2791                    }
2792                }
2793
2794                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2795                    mLastWriteTime = now;
2796                    mBatteryStatsService.scheduleWriteToDisk();
2797                }
2798            }
2799        }
2800    }
2801
2802    @Override
2803    public void batteryNeedsCpuUpdate() {
2804        updateCpuStatsNow();
2805    }
2806
2807    @Override
2808    public void batteryPowerChanged(boolean onBattery) {
2809        // When plugging in, update the CPU stats first before changing
2810        // the plug state.
2811        updateCpuStatsNow();
2812        synchronized (this) {
2813            synchronized(mPidsSelfLocked) {
2814                mOnBattery = DEBUG_POWER ? true : onBattery;
2815            }
2816        }
2817    }
2818
2819    @Override
2820    public void batterySendBroadcast(Intent intent) {
2821        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2822                AppOpsManager.OP_NONE, null, false, false,
2823                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2824    }
2825
2826    /**
2827     * Initialize the application bind args. These are passed to each
2828     * process when the bindApplication() IPC is sent to the process. They're
2829     * lazily setup to make sure the services are running when they're asked for.
2830     */
2831    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2832        if (mAppBindArgs == null) {
2833            mAppBindArgs = new HashMap<>();
2834
2835            // Isolated processes won't get this optimization, so that we don't
2836            // violate the rules about which services they have access to.
2837            if (!isolated) {
2838                // Setup the application init args
2839                mAppBindArgs.put("package", ServiceManager.getService("package"));
2840                mAppBindArgs.put("window", ServiceManager.getService("window"));
2841                mAppBindArgs.put(Context.ALARM_SERVICE,
2842                        ServiceManager.getService(Context.ALARM_SERVICE));
2843            }
2844        }
2845        return mAppBindArgs;
2846    }
2847
2848    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2849        if (r == null || mFocusedActivity == r) {
2850            return false;
2851        }
2852
2853        if (!r.isFocusable()) {
2854            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2855            return false;
2856        }
2857
2858        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2859
2860        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2861        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2862                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2863        mDoingSetFocusedActivity = true;
2864
2865        final ActivityRecord last = mFocusedActivity;
2866        mFocusedActivity = r;
2867        if (r.task.isApplicationTask()) {
2868            if (mCurAppTimeTracker != r.appTimeTracker) {
2869                // We are switching app tracking.  Complete the current one.
2870                if (mCurAppTimeTracker != null) {
2871                    mCurAppTimeTracker.stop();
2872                    mHandler.obtainMessage(
2873                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2874                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2875                    mCurAppTimeTracker = null;
2876                }
2877                if (r.appTimeTracker != null) {
2878                    mCurAppTimeTracker = r.appTimeTracker;
2879                    startTimeTrackingFocusedActivityLocked();
2880                }
2881            } else {
2882                startTimeTrackingFocusedActivityLocked();
2883            }
2884        } else {
2885            r.appTimeTracker = null;
2886        }
2887        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2888        // TODO: Probably not, because we don't want to resume voice on switching
2889        // back to this activity
2890        if (r.task.voiceInteractor != null) {
2891            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2892        } else {
2893            finishRunningVoiceLocked();
2894            IVoiceInteractionSession session;
2895            if (last != null && ((session = last.task.voiceSession) != null
2896                    || (session = last.voiceSession) != null)) {
2897                // We had been in a voice interaction session, but now focused has
2898                // move to something different.  Just finish the session, we can't
2899                // return to it and retain the proper state and synchronization with
2900                // the voice interaction service.
2901                finishVoiceTask(session);
2902            }
2903        }
2904        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2905            mWindowManager.setFocusedApp(r.appToken, true);
2906        }
2907        applyUpdateLockStateLocked(r);
2908        applyUpdateVrModeLocked(r);
2909        if (mFocusedActivity.userId != mLastFocusedUserId) {
2910            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2911            mHandler.obtainMessage(
2912                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2913            mLastFocusedUserId = mFocusedActivity.userId;
2914        }
2915
2916        // Log a warning if the focused app is changed during the process. This could
2917        // indicate a problem of the focus setting logic!
2918        if (mFocusedActivity != r) Slog.w(TAG,
2919                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2920        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2921
2922        EventLogTags.writeAmFocusedActivity(
2923                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2924                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2925                reason);
2926        return true;
2927    }
2928
2929    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2930        if (mFocusedActivity != goingAway) {
2931            return;
2932        }
2933
2934        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2935        if (focusedStack != null) {
2936            final ActivityRecord top = focusedStack.topActivity();
2937            if (top != null && top.userId != mLastFocusedUserId) {
2938                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2939                mHandler.sendMessage(
2940                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2941                mLastFocusedUserId = top.userId;
2942            }
2943        }
2944
2945        // Try to move focus to another activity if possible.
2946        if (setFocusedActivityLocked(
2947                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2948            return;
2949        }
2950
2951        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2952                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2953        mFocusedActivity = null;
2954        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2955    }
2956
2957    @Override
2958    public void setFocusedStack(int stackId) {
2959        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2960        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2961        final long callingId = Binder.clearCallingIdentity();
2962        try {
2963            synchronized (this) {
2964                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2965                if (stack == null) {
2966                    return;
2967                }
2968                final ActivityRecord r = stack.topRunningActivityLocked();
2969                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2970                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2971                }
2972            }
2973        } finally {
2974            Binder.restoreCallingIdentity(callingId);
2975        }
2976    }
2977
2978    @Override
2979    public void setFocusedTask(int taskId) {
2980        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2981        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2982        final long callingId = Binder.clearCallingIdentity();
2983        try {
2984            synchronized (this) {
2985                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2986                if (task == null) {
2987                    return;
2988                }
2989                final ActivityRecord r = task.topRunningActivityLocked();
2990                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2991                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2992                }
2993            }
2994        } finally {
2995            Binder.restoreCallingIdentity(callingId);
2996        }
2997    }
2998
2999    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3000    @Override
3001    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3003        synchronized (this) {
3004            if (listener != null) {
3005                mTaskStackListeners.register(listener);
3006            }
3007        }
3008    }
3009
3010    @Override
3011    public void notifyActivityDrawn(IBinder token) {
3012        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3013        synchronized (this) {
3014            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3015            if (r != null) {
3016                r.task.stack.notifyActivityDrawnLocked(r);
3017            }
3018        }
3019    }
3020
3021    final void applyUpdateLockStateLocked(ActivityRecord r) {
3022        // Modifications to the UpdateLock state are done on our handler, outside
3023        // the activity manager's locks.  The new state is determined based on the
3024        // state *now* of the relevant activity record.  The object is passed to
3025        // the handler solely for logging detail, not to be consulted/modified.
3026        final boolean nextState = r != null && r.immersive;
3027        mHandler.sendMessage(
3028                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3029    }
3030
3031    final void applyUpdateVrModeLocked(ActivityRecord r) {
3032        mHandler.sendMessage(
3033                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3034    }
3035
3036    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3037        mHandler.sendMessage(
3038                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3039    }
3040
3041    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3042        Message msg = Message.obtain();
3043        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3044        msg.obj = r.task.askedCompatMode ? null : r;
3045        mUiHandler.sendMessage(msg);
3046    }
3047
3048    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3049            String what, Object obj, ProcessRecord srcApp) {
3050        app.lastActivityTime = now;
3051
3052        if (app.activities.size() > 0) {
3053            // Don't want to touch dependent processes that are hosting activities.
3054            return index;
3055        }
3056
3057        int lrui = mLruProcesses.lastIndexOf(app);
3058        if (lrui < 0) {
3059            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3060                    + what + " " + obj + " from " + srcApp);
3061            return index;
3062        }
3063
3064        if (lrui >= index) {
3065            // Don't want to cause this to move dependent processes *back* in the
3066            // list as if they were less frequently used.
3067            return index;
3068        }
3069
3070        if (lrui >= mLruProcessActivityStart) {
3071            // Don't want to touch dependent processes that are hosting activities.
3072            return index;
3073        }
3074
3075        mLruProcesses.remove(lrui);
3076        if (index > 0) {
3077            index--;
3078        }
3079        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3080                + " in LRU list: " + app);
3081        mLruProcesses.add(index, app);
3082        return index;
3083    }
3084
3085    static void killProcessGroup(int uid, int pid) {
3086        if (sKillHandler != null) {
3087            sKillHandler.sendMessage(
3088                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3089        } else {
3090            Slog.w(TAG, "Asked to kill process group before system bringup!");
3091            Process.killProcessGroup(uid, pid);
3092        }
3093    }
3094
3095    final void removeLruProcessLocked(ProcessRecord app) {
3096        int lrui = mLruProcesses.lastIndexOf(app);
3097        if (lrui >= 0) {
3098            if (!app.killed) {
3099                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3100                Process.killProcessQuiet(app.pid);
3101                killProcessGroup(app.uid, app.pid);
3102            }
3103            if (lrui <= mLruProcessActivityStart) {
3104                mLruProcessActivityStart--;
3105            }
3106            if (lrui <= mLruProcessServiceStart) {
3107                mLruProcessServiceStart--;
3108            }
3109            mLruProcesses.remove(lrui);
3110        }
3111    }
3112
3113    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3114            ProcessRecord client) {
3115        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3116                || app.treatLikeActivity;
3117        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3118        if (!activityChange && hasActivity) {
3119            // The process has activities, so we are only allowing activity-based adjustments
3120            // to move it.  It should be kept in the front of the list with other
3121            // processes that have activities, and we don't want those to change their
3122            // order except due to activity operations.
3123            return;
3124        }
3125
3126        mLruSeq++;
3127        final long now = SystemClock.uptimeMillis();
3128        app.lastActivityTime = now;
3129
3130        // First a quick reject: if the app is already at the position we will
3131        // put it, then there is nothing to do.
3132        if (hasActivity) {
3133            final int N = mLruProcesses.size();
3134            if (N > 0 && mLruProcesses.get(N-1) == app) {
3135                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3136                return;
3137            }
3138        } else {
3139            if (mLruProcessServiceStart > 0
3140                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3142                return;
3143            }
3144        }
3145
3146        int lrui = mLruProcesses.lastIndexOf(app);
3147
3148        if (app.persistent && lrui >= 0) {
3149            // We don't care about the position of persistent processes, as long as
3150            // they are in the list.
3151            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3152            return;
3153        }
3154
3155        /* In progress: compute new position first, so we can avoid doing work
3156           if the process is not actually going to move.  Not yet working.
3157        int addIndex;
3158        int nextIndex;
3159        boolean inActivity = false, inService = false;
3160        if (hasActivity) {
3161            // Process has activities, put it at the very tipsy-top.
3162            addIndex = mLruProcesses.size();
3163            nextIndex = mLruProcessServiceStart;
3164            inActivity = true;
3165        } else if (hasService) {
3166            // Process has services, put it at the top of the service list.
3167            addIndex = mLruProcessActivityStart;
3168            nextIndex = mLruProcessServiceStart;
3169            inActivity = true;
3170            inService = true;
3171        } else  {
3172            // Process not otherwise of interest, it goes to the top of the non-service area.
3173            addIndex = mLruProcessServiceStart;
3174            if (client != null) {
3175                int clientIndex = mLruProcesses.lastIndexOf(client);
3176                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3177                        + app);
3178                if (clientIndex >= 0 && addIndex > clientIndex) {
3179                    addIndex = clientIndex;
3180                }
3181            }
3182            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3183        }
3184
3185        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3186                + mLruProcessActivityStart + "): " + app);
3187        */
3188
3189        if (lrui >= 0) {
3190            if (lrui < mLruProcessActivityStart) {
3191                mLruProcessActivityStart--;
3192            }
3193            if (lrui < mLruProcessServiceStart) {
3194                mLruProcessServiceStart--;
3195            }
3196            /*
3197            if (addIndex > lrui) {
3198                addIndex--;
3199            }
3200            if (nextIndex > lrui) {
3201                nextIndex--;
3202            }
3203            */
3204            mLruProcesses.remove(lrui);
3205        }
3206
3207        /*
3208        mLruProcesses.add(addIndex, app);
3209        if (inActivity) {
3210            mLruProcessActivityStart++;
3211        }
3212        if (inService) {
3213            mLruProcessActivityStart++;
3214        }
3215        */
3216
3217        int nextIndex;
3218        if (hasActivity) {
3219            final int N = mLruProcesses.size();
3220            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3221                // Process doesn't have activities, but has clients with
3222                // activities...  move it up, but one below the top (the top
3223                // should always have a real activity).
3224                if (DEBUG_LRU) Slog.d(TAG_LRU,
3225                        "Adding to second-top of LRU activity list: " + app);
3226                mLruProcesses.add(N - 1, app);
3227                // To keep it from spamming the LRU list (by making a bunch of clients),
3228                // we will push down any other entries owned by the app.
3229                final int uid = app.info.uid;
3230                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3231                    ProcessRecord subProc = mLruProcesses.get(i);
3232                    if (subProc.info.uid == uid) {
3233                        // We want to push this one down the list.  If the process after
3234                        // it is for the same uid, however, don't do so, because we don't
3235                        // want them internally to be re-ordered.
3236                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3237                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3238                                    "Pushing uid " + uid + " swapping at " + i + ": "
3239                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3240                            ProcessRecord tmp = mLruProcesses.get(i);
3241                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3242                            mLruProcesses.set(i - 1, tmp);
3243                            i--;
3244                        }
3245                    } else {
3246                        // A gap, we can stop here.
3247                        break;
3248                    }
3249                }
3250            } else {
3251                // Process has activities, put it at the very tipsy-top.
3252                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3253                mLruProcesses.add(app);
3254            }
3255            nextIndex = mLruProcessServiceStart;
3256        } else if (hasService) {
3257            // Process has services, put it at the top of the service list.
3258            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3259            mLruProcesses.add(mLruProcessActivityStart, app);
3260            nextIndex = mLruProcessServiceStart;
3261            mLruProcessActivityStart++;
3262        } else  {
3263            // Process not otherwise of interest, it goes to the top of the non-service area.
3264            int index = mLruProcessServiceStart;
3265            if (client != null) {
3266                // If there is a client, don't allow the process to be moved up higher
3267                // in the list than that client.
3268                int clientIndex = mLruProcesses.lastIndexOf(client);
3269                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3270                        + " when updating " + app);
3271                if (clientIndex <= lrui) {
3272                    // Don't allow the client index restriction to push it down farther in the
3273                    // list than it already is.
3274                    clientIndex = lrui;
3275                }
3276                if (clientIndex >= 0 && index > clientIndex) {
3277                    index = clientIndex;
3278                }
3279            }
3280            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3281            mLruProcesses.add(index, app);
3282            nextIndex = index-1;
3283            mLruProcessActivityStart++;
3284            mLruProcessServiceStart++;
3285        }
3286
3287        // If the app is currently using a content provider or service,
3288        // bump those processes as well.
3289        for (int j=app.connections.size()-1; j>=0; j--) {
3290            ConnectionRecord cr = app.connections.valueAt(j);
3291            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3292                    && cr.binding.service.app != null
3293                    && cr.binding.service.app.lruSeq != mLruSeq
3294                    && !cr.binding.service.app.persistent) {
3295                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3296                        "service connection", cr, app);
3297            }
3298        }
3299        for (int j=app.conProviders.size()-1; j>=0; j--) {
3300            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3301            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3302                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3303                        "provider reference", cpr, app);
3304            }
3305        }
3306    }
3307
3308    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3309        if (uid == Process.SYSTEM_UID) {
3310            // The system gets to run in any process.  If there are multiple
3311            // processes with the same uid, just pick the first (this
3312            // should never happen).
3313            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3314            if (procs == null) return null;
3315            final int procCount = procs.size();
3316            for (int i = 0; i < procCount; i++) {
3317                final int procUid = procs.keyAt(i);
3318                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3319                    // Don't use an app process or different user process for system component.
3320                    continue;
3321                }
3322                return procs.valueAt(i);
3323            }
3324        }
3325        ProcessRecord proc = mProcessNames.get(processName, uid);
3326        if (false && proc != null && !keepIfLarge
3327                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3328                && proc.lastCachedPss >= 4000) {
3329            // Turn this condition on to cause killing to happen regularly, for testing.
3330            if (proc.baseProcessTracker != null) {
3331                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3332            }
3333            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3334        } else if (proc != null && !keepIfLarge
3335                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3336                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3337            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3338            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3339                if (proc.baseProcessTracker != null) {
3340                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3341                }
3342                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3343            }
3344        }
3345        return proc;
3346    }
3347
3348    void notifyPackageUse(String packageName) {
3349        IPackageManager pm = AppGlobals.getPackageManager();
3350        try {
3351            pm.notifyPackageUse(packageName);
3352        } catch (RemoteException e) {
3353        }
3354    }
3355
3356    boolean isNextTransitionForward() {
3357        int transit = mWindowManager.getPendingAppTransition();
3358        return transit == TRANSIT_ACTIVITY_OPEN
3359                || transit == TRANSIT_TASK_OPEN
3360                || transit == TRANSIT_TASK_TO_FRONT;
3361    }
3362
3363    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3364            String processName, String abiOverride, int uid, Runnable crashHandler) {
3365        synchronized(this) {
3366            ApplicationInfo info = new ApplicationInfo();
3367            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3368            // For isolated processes, the former contains the parent's uid and the latter the
3369            // actual uid of the isolated process.
3370            // In the special case introduced by this method (which is, starting an isolated
3371            // process directly from the SystemServer without an actual parent app process) the
3372            // closest thing to a parent's uid is SYSTEM_UID.
3373            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3374            // the |isolated| logic in the ProcessRecord constructor.
3375            info.uid = Process.SYSTEM_UID;
3376            info.processName = processName;
3377            info.className = entryPoint;
3378            info.packageName = "android";
3379            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3380                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3381                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3382                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3383                    crashHandler);
3384            return proc != null ? proc.pid : 0;
3385        }
3386    }
3387
3388    final ProcessRecord startProcessLocked(String processName,
3389            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3390            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3391            boolean isolated, boolean keepIfLarge) {
3392        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3393                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3394                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3395                null /* crashHandler */);
3396    }
3397
3398    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3399            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3400            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3401            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3402        long startTime = SystemClock.elapsedRealtime();
3403        ProcessRecord app;
3404        if (!isolated) {
3405            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3406            checkTime(startTime, "startProcess: after getProcessRecord");
3407
3408            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3409                // If we are in the background, then check to see if this process
3410                // is bad.  If so, we will just silently fail.
3411                if (mAppErrors.isBadProcessLocked(info)) {
3412                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3413                            + "/" + info.processName);
3414                    return null;
3415                }
3416            } else {
3417                // When the user is explicitly starting a process, then clear its
3418                // crash count so that we won't make it bad until they see at
3419                // least one crash dialog again, and make the process good again
3420                // if it had been bad.
3421                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3422                        + "/" + info.processName);
3423                mAppErrors.resetProcessCrashTimeLocked(info);
3424                if (mAppErrors.isBadProcessLocked(info)) {
3425                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3426                            UserHandle.getUserId(info.uid), info.uid,
3427                            info.processName);
3428                    mAppErrors.clearBadProcessLocked(info);
3429                    if (app != null) {
3430                        app.bad = false;
3431                    }
3432                }
3433            }
3434        } else {
3435            // If this is an isolated process, it can't re-use an existing process.
3436            app = null;
3437        }
3438
3439        // app launch boost for big.little configurations
3440        // use cpusets to migrate freshly launched tasks to big cores
3441        synchronized(ActivityManagerService.this) {
3442            nativeMigrateToBoost();
3443            mIsBoosted = true;
3444            mBoostStartTime = SystemClock.uptimeMillis();
3445            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3446            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3447        }
3448
3449        // We don't have to do anything more if:
3450        // (1) There is an existing application record; and
3451        // (2) The caller doesn't think it is dead, OR there is no thread
3452        //     object attached to it so we know it couldn't have crashed; and
3453        // (3) There is a pid assigned to it, so it is either starting or
3454        //     already running.
3455        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3456                + " app=" + app + " knownToBeDead=" + knownToBeDead
3457                + " thread=" + (app != null ? app.thread : null)
3458                + " pid=" + (app != null ? app.pid : -1));
3459        if (app != null && app.pid > 0) {
3460            if (!knownToBeDead || app.thread == null) {
3461                // We already have the app running, or are waiting for it to
3462                // come up (we have a pid but not yet its thread), so keep it.
3463                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3464                // If this is a new package in the process, add the package to the list
3465                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3466                checkTime(startTime, "startProcess: done, added package to proc");
3467                return app;
3468            }
3469
3470            // An application record is attached to a previous process,
3471            // clean it up now.
3472            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3473            checkTime(startTime, "startProcess: bad proc running, killing");
3474            killProcessGroup(app.uid, app.pid);
3475            handleAppDiedLocked(app, true, true);
3476            checkTime(startTime, "startProcess: done killing old proc");
3477        }
3478
3479        String hostingNameStr = hostingName != null
3480                ? hostingName.flattenToShortString() : null;
3481
3482        if (app == null) {
3483            checkTime(startTime, "startProcess: creating new process record");
3484            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3485            if (app == null) {
3486                Slog.w(TAG, "Failed making new process record for "
3487                        + processName + "/" + info.uid + " isolated=" + isolated);
3488                return null;
3489            }
3490            app.crashHandler = crashHandler;
3491            checkTime(startTime, "startProcess: done creating new process record");
3492        } else {
3493            // If this is a new package in the process, add the package to the list
3494            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3495            checkTime(startTime, "startProcess: added package to existing proc");
3496        }
3497
3498        // If the system is not ready yet, then hold off on starting this
3499        // process until it is.
3500        if (!mProcessesReady
3501                && !isAllowedWhileBooting(info)
3502                && !allowWhileBooting) {
3503            if (!mProcessesOnHold.contains(app)) {
3504                mProcessesOnHold.add(app);
3505            }
3506            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3507                    "System not ready, putting on hold: " + app);
3508            checkTime(startTime, "startProcess: returning with proc on hold");
3509            return app;
3510        }
3511
3512        checkTime(startTime, "startProcess: stepping in to startProcess");
3513        startProcessLocked(
3514                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3515        checkTime(startTime, "startProcess: done starting proc!");
3516        return (app.pid != 0) ? app : null;
3517    }
3518
3519    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3520        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3521    }
3522
3523    private final void startProcessLocked(ProcessRecord app,
3524            String hostingType, String hostingNameStr) {
3525        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3526                null /* entryPoint */, null /* entryPointArgs */);
3527    }
3528
3529    private final void startProcessLocked(ProcessRecord app, String hostingType,
3530            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3531        long startTime = SystemClock.elapsedRealtime();
3532        if (app.pid > 0 && app.pid != MY_PID) {
3533            checkTime(startTime, "startProcess: removing from pids map");
3534            synchronized (mPidsSelfLocked) {
3535                mPidsSelfLocked.remove(app.pid);
3536                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3537            }
3538            checkTime(startTime, "startProcess: done removing from pids map");
3539            app.setPid(0);
3540        }
3541
3542        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3543                "startProcessLocked removing on hold: " + app);
3544        mProcessesOnHold.remove(app);
3545
3546        checkTime(startTime, "startProcess: starting to update cpu stats");
3547        updateCpuStats();
3548        checkTime(startTime, "startProcess: done updating cpu stats");
3549
3550        try {
3551            try {
3552                final int userId = UserHandle.getUserId(app.uid);
3553                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3554            } catch (RemoteException e) {
3555                throw e.rethrowAsRuntimeException();
3556            }
3557
3558            int uid = app.uid;
3559            int[] gids = null;
3560            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3561            if (!app.isolated) {
3562                int[] permGids = null;
3563                try {
3564                    checkTime(startTime, "startProcess: getting gids from package manager");
3565                    final IPackageManager pm = AppGlobals.getPackageManager();
3566                    permGids = pm.getPackageGids(app.info.packageName,
3567                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3568                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3569                            MountServiceInternal.class);
3570                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3571                            app.info.packageName);
3572                } catch (RemoteException e) {
3573                    throw e.rethrowAsRuntimeException();
3574                }
3575
3576                /*
3577                 * Add shared application and profile GIDs so applications can share some
3578                 * resources like shared libraries and access user-wide resources
3579                 */
3580                if (ArrayUtils.isEmpty(permGids)) {
3581                    gids = new int[2];
3582                } else {
3583                    gids = new int[permGids.length + 2];
3584                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3585                }
3586                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3587                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3588            }
3589            checkTime(startTime, "startProcess: building args");
3590            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3591                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3592                        && mTopComponent != null
3593                        && app.processName.equals(mTopComponent.getPackageName())) {
3594                    uid = 0;
3595                }
3596                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3597                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3598                    uid = 0;
3599                }
3600            }
3601            int debugFlags = 0;
3602            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3603                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3604                // Also turn on CheckJNI for debuggable apps. It's quite
3605                // awkward to turn on otherwise.
3606                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3607            }
3608            // Run the app in safe mode if its manifest requests so or the
3609            // system is booted in safe mode.
3610            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3611                mSafeMode == true) {
3612                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3613            }
3614            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3615                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3616            }
3617            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3618            if ("true".equals(genDebugInfoProperty)) {
3619                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3620            }
3621            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3622                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3623            }
3624            if ("1".equals(SystemProperties.get("debug.assert"))) {
3625                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3626            }
3627            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3628                // Enable all debug flags required by the native debugger.
3629                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3630                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3631                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3632                mNativeDebuggingApp = null;
3633            }
3634
3635            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3636            if (requiredAbi == null) {
3637                requiredAbi = Build.SUPPORTED_ABIS[0];
3638            }
3639
3640            String instructionSet = null;
3641            if (app.info.primaryCpuAbi != null) {
3642                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3643            }
3644
3645            app.gids = gids;
3646            app.requiredAbi = requiredAbi;
3647            app.instructionSet = instructionSet;
3648
3649            // Start the process.  It will either succeed and return a result containing
3650            // the PID of the new process, or else throw a RuntimeException.
3651            boolean isActivityProcess = (entryPoint == null);
3652            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3653            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3654                    app.processName);
3655            checkTime(startTime, "startProcess: asking zygote to start proc");
3656            Process.ProcessStartResult startResult = Process.start(entryPoint,
3657                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3658                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3659                    app.info.dataDir, entryPointArgs);
3660            checkTime(startTime, "startProcess: returned from zygote!");
3661            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3662
3663            if (app.isolated) {
3664                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3665            }
3666            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3667            checkTime(startTime, "startProcess: done updating battery stats");
3668
3669            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3670                    UserHandle.getUserId(uid), startResult.pid, uid,
3671                    app.processName, hostingType,
3672                    hostingNameStr != null ? hostingNameStr : "");
3673
3674            try {
3675                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3676                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3677            } catch (RemoteException ex) {
3678                // Ignore
3679            }
3680
3681            if (app.persistent) {
3682                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3683            }
3684
3685            if (DEBUG_PROCESSES) {
3686                checkTime(startTime, "startProcess: building log message");
3687                StringBuilder buf = mStringBuilder;
3688                buf.setLength(0);
3689                buf.append("Start proc ");
3690                buf.append(startResult.pid);
3691                buf.append(':');
3692                buf.append(app.processName);
3693                buf.append('/');
3694                UserHandle.formatUid(buf, uid);
3695                if (!isActivityProcess) {
3696                    buf.append(" [");
3697                    buf.append(entryPoint);
3698                    buf.append("]");
3699                }
3700                buf.append(" for ");
3701                buf.append(hostingType);
3702                if (hostingNameStr != null) {
3703                    buf.append(" ");
3704                    buf.append(hostingNameStr);
3705                }
3706                Slog.i(TAG, buf.toString());
3707            }
3708            app.setPid(startResult.pid);
3709            app.usingWrapper = startResult.usingWrapper;
3710            app.removed = false;
3711            app.killed = false;
3712            app.killedByAm = false;
3713            checkTime(startTime, "startProcess: starting to update pids map");
3714            synchronized (mPidsSelfLocked) {
3715                this.mPidsSelfLocked.put(startResult.pid, app);
3716                if (isActivityProcess) {
3717                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3718                    msg.obj = app;
3719                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3720                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3721                }
3722            }
3723            checkTime(startTime, "startProcess: done updating pids map");
3724        } catch (RuntimeException e) {
3725            // XXX do better error recovery.
3726            app.setPid(0);
3727            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3728            if (app.isolated) {
3729                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3730            }
3731            Slog.e(TAG, "Failure starting process " + app.processName, e);
3732        }
3733    }
3734
3735    void updateUsageStats(ActivityRecord component, boolean resumed) {
3736        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3737                "updateUsageStats: comp=" + component + "res=" + resumed);
3738        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3739        if (resumed) {
3740            if (mUsageStatsService != null) {
3741                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3742                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3743            }
3744            synchronized (stats) {
3745                stats.noteActivityResumedLocked(component.app.uid);
3746            }
3747        } else {
3748            if (mUsageStatsService != null) {
3749                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3750                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3751            }
3752            synchronized (stats) {
3753                stats.noteActivityPausedLocked(component.app.uid);
3754            }
3755        }
3756    }
3757
3758    Intent getHomeIntent() {
3759        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3760        intent.setComponent(mTopComponent);
3761        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3762        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3763            intent.addCategory(Intent.CATEGORY_HOME);
3764        }
3765        return intent;
3766    }
3767
3768    boolean startHomeActivityLocked(int userId, String reason) {
3769        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3770                && mTopAction == null) {
3771            // We are running in factory test mode, but unable to find
3772            // the factory test app, so just sit around displaying the
3773            // error message and don't try to start anything.
3774            return false;
3775        }
3776        Intent intent = getHomeIntent();
3777        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3778        if (aInfo != null) {
3779            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3780            // Don't do this if the home app is currently being
3781            // instrumented.
3782            aInfo = new ActivityInfo(aInfo);
3783            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3784            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3785                    aInfo.applicationInfo.uid, true);
3786            if (app == null || app.instrumentationClass == null) {
3787                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3788                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3789            }
3790        }
3791
3792        return true;
3793    }
3794
3795    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3796        ActivityInfo ai = null;
3797        ComponentName comp = intent.getComponent();
3798        try {
3799            if (comp != null) {
3800                // Factory test.
3801                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3802            } else {
3803                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3804                        intent,
3805                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3806                        flags, userId);
3807
3808                if (info != null) {
3809                    ai = info.activityInfo;
3810                }
3811            }
3812        } catch (RemoteException e) {
3813            // ignore
3814        }
3815
3816        return ai;
3817    }
3818
3819    /**
3820     * Starts the "new version setup screen" if appropriate.
3821     */
3822    void startSetupActivityLocked() {
3823        // Only do this once per boot.
3824        if (mCheckedForSetup) {
3825            return;
3826        }
3827
3828        // We will show this screen if the current one is a different
3829        // version than the last one shown, and we are not running in
3830        // low-level factory test mode.
3831        final ContentResolver resolver = mContext.getContentResolver();
3832        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3833                Settings.Global.getInt(resolver,
3834                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3835            mCheckedForSetup = true;
3836
3837            // See if we should be showing the platform update setup UI.
3838            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3839            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3840                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3841            if (!ris.isEmpty()) {
3842                final ResolveInfo ri = ris.get(0);
3843                String vers = ri.activityInfo.metaData != null
3844                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3845                        : null;
3846                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3847                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3848                            Intent.METADATA_SETUP_VERSION);
3849                }
3850                String lastVers = Settings.Secure.getString(
3851                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3852                if (vers != null && !vers.equals(lastVers)) {
3853                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3854                    intent.setComponent(new ComponentName(
3855                            ri.activityInfo.packageName, ri.activityInfo.name));
3856                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3857                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3858                            null, 0, 0, 0, null, false, false, null, null, null);
3859                }
3860            }
3861        }
3862    }
3863
3864    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3865        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3866    }
3867
3868    void enforceNotIsolatedCaller(String caller) {
3869        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3870            throw new SecurityException("Isolated process not allowed to call " + caller);
3871        }
3872    }
3873
3874    void enforceShellRestriction(String restriction, int userHandle) {
3875        if (Binder.getCallingUid() == Process.SHELL_UID) {
3876            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3877                throw new SecurityException("Shell does not have permission to access user "
3878                        + userHandle);
3879            }
3880        }
3881    }
3882
3883    @Override
3884    public int getFrontActivityScreenCompatMode() {
3885        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3886        synchronized (this) {
3887            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3888        }
3889    }
3890
3891    @Override
3892    public void setFrontActivityScreenCompatMode(int mode) {
3893        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3894                "setFrontActivityScreenCompatMode");
3895        synchronized (this) {
3896            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3897        }
3898    }
3899
3900    @Override
3901    public int getPackageScreenCompatMode(String packageName) {
3902        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3903        synchronized (this) {
3904            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3905        }
3906    }
3907
3908    @Override
3909    public void setPackageScreenCompatMode(String packageName, int mode) {
3910        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3911                "setPackageScreenCompatMode");
3912        synchronized (this) {
3913            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3914        }
3915    }
3916
3917    @Override
3918    public boolean getPackageAskScreenCompat(String packageName) {
3919        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3920        synchronized (this) {
3921            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3922        }
3923    }
3924
3925    @Override
3926    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setPackageAskScreenCompat");
3929        synchronized (this) {
3930            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3931        }
3932    }
3933
3934    private boolean hasUsageStatsPermission(String callingPackage) {
3935        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3936                Binder.getCallingUid(), callingPackage);
3937        if (mode == AppOpsManager.MODE_DEFAULT) {
3938            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3939                    == PackageManager.PERMISSION_GRANTED;
3940        }
3941        return mode == AppOpsManager.MODE_ALLOWED;
3942    }
3943
3944    @Override
3945    public int getPackageProcessState(String packageName, String callingPackage) {
3946        if (!hasUsageStatsPermission(callingPackage)) {
3947            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3948                    "getPackageProcessState");
3949        }
3950
3951        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3952        synchronized (this) {
3953            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3954                final ProcessRecord proc = mLruProcesses.get(i);
3955                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3956                        || procState > proc.setProcState) {
3957                    boolean found = false;
3958                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3959                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3960                            procState = proc.setProcState;
3961                            found = true;
3962                        }
3963                    }
3964                    if (proc.pkgDeps != null && !found) {
3965                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3966                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3967                                procState = proc.setProcState;
3968                                break;
3969                            }
3970                        }
3971                    }
3972                }
3973            }
3974        }
3975        return procState;
3976    }
3977
3978    @Override
3979    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3980        synchronized (this) {
3981            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3982            if (app == null) {
3983                return false;
3984            }
3985            if (app.trimMemoryLevel < level && app.thread != null &&
3986                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3987                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3988                try {
3989                    app.thread.scheduleTrimMemory(level);
3990                    app.trimMemoryLevel = level;
3991                    return true;
3992                } catch (RemoteException e) {
3993                    // Fallthrough to failure case.
3994                }
3995            }
3996        }
3997        return false;
3998    }
3999
4000    private void dispatchProcessesChanged() {
4001        int N;
4002        synchronized (this) {
4003            N = mPendingProcessChanges.size();
4004            if (mActiveProcessChanges.length < N) {
4005                mActiveProcessChanges = new ProcessChangeItem[N];
4006            }
4007            mPendingProcessChanges.toArray(mActiveProcessChanges);
4008            mPendingProcessChanges.clear();
4009            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4010                    "*** Delivering " + N + " process changes");
4011        }
4012
4013        int i = mProcessObservers.beginBroadcast();
4014        while (i > 0) {
4015            i--;
4016            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4017            if (observer != null) {
4018                try {
4019                    for (int j=0; j<N; j++) {
4020                        ProcessChangeItem item = mActiveProcessChanges[j];
4021                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4022                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4023                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4024                                    + item.uid + ": " + item.foregroundActivities);
4025                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4026                                    item.foregroundActivities);
4027                        }
4028                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4029                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4030                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4031                                    + ": " + item.processState);
4032                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4033                        }
4034                    }
4035                } catch (RemoteException e) {
4036                }
4037            }
4038        }
4039        mProcessObservers.finishBroadcast();
4040
4041        synchronized (this) {
4042            for (int j=0; j<N; j++) {
4043                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4044            }
4045        }
4046    }
4047
4048    private void dispatchProcessDied(int pid, int uid) {
4049        int i = mProcessObservers.beginBroadcast();
4050        while (i > 0) {
4051            i--;
4052            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4053            if (observer != null) {
4054                try {
4055                    observer.onProcessDied(pid, uid);
4056                } catch (RemoteException e) {
4057                }
4058            }
4059        }
4060        mProcessObservers.finishBroadcast();
4061    }
4062
4063    private void dispatchUidsChanged() {
4064        int N;
4065        synchronized (this) {
4066            N = mPendingUidChanges.size();
4067            if (mActiveUidChanges.length < N) {
4068                mActiveUidChanges = new UidRecord.ChangeItem[N];
4069            }
4070            for (int i=0; i<N; i++) {
4071                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4072                mActiveUidChanges[i] = change;
4073                if (change.uidRecord != null) {
4074                    change.uidRecord.pendingChange = null;
4075                    change.uidRecord = null;
4076                }
4077            }
4078            mPendingUidChanges.clear();
4079            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4080                    "*** Delivering " + N + " uid changes");
4081        }
4082
4083        if (mLocalPowerManager != null) {
4084            for (int j=0; j<N; j++) {
4085                UidRecord.ChangeItem item = mActiveUidChanges[j];
4086                if (item.change == UidRecord.CHANGE_GONE
4087                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4088                    mLocalPowerManager.uidGone(item.uid);
4089                } else {
4090                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4091                }
4092            }
4093        }
4094
4095        int i = mUidObservers.beginBroadcast();
4096        while (i > 0) {
4097            i--;
4098            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4099            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4100            if (observer != null) {
4101                try {
4102                    for (int j=0; j<N; j++) {
4103                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4104                        final int change = item.change;
4105                        UidRecord validateUid = null;
4106                        if (VALIDATE_UID_STATES && i == 0) {
4107                            validateUid = mValidateUids.get(item.uid);
4108                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4109                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4110                                validateUid = new UidRecord(item.uid);
4111                                mValidateUids.put(item.uid, validateUid);
4112                            }
4113                        }
4114                        if (change == UidRecord.CHANGE_IDLE
4115                                || change == UidRecord.CHANGE_GONE_IDLE) {
4116                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4117                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4118                                        "UID idle uid=" + item.uid);
4119                                observer.onUidIdle(item.uid);
4120                            }
4121                            if (VALIDATE_UID_STATES && i == 0) {
4122                                if (validateUid != null) {
4123                                    validateUid.idle = true;
4124                                }
4125                            }
4126                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4127                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4128                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129                                        "UID active uid=" + item.uid);
4130                                observer.onUidActive(item.uid);
4131                            }
4132                            if (VALIDATE_UID_STATES && i == 0) {
4133                                validateUid.idle = false;
4134                            }
4135                        }
4136                        if (change == UidRecord.CHANGE_GONE
4137                                || change == UidRecord.CHANGE_GONE_IDLE) {
4138                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4139                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4140                                        "UID gone uid=" + item.uid);
4141                                observer.onUidGone(item.uid);
4142                            }
4143                            if (VALIDATE_UID_STATES && i == 0) {
4144                                if (validateUid != null) {
4145                                    mValidateUids.remove(item.uid);
4146                                }
4147                            }
4148                        } else {
4149                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4150                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4151                                        "UID CHANGED uid=" + item.uid
4152                                                + ": " + item.processState);
4153                                observer.onUidStateChanged(item.uid, item.processState);
4154                            }
4155                            if (VALIDATE_UID_STATES && i == 0) {
4156                                validateUid.curProcState = validateUid.setProcState
4157                                        = item.processState;
4158                            }
4159                        }
4160                    }
4161                } catch (RemoteException e) {
4162                }
4163            }
4164        }
4165        mUidObservers.finishBroadcast();
4166
4167        synchronized (this) {
4168            for (int j=0; j<N; j++) {
4169                mAvailUidChanges.add(mActiveUidChanges[j]);
4170            }
4171        }
4172    }
4173
4174    @Override
4175    public final int startActivity(IApplicationThread caller, String callingPackage,
4176            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4177            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4178        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4179                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4180                UserHandle.getCallingUserId());
4181    }
4182
4183    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4184        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4185        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4186                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4187                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4188
4189        // TODO: Switch to user app stacks here.
4190        String mimeType = intent.getType();
4191        final Uri data = intent.getData();
4192        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4193            mimeType = getProviderMimeType(data, userId);
4194        }
4195        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4196
4197        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4198        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4199                null, 0, 0, null, null, null, null, false, userId, container, null);
4200    }
4201
4202    @Override
4203    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4204            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4205            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4206        enforceNotIsolatedCaller("startActivity");
4207        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4208                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4209        // TODO: Switch to user app stacks here.
4210        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4211                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4212                profilerInfo, null, null, bOptions, false, userId, null, null);
4213    }
4214
4215    @Override
4216    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4217            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4218            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4219            int userId) {
4220
4221        // This is very dangerous -- it allows you to perform a start activity (including
4222        // permission grants) as any app that may launch one of your own activities.  So
4223        // we will only allow this to be done from activities that are part of the core framework,
4224        // and then only when they are running as the system.
4225        final ActivityRecord sourceRecord;
4226        final int targetUid;
4227        final String targetPackage;
4228        synchronized (this) {
4229            if (resultTo == null) {
4230                throw new SecurityException("Must be called from an activity");
4231            }
4232            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4233            if (sourceRecord == null) {
4234                throw new SecurityException("Called with bad activity token: " + resultTo);
4235            }
4236            if (!sourceRecord.info.packageName.equals("android")) {
4237                throw new SecurityException(
4238                        "Must be called from an activity that is declared in the android package");
4239            }
4240            if (sourceRecord.app == null) {
4241                throw new SecurityException("Called without a process attached to activity");
4242            }
4243            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4244                // This is still okay, as long as this activity is running under the
4245                // uid of the original calling activity.
4246                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4247                    throw new SecurityException(
4248                            "Calling activity in uid " + sourceRecord.app.uid
4249                                    + " must be system uid or original calling uid "
4250                                    + sourceRecord.launchedFromUid);
4251                }
4252            }
4253            if (ignoreTargetSecurity) {
4254                if (intent.getComponent() == null) {
4255                    throw new SecurityException(
4256                            "Component must be specified with ignoreTargetSecurity");
4257                }
4258                if (intent.getSelector() != null) {
4259                    throw new SecurityException(
4260                            "Selector not allowed with ignoreTargetSecurity");
4261                }
4262            }
4263            targetUid = sourceRecord.launchedFromUid;
4264            targetPackage = sourceRecord.launchedFromPackage;
4265        }
4266
4267        if (userId == UserHandle.USER_NULL) {
4268            userId = UserHandle.getUserId(sourceRecord.app.uid);
4269        }
4270
4271        // TODO: Switch to user app stacks here.
4272        try {
4273            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4274                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4275                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4276            return ret;
4277        } catch (SecurityException e) {
4278            // XXX need to figure out how to propagate to original app.
4279            // A SecurityException here is generally actually a fault of the original
4280            // calling activity (such as a fairly granting permissions), so propagate it
4281            // back to them.
4282            /*
4283            StringBuilder msg = new StringBuilder();
4284            msg.append("While launching");
4285            msg.append(intent.toString());
4286            msg.append(": ");
4287            msg.append(e.getMessage());
4288            */
4289            throw e;
4290        }
4291    }
4292
4293    @Override
4294    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4295            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4297        enforceNotIsolatedCaller("startActivityAndWait");
4298        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4299                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4300        WaitResult res = new WaitResult();
4301        // TODO: Switch to user app stacks here.
4302        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4303                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4304                bOptions, false, userId, null, null);
4305        return res;
4306    }
4307
4308    @Override
4309    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4310            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4311            int startFlags, Configuration config, Bundle bOptions, int userId) {
4312        enforceNotIsolatedCaller("startActivityWithConfig");
4313        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4314                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4315        // TODO: Switch to user app stacks here.
4316        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4317                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4318                null, null, config, bOptions, false, userId, null, null);
4319        return ret;
4320    }
4321
4322    @Override
4323    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4324            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4325            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4326            throws TransactionTooLargeException {
4327        enforceNotIsolatedCaller("startActivityIntentSender");
4328        // Refuse possible leaked file descriptors
4329        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4330            throw new IllegalArgumentException("File descriptors passed in Intent");
4331        }
4332
4333        IIntentSender sender = intent.getTarget();
4334        if (!(sender instanceof PendingIntentRecord)) {
4335            throw new IllegalArgumentException("Bad PendingIntent object");
4336        }
4337
4338        PendingIntentRecord pir = (PendingIntentRecord)sender;
4339
4340        synchronized (this) {
4341            // If this is coming from the currently resumed activity, it is
4342            // effectively saying that app switches are allowed at this point.
4343            final ActivityStack stack = getFocusedStack();
4344            if (stack.mResumedActivity != null &&
4345                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4346                mAppSwitchesAllowedTime = 0;
4347            }
4348        }
4349        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4350                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4351        return ret;
4352    }
4353
4354    @Override
4355    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4356            Intent intent, String resolvedType, IVoiceInteractionSession session,
4357            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4358            Bundle bOptions, int userId) {
4359        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4360                != PackageManager.PERMISSION_GRANTED) {
4361            String msg = "Permission Denial: startVoiceActivity() from pid="
4362                    + Binder.getCallingPid()
4363                    + ", uid=" + Binder.getCallingUid()
4364                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4365            Slog.w(TAG, msg);
4366            throw new SecurityException(msg);
4367        }
4368        if (session == null || interactor == null) {
4369            throw new NullPointerException("null session or interactor");
4370        }
4371        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4372                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4373        // TODO: Switch to user app stacks here.
4374        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4375                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4376                null, bOptions, false, userId, null, null);
4377    }
4378
4379    @Override
4380    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4381            throws RemoteException {
4382        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4383        synchronized (this) {
4384            ActivityRecord activity = getFocusedStack().topActivity();
4385            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4386                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4387            }
4388            if (mRunningVoice != null || activity.task.voiceSession != null
4389                    || activity.voiceSession != null) {
4390                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4391                return;
4392            }
4393            if (activity.pendingVoiceInteractionStart) {
4394                Slog.w(TAG, "Pending start of voice interaction already.");
4395                return;
4396            }
4397            activity.pendingVoiceInteractionStart = true;
4398        }
4399        LocalServices.getService(VoiceInteractionManagerInternal.class)
4400                .startLocalVoiceInteraction(callingActivity, options);
4401    }
4402
4403    @Override
4404    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4405        LocalServices.getService(VoiceInteractionManagerInternal.class)
4406                .stopLocalVoiceInteraction(callingActivity);
4407    }
4408
4409    @Override
4410    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4411        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4412                .supportsLocalVoiceInteraction();
4413    }
4414
4415    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4416            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4417        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4418        if (activityToCallback == null) return;
4419        activityToCallback.setVoiceSessionLocked(voiceSession);
4420
4421        // Inform the activity
4422        try {
4423            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4424                    voiceInteractor);
4425            long token = Binder.clearCallingIdentity();
4426            try {
4427                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4428            } finally {
4429                Binder.restoreCallingIdentity(token);
4430            }
4431            // TODO: VI Should we cache the activity so that it's easier to find later
4432            // rather than scan through all the stacks and activities?
4433        } catch (RemoteException re) {
4434            activityToCallback.clearVoiceSessionLocked();
4435            // TODO: VI Should this terminate the voice session?
4436        }
4437    }
4438
4439    @Override
4440    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4441        synchronized (this) {
4442            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4443                if (keepAwake) {
4444                    mVoiceWakeLock.acquire();
4445                } else {
4446                    mVoiceWakeLock.release();
4447                }
4448            }
4449        }
4450    }
4451
4452    @Override
4453    public boolean startNextMatchingActivity(IBinder callingActivity,
4454            Intent intent, Bundle bOptions) {
4455        // Refuse possible leaked file descriptors
4456        if (intent != null && intent.hasFileDescriptors() == true) {
4457            throw new IllegalArgumentException("File descriptors passed in Intent");
4458        }
4459        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4460
4461        synchronized (this) {
4462            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4463            if (r == null) {
4464                ActivityOptions.abort(options);
4465                return false;
4466            }
4467            if (r.app == null || r.app.thread == null) {
4468                // The caller is not running...  d'oh!
4469                ActivityOptions.abort(options);
4470                return false;
4471            }
4472            intent = new Intent(intent);
4473            // The caller is not allowed to change the data.
4474            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4475            // And we are resetting to find the next component...
4476            intent.setComponent(null);
4477
4478            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4479
4480            ActivityInfo aInfo = null;
4481            try {
4482                List<ResolveInfo> resolves =
4483                    AppGlobals.getPackageManager().queryIntentActivities(
4484                            intent, r.resolvedType,
4485                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4486                            UserHandle.getCallingUserId()).getList();
4487
4488                // Look for the original activity in the list...
4489                final int N = resolves != null ? resolves.size() : 0;
4490                for (int i=0; i<N; i++) {
4491                    ResolveInfo rInfo = resolves.get(i);
4492                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4493                            && rInfo.activityInfo.name.equals(r.info.name)) {
4494                        // We found the current one...  the next matching is
4495                        // after it.
4496                        i++;
4497                        if (i<N) {
4498                            aInfo = resolves.get(i).activityInfo;
4499                        }
4500                        if (debug) {
4501                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4502                                    + "/" + r.info.name);
4503                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4504                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4505                        }
4506                        break;
4507                    }
4508                }
4509            } catch (RemoteException e) {
4510            }
4511
4512            if (aInfo == null) {
4513                // Nobody who is next!
4514                ActivityOptions.abort(options);
4515                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4516                return false;
4517            }
4518
4519            intent.setComponent(new ComponentName(
4520                    aInfo.applicationInfo.packageName, aInfo.name));
4521            intent.setFlags(intent.getFlags()&~(
4522                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4523                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4524                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4525                    Intent.FLAG_ACTIVITY_NEW_TASK));
4526
4527            // Okay now we need to start the new activity, replacing the
4528            // currently running activity.  This is a little tricky because
4529            // we want to start the new one as if the current one is finished,
4530            // but not finish the current one first so that there is no flicker.
4531            // And thus...
4532            final boolean wasFinishing = r.finishing;
4533            r.finishing = true;
4534
4535            // Propagate reply information over to the new activity.
4536            final ActivityRecord resultTo = r.resultTo;
4537            final String resultWho = r.resultWho;
4538            final int requestCode = r.requestCode;
4539            r.resultTo = null;
4540            if (resultTo != null) {
4541                resultTo.removeResultsLocked(r, resultWho, requestCode);
4542            }
4543
4544            final long origId = Binder.clearCallingIdentity();
4545            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4546                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4547                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4548                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4549                    false, false, null, null, null);
4550            Binder.restoreCallingIdentity(origId);
4551
4552            r.finishing = wasFinishing;
4553            if (res != ActivityManager.START_SUCCESS) {
4554                return false;
4555            }
4556            return true;
4557        }
4558    }
4559
4560    @Override
4561    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4562        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4563            String msg = "Permission Denial: startActivityFromRecents called without " +
4564                    START_TASKS_FROM_RECENTS;
4565            Slog.w(TAG, msg);
4566            throw new SecurityException(msg);
4567        }
4568        final long origId = Binder.clearCallingIdentity();
4569        try {
4570            synchronized (this) {
4571                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4572            }
4573        } finally {
4574            Binder.restoreCallingIdentity(origId);
4575        }
4576    }
4577
4578    final int startActivityInPackage(int uid, String callingPackage,
4579            Intent intent, String resolvedType, IBinder resultTo,
4580            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4581            IActivityContainer container, TaskRecord inTask) {
4582
4583        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4584                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4585
4586        // TODO: Switch to user app stacks here.
4587        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4588                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4589                null, null, null, bOptions, false, userId, container, inTask);
4590        return ret;
4591    }
4592
4593    @Override
4594    public final int startActivities(IApplicationThread caller, String callingPackage,
4595            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4596            int userId) {
4597        enforceNotIsolatedCaller("startActivities");
4598        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4599                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4600        // TODO: Switch to user app stacks here.
4601        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4602                resolvedTypes, resultTo, bOptions, userId);
4603        return ret;
4604    }
4605
4606    final int startActivitiesInPackage(int uid, String callingPackage,
4607            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4608            Bundle bOptions, int userId) {
4609
4610        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4611                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4612        // TODO: Switch to user app stacks here.
4613        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4614                resultTo, bOptions, userId);
4615        return ret;
4616    }
4617
4618    @Override
4619    public void reportActivityFullyDrawn(IBinder token) {
4620        synchronized (this) {
4621            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4622            if (r == null) {
4623                return;
4624            }
4625            r.reportFullyDrawnLocked();
4626        }
4627    }
4628
4629    @Override
4630    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4631        synchronized (this) {
4632            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4633            if (r == null) {
4634                return;
4635            }
4636            TaskRecord task = r.task;
4637            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4638                // Fixed screen orientation isn't supported when activities aren't in full screen
4639                // mode.
4640                return;
4641            }
4642            final long origId = Binder.clearCallingIdentity();
4643            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4644            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4645                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4646            if (config != null) {
4647                r.frozenBeforeDestroy = true;
4648                if (!updateConfigurationLocked(config, r, false)) {
4649                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4650                }
4651            }
4652            Binder.restoreCallingIdentity(origId);
4653        }
4654    }
4655
4656    @Override
4657    public int getRequestedOrientation(IBinder token) {
4658        synchronized (this) {
4659            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4660            if (r == null) {
4661                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4662            }
4663            return mWindowManager.getAppOrientation(r.appToken);
4664        }
4665    }
4666
4667    /**
4668     * This is the internal entry point for handling Activity.finish().
4669     *
4670     * @param token The Binder token referencing the Activity we want to finish.
4671     * @param resultCode Result code, if any, from this Activity.
4672     * @param resultData Result data (Intent), if any, from this Activity.
4673     * @param finishTask Whether to finish the task associated with this Activity.
4674     *
4675     * @return Returns true if the activity successfully finished, or false if it is still running.
4676     */
4677    @Override
4678    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4679            int finishTask) {
4680        // Refuse possible leaked file descriptors
4681        if (resultData != null && resultData.hasFileDescriptors() == true) {
4682            throw new IllegalArgumentException("File descriptors passed in Intent");
4683        }
4684
4685        synchronized(this) {
4686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4687            if (r == null) {
4688                return true;
4689            }
4690            // Keep track of the root activity of the task before we finish it
4691            TaskRecord tr = r.task;
4692            ActivityRecord rootR = tr.getRootActivity();
4693            if (rootR == null) {
4694                Slog.w(TAG, "Finishing task with all activities already finished");
4695            }
4696            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4697            // finish.
4698            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4699                    mStackSupervisor.isLastLockedTask(tr)) {
4700                Slog.i(TAG, "Not finishing task in lock task mode");
4701                mStackSupervisor.showLockTaskToast();
4702                return false;
4703            }
4704            if (mController != null) {
4705                // Find the first activity that is not finishing.
4706                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4707                if (next != null) {
4708                    // ask watcher if this is allowed
4709                    boolean resumeOK = true;
4710                    try {
4711                        resumeOK = mController.activityResuming(next.packageName);
4712                    } catch (RemoteException e) {
4713                        mController = null;
4714                        Watchdog.getInstance().setActivityController(null);
4715                    }
4716
4717                    if (!resumeOK) {
4718                        Slog.i(TAG, "Not finishing activity because controller resumed");
4719                        return false;
4720                    }
4721                }
4722            }
4723            final long origId = Binder.clearCallingIdentity();
4724            try {
4725                boolean res;
4726                final boolean finishWithRootActivity =
4727                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4728                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4729                        || (finishWithRootActivity && r == rootR)) {
4730                    // If requested, remove the task that is associated to this activity only if it
4731                    // was the root activity in the task. The result code and data is ignored
4732                    // because we don't support returning them across task boundaries. Also, to
4733                    // keep backwards compatibility we remove the task from recents when finishing
4734                    // task with root activity.
4735                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4736                    if (!res) {
4737                        Slog.i(TAG, "Removing task failed to finish activity");
4738                    }
4739                } else {
4740                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4741                            resultData, "app-request", true);
4742                    if (!res) {
4743                        Slog.i(TAG, "Failed to finish by app-request");
4744                    }
4745                }
4746                return res;
4747            } finally {
4748                Binder.restoreCallingIdentity(origId);
4749            }
4750        }
4751    }
4752
4753    @Override
4754    public final void finishHeavyWeightApp() {
4755        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4756                != PackageManager.PERMISSION_GRANTED) {
4757            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4758                    + Binder.getCallingPid()
4759                    + ", uid=" + Binder.getCallingUid()
4760                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4761            Slog.w(TAG, msg);
4762            throw new SecurityException(msg);
4763        }
4764
4765        synchronized(this) {
4766            if (mHeavyWeightProcess == null) {
4767                return;
4768            }
4769
4770            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4771            for (int i = 0; i < activities.size(); i++) {
4772                ActivityRecord r = activities.get(i);
4773                if (!r.finishing && r.isInStackLocked()) {
4774                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4775                            null, "finish-heavy", true);
4776                }
4777            }
4778
4779            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4780                    mHeavyWeightProcess.userId, 0));
4781            mHeavyWeightProcess = null;
4782        }
4783    }
4784
4785    @Override
4786    public void crashApplication(int uid, int initialPid, String packageName,
4787            String message) {
4788        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4789                != PackageManager.PERMISSION_GRANTED) {
4790            String msg = "Permission Denial: crashApplication() from pid="
4791                    + Binder.getCallingPid()
4792                    + ", uid=" + Binder.getCallingUid()
4793                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4794            Slog.w(TAG, msg);
4795            throw new SecurityException(msg);
4796        }
4797
4798        synchronized(this) {
4799            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4800        }
4801    }
4802
4803    @Override
4804    public final void finishSubActivity(IBinder token, String resultWho,
4805            int requestCode) {
4806        synchronized(this) {
4807            final long origId = Binder.clearCallingIdentity();
4808            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4809            if (r != null) {
4810                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4811            }
4812            Binder.restoreCallingIdentity(origId);
4813        }
4814    }
4815
4816    @Override
4817    public boolean finishActivityAffinity(IBinder token) {
4818        synchronized(this) {
4819            final long origId = Binder.clearCallingIdentity();
4820            try {
4821                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822                if (r == null) {
4823                    return false;
4824                }
4825
4826                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4827                // can finish.
4828                final TaskRecord task = r.task;
4829                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4830                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4831                    mStackSupervisor.showLockTaskToast();
4832                    return false;
4833                }
4834                return task.stack.finishActivityAffinityLocked(r);
4835            } finally {
4836                Binder.restoreCallingIdentity(origId);
4837            }
4838        }
4839    }
4840
4841    @Override
4842    public void finishVoiceTask(IVoiceInteractionSession session) {
4843        synchronized (this) {
4844            final long origId = Binder.clearCallingIdentity();
4845            try {
4846                // TODO: VI Consider treating local voice interactions and voice tasks
4847                // differently here
4848                mStackSupervisor.finishVoiceTask(session);
4849            } finally {
4850                Binder.restoreCallingIdentity(origId);
4851            }
4852        }
4853
4854    }
4855
4856    @Override
4857    public boolean releaseActivityInstance(IBinder token) {
4858        synchronized(this) {
4859            final long origId = Binder.clearCallingIdentity();
4860            try {
4861                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4862                if (r == null) {
4863                    return false;
4864                }
4865                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4866            } finally {
4867                Binder.restoreCallingIdentity(origId);
4868            }
4869        }
4870    }
4871
4872    @Override
4873    public void releaseSomeActivities(IApplicationThread appInt) {
4874        synchronized(this) {
4875            final long origId = Binder.clearCallingIdentity();
4876            try {
4877                ProcessRecord app = getRecordForAppLocked(appInt);
4878                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4879            } finally {
4880                Binder.restoreCallingIdentity(origId);
4881            }
4882        }
4883    }
4884
4885    @Override
4886    public boolean willActivityBeVisible(IBinder token) {
4887        synchronized(this) {
4888            ActivityStack stack = ActivityRecord.getStackLocked(token);
4889            if (stack != null) {
4890                return stack.willActivityBeVisibleLocked(token);
4891            }
4892            return false;
4893        }
4894    }
4895
4896    @Override
4897    public void overridePendingTransition(IBinder token, String packageName,
4898            int enterAnim, int exitAnim) {
4899        synchronized(this) {
4900            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4901            if (self == null) {
4902                return;
4903            }
4904
4905            final long origId = Binder.clearCallingIdentity();
4906
4907            if (self.state == ActivityState.RESUMED
4908                    || self.state == ActivityState.PAUSING) {
4909                mWindowManager.overridePendingAppTransition(packageName,
4910                        enterAnim, exitAnim, null);
4911            }
4912
4913            Binder.restoreCallingIdentity(origId);
4914        }
4915    }
4916
4917    /**
4918     * Main function for removing an existing process from the activity manager
4919     * as a result of that process going away.  Clears out all connections
4920     * to the process.
4921     */
4922    private final void handleAppDiedLocked(ProcessRecord app,
4923            boolean restarting, boolean allowRestart) {
4924        int pid = app.pid;
4925        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4926        if (!kept && !restarting) {
4927            removeLruProcessLocked(app);
4928            if (pid > 0) {
4929                ProcessList.remove(pid);
4930            }
4931        }
4932
4933        if (mProfileProc == app) {
4934            clearProfilerLocked();
4935        }
4936
4937        // Remove this application's activities from active lists.
4938        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4939
4940        app.activities.clear();
4941
4942        if (app.instrumentationClass != null) {
4943            Slog.w(TAG, "Crash of app " + app.processName
4944                  + " running instrumentation " + app.instrumentationClass);
4945            Bundle info = new Bundle();
4946            info.putString("shortMsg", "Process crashed.");
4947            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4948        }
4949
4950        if (!restarting && hasVisibleActivities
4951                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4952            // If there was nothing to resume, and we are not already restarting this process, but
4953            // there is a visible activity that is hosted by the process...  then make sure all
4954            // visible activities are running, taking care of restarting this process.
4955            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4956        }
4957    }
4958
4959    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4960        IBinder threadBinder = thread.asBinder();
4961        // Find the application record.
4962        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4963            ProcessRecord rec = mLruProcesses.get(i);
4964            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4965                return i;
4966            }
4967        }
4968        return -1;
4969    }
4970
4971    final ProcessRecord getRecordForAppLocked(
4972            IApplicationThread thread) {
4973        if (thread == null) {
4974            return null;
4975        }
4976
4977        int appIndex = getLRURecordIndexForAppLocked(thread);
4978        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4979    }
4980
4981    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4982        // If there are no longer any background processes running,
4983        // and the app that died was not running instrumentation,
4984        // then tell everyone we are now low on memory.
4985        boolean haveBg = false;
4986        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4987            ProcessRecord rec = mLruProcesses.get(i);
4988            if (rec.thread != null
4989                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4990                haveBg = true;
4991                break;
4992            }
4993        }
4994
4995        if (!haveBg) {
4996            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4997            if (doReport) {
4998                long now = SystemClock.uptimeMillis();
4999                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5000                    doReport = false;
5001                } else {
5002                    mLastMemUsageReportTime = now;
5003                }
5004            }
5005            final ArrayList<ProcessMemInfo> memInfos
5006                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5007            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5008            long now = SystemClock.uptimeMillis();
5009            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5010                ProcessRecord rec = mLruProcesses.get(i);
5011                if (rec == dyingProc || rec.thread == null) {
5012                    continue;
5013                }
5014                if (doReport) {
5015                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5016                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5017                }
5018                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5019                    // The low memory report is overriding any current
5020                    // state for a GC request.  Make sure to do
5021                    // heavy/important/visible/foreground processes first.
5022                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5023                        rec.lastRequestedGc = 0;
5024                    } else {
5025                        rec.lastRequestedGc = rec.lastLowMemory;
5026                    }
5027                    rec.reportLowMemory = true;
5028                    rec.lastLowMemory = now;
5029                    mProcessesToGc.remove(rec);
5030                    addProcessToGcListLocked(rec);
5031                }
5032            }
5033            if (doReport) {
5034                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5035                mHandler.sendMessage(msg);
5036            }
5037            scheduleAppGcsLocked();
5038        }
5039    }
5040
5041    final void appDiedLocked(ProcessRecord app) {
5042       appDiedLocked(app, app.pid, app.thread, false);
5043    }
5044
5045    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5046            boolean fromBinderDied) {
5047        // First check if this ProcessRecord is actually active for the pid.
5048        synchronized (mPidsSelfLocked) {
5049            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5050            if (curProc != app) {
5051                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5052                return;
5053            }
5054        }
5055
5056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5057        synchronized (stats) {
5058            stats.noteProcessDiedLocked(app.info.uid, pid);
5059        }
5060
5061        if (!app.killed) {
5062            if (!fromBinderDied) {
5063                Process.killProcessQuiet(pid);
5064            }
5065            killProcessGroup(app.uid, pid);
5066            app.killed = true;
5067        }
5068
5069        // Clean up already done if the process has been re-started.
5070        if (app.pid == pid && app.thread != null &&
5071                app.thread.asBinder() == thread.asBinder()) {
5072            boolean doLowMem = app.instrumentationClass == null;
5073            boolean doOomAdj = doLowMem;
5074            if (!app.killedByAm) {
5075                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5076                        + ") has died");
5077                mAllowLowerMemLevel = true;
5078            } else {
5079                // Note that we always want to do oom adj to update our state with the
5080                // new number of procs.
5081                mAllowLowerMemLevel = false;
5082                doLowMem = false;
5083            }
5084            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5085            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5086                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5087            handleAppDiedLocked(app, false, true);
5088
5089            if (doOomAdj) {
5090                updateOomAdjLocked();
5091            }
5092            if (doLowMem) {
5093                doLowMemReportIfNeededLocked(app);
5094            }
5095        } else if (app.pid != pid) {
5096            // A new process has already been started.
5097            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5098                    + ") has died and restarted (pid " + app.pid + ").");
5099            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5100        } else if (DEBUG_PROCESSES) {
5101            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5102                    + thread.asBinder());
5103        }
5104    }
5105
5106    /**
5107     * If a stack trace dump file is configured, dump process stack traces.
5108     * @param clearTraces causes the dump file to be erased prior to the new
5109     *    traces being written, if true; when false, the new traces will be
5110     *    appended to any existing file content.
5111     * @param firstPids of dalvik VM processes to dump stack traces for first
5112     * @param lastPids of dalvik VM processes to dump stack traces for last
5113     * @param nativeProcs optional list of native process names to dump stack crawls
5114     * @return file containing stack traces, or null if no dump file is configured
5115     */
5116    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5117            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5118        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5119        if (tracesPath == null || tracesPath.length() == 0) {
5120            return null;
5121        }
5122
5123        File tracesFile = new File(tracesPath);
5124        try {
5125            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5126            tracesFile.createNewFile();
5127            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5128        } catch (IOException e) {
5129            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5130            return null;
5131        }
5132
5133        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5134        return tracesFile;
5135    }
5136
5137    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5138            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5139        // Use a FileObserver to detect when traces finish writing.
5140        // The order of traces is considered important to maintain for legibility.
5141        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5142            @Override
5143            public synchronized void onEvent(int event, String path) { notify(); }
5144        };
5145
5146        try {
5147            observer.startWatching();
5148
5149            // First collect all of the stacks of the most important pids.
5150            if (firstPids != null) {
5151                try {
5152                    int num = firstPids.size();
5153                    for (int i = 0; i < num; i++) {
5154                        synchronized (observer) {
5155                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5156                                    + firstPids.get(i));
5157                            final long sime = SystemClock.elapsedRealtime();
5158                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5159                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5160                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5161                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5162                        }
5163                    }
5164                } catch (InterruptedException e) {
5165                    Slog.wtf(TAG, e);
5166                }
5167            }
5168
5169            // Next collect the stacks of the native pids
5170            if (nativeProcs != null) {
5171                int[] pids = Process.getPidsForCommands(nativeProcs);
5172                if (pids != null) {
5173                    for (int pid : pids) {
5174                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5175                        final long sime = SystemClock.elapsedRealtime();
5176                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5177                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5178                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5179                    }
5180                }
5181            }
5182
5183            // Lastly, measure CPU usage.
5184            if (processCpuTracker != null) {
5185                processCpuTracker.init();
5186                System.gc();
5187                processCpuTracker.update();
5188                try {
5189                    synchronized (processCpuTracker) {
5190                        processCpuTracker.wait(500); // measure over 1/2 second.
5191                    }
5192                } catch (InterruptedException e) {
5193                }
5194                processCpuTracker.update();
5195
5196                // We'll take the stack crawls of just the top apps using CPU.
5197                final int N = processCpuTracker.countWorkingStats();
5198                int numProcs = 0;
5199                for (int i=0; i<N && numProcs<5; i++) {
5200                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5201                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5202                        numProcs++;
5203                        try {
5204                            synchronized (observer) {
5205                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5206                                        + stats.pid);
5207                                final long stime = SystemClock.elapsedRealtime();
5208                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5209                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5210                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5211                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5212                            }
5213                        } catch (InterruptedException e) {
5214                            Slog.wtf(TAG, e);
5215                        }
5216                    } else if (DEBUG_ANR) {
5217                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5218                                + stats.pid);
5219                    }
5220                }
5221            }
5222        } finally {
5223            observer.stopWatching();
5224        }
5225    }
5226
5227    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5228        if (true || IS_USER_BUILD) {
5229            return;
5230        }
5231        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5232        if (tracesPath == null || tracesPath.length() == 0) {
5233            return;
5234        }
5235
5236        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5237        StrictMode.allowThreadDiskWrites();
5238        try {
5239            final File tracesFile = new File(tracesPath);
5240            final File tracesDir = tracesFile.getParentFile();
5241            final File tracesTmp = new File(tracesDir, "__tmp__");
5242            try {
5243                if (tracesFile.exists()) {
5244                    tracesTmp.delete();
5245                    tracesFile.renameTo(tracesTmp);
5246                }
5247                StringBuilder sb = new StringBuilder();
5248                Time tobj = new Time();
5249                tobj.set(System.currentTimeMillis());
5250                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5251                sb.append(": ");
5252                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5253                sb.append(" since ");
5254                sb.append(msg);
5255                FileOutputStream fos = new FileOutputStream(tracesFile);
5256                fos.write(sb.toString().getBytes());
5257                if (app == null) {
5258                    fos.write("\n*** No application process!".getBytes());
5259                }
5260                fos.close();
5261                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5262            } catch (IOException e) {
5263                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5264                return;
5265            }
5266
5267            if (app != null) {
5268                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5269                firstPids.add(app.pid);
5270                dumpStackTraces(tracesPath, firstPids, null, null, null);
5271            }
5272
5273            File lastTracesFile = null;
5274            File curTracesFile = null;
5275            for (int i=9; i>=0; i--) {
5276                String name = String.format(Locale.US, "slow%02d.txt", i);
5277                curTracesFile = new File(tracesDir, name);
5278                if (curTracesFile.exists()) {
5279                    if (lastTracesFile != null) {
5280                        curTracesFile.renameTo(lastTracesFile);
5281                    } else {
5282                        curTracesFile.delete();
5283                    }
5284                }
5285                lastTracesFile = curTracesFile;
5286            }
5287            tracesFile.renameTo(curTracesFile);
5288            if (tracesTmp.exists()) {
5289                tracesTmp.renameTo(tracesFile);
5290            }
5291        } finally {
5292            StrictMode.setThreadPolicy(oldPolicy);
5293        }
5294    }
5295
5296    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5297        if (!mLaunchWarningShown) {
5298            mLaunchWarningShown = true;
5299            mUiHandler.post(new Runnable() {
5300                @Override
5301                public void run() {
5302                    synchronized (ActivityManagerService.this) {
5303                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5304                        d.show();
5305                        mUiHandler.postDelayed(new Runnable() {
5306                            @Override
5307                            public void run() {
5308                                synchronized (ActivityManagerService.this) {
5309                                    d.dismiss();
5310                                    mLaunchWarningShown = false;
5311                                }
5312                            }
5313                        }, 4000);
5314                    }
5315                }
5316            });
5317        }
5318    }
5319
5320    @Override
5321    public boolean clearApplicationUserData(final String packageName,
5322            final IPackageDataObserver observer, int userId) {
5323        enforceNotIsolatedCaller("clearApplicationUserData");
5324        int uid = Binder.getCallingUid();
5325        int pid = Binder.getCallingPid();
5326        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5327                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5328
5329        final DevicePolicyManagerInternal dpmi = LocalServices
5330                .getService(DevicePolicyManagerInternal.class);
5331        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5332            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5333        }
5334
5335        long callingId = Binder.clearCallingIdentity();
5336        try {
5337            IPackageManager pm = AppGlobals.getPackageManager();
5338            int pkgUid = -1;
5339            synchronized(this) {
5340                try {
5341                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5342                } catch (RemoteException e) {
5343                }
5344                if (pkgUid == -1) {
5345                    Slog.w(TAG, "Invalid packageName: " + packageName);
5346                    if (observer != null) {
5347                        try {
5348                            observer.onRemoveCompleted(packageName, false);
5349                        } catch (RemoteException e) {
5350                            Slog.i(TAG, "Observer no longer exists.");
5351                        }
5352                    }
5353                    return false;
5354                }
5355                if (uid == pkgUid || checkComponentPermission(
5356                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5357                        pid, uid, -1, true)
5358                        == PackageManager.PERMISSION_GRANTED) {
5359                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5360                } else {
5361                    throw new SecurityException("PID " + pid + " does not have permission "
5362                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5363                                    + " of package " + packageName);
5364                }
5365
5366                // Remove all tasks match the cleared application package and user
5367                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5368                    final TaskRecord tr = mRecentTasks.get(i);
5369                    final String taskPackageName =
5370                            tr.getBaseIntent().getComponent().getPackageName();
5371                    if (tr.userId != userId) continue;
5372                    if (!taskPackageName.equals(packageName)) continue;
5373                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5374                }
5375            }
5376
5377            try {
5378                // Clear application user data
5379                pm.clearApplicationUserData(packageName, observer, userId);
5380
5381                synchronized(this) {
5382                    // Remove all permissions granted from/to this package
5383                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5384                }
5385
5386                // Remove all zen rules created by this package; revoke it's zen access.
5387                INotificationManager inm = NotificationManager.getService();
5388                inm.removeAutomaticZenRules(packageName);
5389                inm.setNotificationPolicyAccessGranted(packageName, false);
5390
5391                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5392                        Uri.fromParts("package", packageName, null));
5393                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5394                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5395                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5396                        null, null, 0, null, null, null, null, false, false, userId);
5397            } catch (RemoteException e) {
5398            }
5399        } finally {
5400            Binder.restoreCallingIdentity(callingId);
5401        }
5402        return true;
5403    }
5404
5405    @Override
5406    public void killBackgroundProcesses(final String packageName, int userId) {
5407        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5408                != PackageManager.PERMISSION_GRANTED &&
5409                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5410                        != PackageManager.PERMISSION_GRANTED) {
5411            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5412                    + Binder.getCallingPid()
5413                    + ", uid=" + Binder.getCallingUid()
5414                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5415            Slog.w(TAG, msg);
5416            throw new SecurityException(msg);
5417        }
5418
5419        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5420                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5421        long callingId = Binder.clearCallingIdentity();
5422        try {
5423            IPackageManager pm = AppGlobals.getPackageManager();
5424            synchronized(this) {
5425                int appId = -1;
5426                try {
5427                    appId = UserHandle.getAppId(
5428                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5429                } catch (RemoteException e) {
5430                }
5431                if (appId == -1) {
5432                    Slog.w(TAG, "Invalid packageName: " + packageName);
5433                    return;
5434                }
5435                killPackageProcessesLocked(packageName, appId, userId,
5436                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5437            }
5438        } finally {
5439            Binder.restoreCallingIdentity(callingId);
5440        }
5441    }
5442
5443    @Override
5444    public void killAllBackgroundProcesses() {
5445        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5446                != PackageManager.PERMISSION_GRANTED) {
5447            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5448                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5449                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5450            Slog.w(TAG, msg);
5451            throw new SecurityException(msg);
5452        }
5453
5454        final long callingId = Binder.clearCallingIdentity();
5455        try {
5456            synchronized (this) {
5457                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5458                final int NP = mProcessNames.getMap().size();
5459                for (int ip = 0; ip < NP; ip++) {
5460                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5461                    final int NA = apps.size();
5462                    for (int ia = 0; ia < NA; ia++) {
5463                        final ProcessRecord app = apps.valueAt(ia);
5464                        if (app.persistent) {
5465                            // We don't kill persistent processes.
5466                            continue;
5467                        }
5468                        if (app.removed) {
5469                            procs.add(app);
5470                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5471                            app.removed = true;
5472                            procs.add(app);
5473                        }
5474                    }
5475                }
5476
5477                final int N = procs.size();
5478                for (int i = 0; i < N; i++) {
5479                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5480                }
5481
5482                mAllowLowerMemLevel = true;
5483
5484                updateOomAdjLocked();
5485                doLowMemReportIfNeededLocked(null);
5486            }
5487        } finally {
5488            Binder.restoreCallingIdentity(callingId);
5489        }
5490    }
5491
5492    /**
5493     * Kills all background processes, except those matching any of the
5494     * specified properties.
5495     *
5496     * @param minTargetSdk the target SDK version at or above which to preserve
5497     *                     processes, or {@code -1} to ignore the target SDK
5498     * @param maxProcState the process state at or below which to preserve
5499     *                     processes, or {@code -1} to ignore the process state
5500     */
5501    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5502        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5503                != PackageManager.PERMISSION_GRANTED) {
5504            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5505                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5506                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5507            Slog.w(TAG, msg);
5508            throw new SecurityException(msg);
5509        }
5510
5511        final long callingId = Binder.clearCallingIdentity();
5512        try {
5513            synchronized (this) {
5514                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5515                final int NP = mProcessNames.getMap().size();
5516                for (int ip = 0; ip < NP; ip++) {
5517                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5518                    final int NA = apps.size();
5519                    for (int ia = 0; ia < NA; ia++) {
5520                        final ProcessRecord app = apps.valueAt(ia);
5521                        if (app.removed) {
5522                            procs.add(app);
5523                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5524                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5525                            app.removed = true;
5526                            procs.add(app);
5527                        }
5528                    }
5529                }
5530
5531                final int N = procs.size();
5532                for (int i = 0; i < N; i++) {
5533                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5534                }
5535            }
5536        } finally {
5537            Binder.restoreCallingIdentity(callingId);
5538        }
5539    }
5540
5541    @Override
5542    public void forceStopPackage(final String packageName, int userId) {
5543        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5544                != PackageManager.PERMISSION_GRANTED) {
5545            String msg = "Permission Denial: forceStopPackage() from pid="
5546                    + Binder.getCallingPid()
5547                    + ", uid=" + Binder.getCallingUid()
5548                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5549            Slog.w(TAG, msg);
5550            throw new SecurityException(msg);
5551        }
5552        final int callingPid = Binder.getCallingPid();
5553        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5554                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5555        long callingId = Binder.clearCallingIdentity();
5556        try {
5557            IPackageManager pm = AppGlobals.getPackageManager();
5558            synchronized(this) {
5559                int[] users = userId == UserHandle.USER_ALL
5560                        ? mUserController.getUsers() : new int[] { userId };
5561                for (int user : users) {
5562                    int pkgUid = -1;
5563                    try {
5564                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5565                                user);
5566                    } catch (RemoteException e) {
5567                    }
5568                    if (pkgUid == -1) {
5569                        Slog.w(TAG, "Invalid packageName: " + packageName);
5570                        continue;
5571                    }
5572                    try {
5573                        pm.setPackageStoppedState(packageName, true, user);
5574                    } catch (RemoteException e) {
5575                    } catch (IllegalArgumentException e) {
5576                        Slog.w(TAG, "Failed trying to unstop package "
5577                                + packageName + ": " + e);
5578                    }
5579                    if (mUserController.isUserRunningLocked(user, 0)) {
5580                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5581                    }
5582                }
5583            }
5584        } finally {
5585            Binder.restoreCallingIdentity(callingId);
5586        }
5587    }
5588
5589    @Override
5590    public void addPackageDependency(String packageName) {
5591        synchronized (this) {
5592            int callingPid = Binder.getCallingPid();
5593            if (callingPid == Process.myPid()) {
5594                //  Yeah, um, no.
5595                return;
5596            }
5597            ProcessRecord proc;
5598            synchronized (mPidsSelfLocked) {
5599                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5600            }
5601            if (proc != null) {
5602                if (proc.pkgDeps == null) {
5603                    proc.pkgDeps = new ArraySet<String>(1);
5604                }
5605                proc.pkgDeps.add(packageName);
5606            }
5607        }
5608    }
5609
5610    /*
5611     * The pkg name and app id have to be specified.
5612     */
5613    @Override
5614    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5615        if (pkg == null) {
5616            return;
5617        }
5618        // Make sure the uid is valid.
5619        if (appid < 0) {
5620            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5621            return;
5622        }
5623        int callerUid = Binder.getCallingUid();
5624        // Only the system server can kill an application
5625        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5626            // Post an aysnc message to kill the application
5627            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5628            msg.arg1 = appid;
5629            msg.arg2 = 0;
5630            Bundle bundle = new Bundle();
5631            bundle.putString("pkg", pkg);
5632            bundle.putString("reason", reason);
5633            msg.obj = bundle;
5634            mHandler.sendMessage(msg);
5635        } else {
5636            throw new SecurityException(callerUid + " cannot kill pkg: " +
5637                    pkg);
5638        }
5639    }
5640
5641    @Override
5642    public void closeSystemDialogs(String reason) {
5643        enforceNotIsolatedCaller("closeSystemDialogs");
5644
5645        final int pid = Binder.getCallingPid();
5646        final int uid = Binder.getCallingUid();
5647        final long origId = Binder.clearCallingIdentity();
5648        try {
5649            synchronized (this) {
5650                // Only allow this from foreground processes, so that background
5651                // applications can't abuse it to prevent system UI from being shown.
5652                if (uid >= Process.FIRST_APPLICATION_UID) {
5653                    ProcessRecord proc;
5654                    synchronized (mPidsSelfLocked) {
5655                        proc = mPidsSelfLocked.get(pid);
5656                    }
5657                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5658                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5659                                + " from background process " + proc);
5660                        return;
5661                    }
5662                }
5663                closeSystemDialogsLocked(reason);
5664            }
5665        } finally {
5666            Binder.restoreCallingIdentity(origId);
5667        }
5668    }
5669
5670    void closeSystemDialogsLocked(String reason) {
5671        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5672        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5673                | Intent.FLAG_RECEIVER_FOREGROUND);
5674        if (reason != null) {
5675            intent.putExtra("reason", reason);
5676        }
5677        mWindowManager.closeSystemDialogs(reason);
5678
5679        mStackSupervisor.closeSystemDialogsLocked();
5680
5681        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5682                AppOpsManager.OP_NONE, null, false, false,
5683                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5684    }
5685
5686    @Override
5687    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5688        enforceNotIsolatedCaller("getProcessMemoryInfo");
5689        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5690        for (int i=pids.length-1; i>=0; i--) {
5691            ProcessRecord proc;
5692            int oomAdj;
5693            synchronized (this) {
5694                synchronized (mPidsSelfLocked) {
5695                    proc = mPidsSelfLocked.get(pids[i]);
5696                    oomAdj = proc != null ? proc.setAdj : 0;
5697                }
5698            }
5699            infos[i] = new Debug.MemoryInfo();
5700            Debug.getMemoryInfo(pids[i], infos[i]);
5701            if (proc != null) {
5702                synchronized (this) {
5703                    if (proc.thread != null && proc.setAdj == oomAdj) {
5704                        // Record this for posterity if the process has been stable.
5705                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5706                                infos[i].getTotalUss(), false, proc.pkgList);
5707                    }
5708                }
5709            }
5710        }
5711        return infos;
5712    }
5713
5714    @Override
5715    public long[] getProcessPss(int[] pids) {
5716        enforceNotIsolatedCaller("getProcessPss");
5717        long[] pss = new long[pids.length];
5718        for (int i=pids.length-1; i>=0; i--) {
5719            ProcessRecord proc;
5720            int oomAdj;
5721            synchronized (this) {
5722                synchronized (mPidsSelfLocked) {
5723                    proc = mPidsSelfLocked.get(pids[i]);
5724                    oomAdj = proc != null ? proc.setAdj : 0;
5725                }
5726            }
5727            long[] tmpUss = new long[1];
5728            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5729            if (proc != null) {
5730                synchronized (this) {
5731                    if (proc.thread != null && proc.setAdj == oomAdj) {
5732                        // Record this for posterity if the process has been stable.
5733                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5734                    }
5735                }
5736            }
5737        }
5738        return pss;
5739    }
5740
5741    @Override
5742    public void killApplicationProcess(String processName, int uid) {
5743        if (processName == null) {
5744            return;
5745        }
5746
5747        int callerUid = Binder.getCallingUid();
5748        // Only the system server can kill an application
5749        if (callerUid == Process.SYSTEM_UID) {
5750            synchronized (this) {
5751                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5752                if (app != null && app.thread != null) {
5753                    try {
5754                        app.thread.scheduleSuicide();
5755                    } catch (RemoteException e) {
5756                        // If the other end already died, then our work here is done.
5757                    }
5758                } else {
5759                    Slog.w(TAG, "Process/uid not found attempting kill of "
5760                            + processName + " / " + uid);
5761                }
5762            }
5763        } else {
5764            throw new SecurityException(callerUid + " cannot kill app process: " +
5765                    processName);
5766        }
5767    }
5768
5769    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5770        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5771                false, true, false, false, UserHandle.getUserId(uid), reason);
5772        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5773                Uri.fromParts("package", packageName, null));
5774        if (!mProcessesReady) {
5775            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5776                    | Intent.FLAG_RECEIVER_FOREGROUND);
5777        }
5778        intent.putExtra(Intent.EXTRA_UID, uid);
5779        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5780        broadcastIntentLocked(null, null, intent,
5781                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5782                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5783    }
5784
5785
5786    private final boolean killPackageProcessesLocked(String packageName, int appId,
5787            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5788            boolean doit, boolean evenPersistent, String reason) {
5789        ArrayList<ProcessRecord> procs = new ArrayList<>();
5790
5791        // Remove all processes this package may have touched: all with the
5792        // same UID (except for the system or root user), and all whose name
5793        // matches the package name.
5794        final int NP = mProcessNames.getMap().size();
5795        for (int ip=0; ip<NP; ip++) {
5796            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5797            final int NA = apps.size();
5798            for (int ia=0; ia<NA; ia++) {
5799                ProcessRecord app = apps.valueAt(ia);
5800                if (app.persistent && !evenPersistent) {
5801                    // we don't kill persistent processes
5802                    continue;
5803                }
5804                if (app.removed) {
5805                    if (doit) {
5806                        procs.add(app);
5807                    }
5808                    continue;
5809                }
5810
5811                // Skip process if it doesn't meet our oom adj requirement.
5812                if (app.setAdj < minOomAdj) {
5813                    continue;
5814                }
5815
5816                // If no package is specified, we call all processes under the
5817                // give user id.
5818                if (packageName == null) {
5819                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5820                        continue;
5821                    }
5822                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5823                        continue;
5824                    }
5825                // Package has been specified, we want to hit all processes
5826                // that match it.  We need to qualify this by the processes
5827                // that are running under the specified app and user ID.
5828                } else {
5829                    final boolean isDep = app.pkgDeps != null
5830                            && app.pkgDeps.contains(packageName);
5831                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5832                        continue;
5833                    }
5834                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5835                        continue;
5836                    }
5837                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5838                        continue;
5839                    }
5840                }
5841
5842                // Process has passed all conditions, kill it!
5843                if (!doit) {
5844                    return true;
5845                }
5846                app.removed = true;
5847                procs.add(app);
5848            }
5849        }
5850
5851        int N = procs.size();
5852        for (int i=0; i<N; i++) {
5853            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5854        }
5855        updateOomAdjLocked();
5856        return N > 0;
5857    }
5858
5859    private void cleanupDisabledPackageComponentsLocked(
5860            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5861
5862        Set<String> disabledClasses = null;
5863        boolean packageDisabled = false;
5864        IPackageManager pm = AppGlobals.getPackageManager();
5865
5866        if (changedClasses == null) {
5867            // Nothing changed...
5868            return;
5869        }
5870
5871        // Determine enable/disable state of the package and its components.
5872        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5873        for (int i = changedClasses.length - 1; i >= 0; i--) {
5874            final String changedClass = changedClasses[i];
5875
5876            if (changedClass.equals(packageName)) {
5877                try {
5878                    // Entire package setting changed
5879                    enabled = pm.getApplicationEnabledSetting(packageName,
5880                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5881                } catch (Exception e) {
5882                    // No such package/component; probably racing with uninstall.  In any
5883                    // event it means we have nothing further to do here.
5884                    return;
5885                }
5886                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5887                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5888                if (packageDisabled) {
5889                    // Entire package is disabled.
5890                    // No need to continue to check component states.
5891                    disabledClasses = null;
5892                    break;
5893                }
5894            } else {
5895                try {
5896                    enabled = pm.getComponentEnabledSetting(
5897                            new ComponentName(packageName, changedClass),
5898                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5899                } catch (Exception e) {
5900                    // As above, probably racing with uninstall.
5901                    return;
5902                }
5903                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5904                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5905                    if (disabledClasses == null) {
5906                        disabledClasses = new ArraySet<>(changedClasses.length);
5907                    }
5908                    disabledClasses.add(changedClass);
5909                }
5910            }
5911        }
5912
5913        if (!packageDisabled && disabledClasses == null) {
5914            // Nothing to do here...
5915            return;
5916        }
5917
5918        // Clean-up disabled activities.
5919        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5920                packageName, disabledClasses, true, false, userId) && mBooted) {
5921            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5922            mStackSupervisor.scheduleIdleLocked();
5923        }
5924
5925        // Clean-up disabled tasks
5926        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5927
5928        // Clean-up disabled services.
5929        mServices.bringDownDisabledPackageServicesLocked(
5930                packageName, disabledClasses, userId, false, killProcess, true);
5931
5932        // Clean-up disabled providers.
5933        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5934        mProviderMap.collectPackageProvidersLocked(
5935                packageName, disabledClasses, true, false, userId, providers);
5936        for (int i = providers.size() - 1; i >= 0; i--) {
5937            removeDyingProviderLocked(null, providers.get(i), true);
5938        }
5939
5940        // Clean-up disabled broadcast receivers.
5941        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5942            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5943                    packageName, disabledClasses, userId, true);
5944        }
5945
5946    }
5947
5948    final boolean forceStopPackageLocked(String packageName, int appId,
5949            boolean callerWillRestart, boolean purgeCache, boolean doit,
5950            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5951        int i;
5952
5953        if (userId == UserHandle.USER_ALL && packageName == null) {
5954            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5955        }
5956
5957        if (appId < 0 && packageName != null) {
5958            try {
5959                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5960                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5961            } catch (RemoteException e) {
5962            }
5963        }
5964
5965        if (doit) {
5966            if (packageName != null) {
5967                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5968                        + " user=" + userId + ": " + reason);
5969            } else {
5970                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5971            }
5972
5973            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5974        }
5975
5976        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5977                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5978                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5979
5980        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5981                packageName, null, doit, evenPersistent, userId)) {
5982            if (!doit) {
5983                return true;
5984            }
5985            didSomething = true;
5986        }
5987
5988        if (mServices.bringDownDisabledPackageServicesLocked(
5989                packageName, null, userId, evenPersistent, true, doit)) {
5990            if (!doit) {
5991                return true;
5992            }
5993            didSomething = true;
5994        }
5995
5996        if (packageName == null) {
5997            // Remove all sticky broadcasts from this user.
5998            mStickyBroadcasts.remove(userId);
5999        }
6000
6001        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6002        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6003                userId, providers)) {
6004            if (!doit) {
6005                return true;
6006            }
6007            didSomething = true;
6008        }
6009        for (i = providers.size() - 1; i >= 0; i--) {
6010            removeDyingProviderLocked(null, providers.get(i), true);
6011        }
6012
6013        // Remove transient permissions granted from/to this package/user
6014        removeUriPermissionsForPackageLocked(packageName, userId, false);
6015
6016        if (doit) {
6017            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019                        packageName, null, userId, doit);
6020            }
6021        }
6022
6023        if (packageName == null || uninstalling) {
6024            // Remove pending intents.  For now we only do this when force
6025            // stopping users, because we have some problems when doing this
6026            // for packages -- app widgets are not currently cleaned up for
6027            // such packages, so they can be left with bad pending intents.
6028            if (mIntentSenderRecords.size() > 0) {
6029                Iterator<WeakReference<PendingIntentRecord>> it
6030                        = mIntentSenderRecords.values().iterator();
6031                while (it.hasNext()) {
6032                    WeakReference<PendingIntentRecord> wpir = it.next();
6033                    if (wpir == null) {
6034                        it.remove();
6035                        continue;
6036                    }
6037                    PendingIntentRecord pir = wpir.get();
6038                    if (pir == null) {
6039                        it.remove();
6040                        continue;
6041                    }
6042                    if (packageName == null) {
6043                        // Stopping user, remove all objects for the user.
6044                        if (pir.key.userId != userId) {
6045                            // Not the same user, skip it.
6046                            continue;
6047                        }
6048                    } else {
6049                        if (UserHandle.getAppId(pir.uid) != appId) {
6050                            // Different app id, skip it.
6051                            continue;
6052                        }
6053                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6054                            // Different user, skip it.
6055                            continue;
6056                        }
6057                        if (!pir.key.packageName.equals(packageName)) {
6058                            // Different package, skip it.
6059                            continue;
6060                        }
6061                    }
6062                    if (!doit) {
6063                        return true;
6064                    }
6065                    didSomething = true;
6066                    it.remove();
6067                    pir.canceled = true;
6068                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6069                        pir.key.activity.pendingResults.remove(pir.ref);
6070                    }
6071                }
6072            }
6073        }
6074
6075        if (doit) {
6076            if (purgeCache && packageName != null) {
6077                AttributeCache ac = AttributeCache.instance();
6078                if (ac != null) {
6079                    ac.removePackage(packageName);
6080                }
6081            }
6082            if (mBooted) {
6083                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6084                mStackSupervisor.scheduleIdleLocked();
6085            }
6086        }
6087
6088        return didSomething;
6089    }
6090
6091    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6092        ProcessRecord old = mProcessNames.remove(name, uid);
6093        if (old != null) {
6094            old.uidRecord.numProcs--;
6095            if (old.uidRecord.numProcs == 0) {
6096                // No more processes using this uid, tell clients it is gone.
6097                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6098                        "No more processes in " + old.uidRecord);
6099                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6100                mActiveUids.remove(uid);
6101                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6102            }
6103            old.uidRecord = null;
6104        }
6105        mIsolatedProcesses.remove(uid);
6106        return old;
6107    }
6108
6109    private final void addProcessNameLocked(ProcessRecord proc) {
6110        // We shouldn't already have a process under this name, but just in case we
6111        // need to clean up whatever may be there now.
6112        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6113        if (old == proc && proc.persistent) {
6114            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6115            Slog.w(TAG, "Re-adding persistent process " + proc);
6116        } else if (old != null) {
6117            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6118        }
6119        UidRecord uidRec = mActiveUids.get(proc.uid);
6120        if (uidRec == null) {
6121            uidRec = new UidRecord(proc.uid);
6122            // This is the first appearance of the uid, report it now!
6123            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6124                    "Creating new process uid: " + uidRec);
6125            mActiveUids.put(proc.uid, uidRec);
6126            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6127            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6128        }
6129        proc.uidRecord = uidRec;
6130        uidRec.numProcs++;
6131        mProcessNames.put(proc.processName, proc.uid, proc);
6132        if (proc.isolated) {
6133            mIsolatedProcesses.put(proc.uid, proc);
6134        }
6135    }
6136
6137    boolean removeProcessLocked(ProcessRecord app,
6138            boolean callerWillRestart, boolean allowRestart, String reason) {
6139        final String name = app.processName;
6140        final int uid = app.uid;
6141        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6142            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6143
6144        removeProcessNameLocked(name, uid);
6145        if (mHeavyWeightProcess == app) {
6146            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6147                    mHeavyWeightProcess.userId, 0));
6148            mHeavyWeightProcess = null;
6149        }
6150        boolean needRestart = false;
6151        if (app.pid > 0 && app.pid != MY_PID) {
6152            int pid = app.pid;
6153            synchronized (mPidsSelfLocked) {
6154                mPidsSelfLocked.remove(pid);
6155                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6156            }
6157            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6158            if (app.isolated) {
6159                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6160            }
6161            boolean willRestart = false;
6162            if (app.persistent && !app.isolated) {
6163                if (!callerWillRestart) {
6164                    willRestart = true;
6165                } else {
6166                    needRestart = true;
6167                }
6168            }
6169            app.kill(reason, true);
6170            handleAppDiedLocked(app, willRestart, allowRestart);
6171            if (willRestart) {
6172                removeLruProcessLocked(app);
6173                addAppLocked(app.info, false, null /* ABI override */);
6174            }
6175        } else {
6176            mRemovedProcesses.add(app);
6177        }
6178
6179        return needRestart;
6180    }
6181
6182    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6183        cleanupAppInLaunchingProvidersLocked(app, true);
6184        removeProcessLocked(app, false, true, "timeout publishing content providers");
6185    }
6186
6187    private final void processStartTimedOutLocked(ProcessRecord app) {
6188        final int pid = app.pid;
6189        boolean gone = false;
6190        synchronized (mPidsSelfLocked) {
6191            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6192            if (knownApp != null && knownApp.thread == null) {
6193                mPidsSelfLocked.remove(pid);
6194                gone = true;
6195            }
6196        }
6197
6198        if (gone) {
6199            Slog.w(TAG, "Process " + app + " failed to attach");
6200            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6201                    pid, app.uid, app.processName);
6202            removeProcessNameLocked(app.processName, app.uid);
6203            if (mHeavyWeightProcess == app) {
6204                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6205                        mHeavyWeightProcess.userId, 0));
6206                mHeavyWeightProcess = null;
6207            }
6208            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6209            if (app.isolated) {
6210                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6211            }
6212            // Take care of any launching providers waiting for this process.
6213            cleanupAppInLaunchingProvidersLocked(app, true);
6214            // Take care of any services that are waiting for the process.
6215            mServices.processStartTimedOutLocked(app);
6216            app.kill("start timeout", true);
6217            removeLruProcessLocked(app);
6218            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6219                Slog.w(TAG, "Unattached app died before backup, skipping");
6220                try {
6221                    IBackupManager bm = IBackupManager.Stub.asInterface(
6222                            ServiceManager.getService(Context.BACKUP_SERVICE));
6223                    bm.agentDisconnected(app.info.packageName);
6224                } catch (RemoteException e) {
6225                    // Can't happen; the backup manager is local
6226                }
6227            }
6228            if (isPendingBroadcastProcessLocked(pid)) {
6229                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6230                skipPendingBroadcastLocked(pid);
6231            }
6232        } else {
6233            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6234        }
6235    }
6236
6237    private final boolean attachApplicationLocked(IApplicationThread thread,
6238            int pid) {
6239
6240        // Find the application record that is being attached...  either via
6241        // the pid if we are running in multiple processes, or just pull the
6242        // next app record if we are emulating process with anonymous threads.
6243        ProcessRecord app;
6244        if (pid != MY_PID && pid >= 0) {
6245            synchronized (mPidsSelfLocked) {
6246                app = mPidsSelfLocked.get(pid);
6247            }
6248        } else {
6249            app = null;
6250        }
6251
6252        if (app == null) {
6253            Slog.w(TAG, "No pending application record for pid " + pid
6254                    + " (IApplicationThread " + thread + "); dropping process");
6255            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6256            if (pid > 0 && pid != MY_PID) {
6257                Process.killProcessQuiet(pid);
6258                //TODO: killProcessGroup(app.info.uid, pid);
6259            } else {
6260                try {
6261                    thread.scheduleExit();
6262                } catch (Exception e) {
6263                    // Ignore exceptions.
6264                }
6265            }
6266            return false;
6267        }
6268
6269        // If this application record is still attached to a previous
6270        // process, clean it up now.
6271        if (app.thread != null) {
6272            handleAppDiedLocked(app, true, true);
6273        }
6274
6275        // Tell the process all about itself.
6276
6277        if (DEBUG_ALL) Slog.v(
6278                TAG, "Binding process pid " + pid + " to record " + app);
6279
6280        final String processName = app.processName;
6281        try {
6282            AppDeathRecipient adr = new AppDeathRecipient(
6283                    app, pid, thread);
6284            thread.asBinder().linkToDeath(adr, 0);
6285            app.deathRecipient = adr;
6286        } catch (RemoteException e) {
6287            app.resetPackageList(mProcessStats);
6288            startProcessLocked(app, "link fail", processName);
6289            return false;
6290        }
6291
6292        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6293
6294        app.makeActive(thread, mProcessStats);
6295        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6296        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6297        app.forcingToForeground = null;
6298        updateProcessForegroundLocked(app, false, false);
6299        app.hasShownUi = false;
6300        app.debugging = false;
6301        app.cached = false;
6302        app.killedByAm = false;
6303        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6304
6305        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6306
6307        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6308        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6309
6310        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6311            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6312            msg.obj = app;
6313            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6314        }
6315
6316        if (!normalMode) {
6317            Slog.i(TAG, "Launching preboot mode app: " + app);
6318        }
6319
6320        if (DEBUG_ALL) Slog.v(
6321            TAG, "New app record " + app
6322            + " thread=" + thread.asBinder() + " pid=" + pid);
6323        try {
6324            int testMode = IApplicationThread.DEBUG_OFF;
6325            if (mDebugApp != null && mDebugApp.equals(processName)) {
6326                testMode = mWaitForDebugger
6327                    ? IApplicationThread.DEBUG_WAIT
6328                    : IApplicationThread.DEBUG_ON;
6329                app.debugging = true;
6330                if (mDebugTransient) {
6331                    mDebugApp = mOrigDebugApp;
6332                    mWaitForDebugger = mOrigWaitForDebugger;
6333                }
6334            }
6335            String profileFile = app.instrumentationProfileFile;
6336            ParcelFileDescriptor profileFd = null;
6337            int samplingInterval = 0;
6338            boolean profileAutoStop = false;
6339            if (mProfileApp != null && mProfileApp.equals(processName)) {
6340                mProfileProc = app;
6341                profileFile = mProfileFile;
6342                profileFd = mProfileFd;
6343                samplingInterval = mSamplingInterval;
6344                profileAutoStop = mAutoStopProfiler;
6345            }
6346            boolean enableTrackAllocation = false;
6347            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6348                enableTrackAllocation = true;
6349                mTrackAllocationApp = null;
6350            }
6351
6352            // If the app is being launched for restore or full backup, set it up specially
6353            boolean isRestrictedBackupMode = false;
6354            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6355                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6356                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6357                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6358                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6359            }
6360
6361            notifyPackageUse(app.instrumentationInfo != null
6362                    ? app.instrumentationInfo.packageName
6363                    : app.info.packageName);
6364            if (app.instrumentationClass != null) {
6365                notifyPackageUse(app.instrumentationClass.getPackageName());
6366            }
6367            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6368                    + processName + " with config " + mConfiguration);
6369            ApplicationInfo appInfo = app.instrumentationInfo != null
6370                    ? app.instrumentationInfo : app.info;
6371            app.compat = compatibilityInfoForPackageLocked(appInfo);
6372            if (profileFd != null) {
6373                profileFd = profileFd.dup();
6374            }
6375            ProfilerInfo profilerInfo = profileFile == null ? null
6376                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6377            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6378                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6379                    app.instrumentationUiAutomationConnection, testMode,
6380                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6381                    isRestrictedBackupMode || !normalMode, app.persistent,
6382                    new Configuration(mConfiguration), app.compat,
6383                    getCommonServicesLocked(app.isolated),
6384                    mCoreSettingsObserver.getCoreSettingsLocked());
6385            updateLruProcessLocked(app, false, null);
6386            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6387        } catch (Exception e) {
6388            // todo: Yikes!  What should we do?  For now we will try to
6389            // start another process, but that could easily get us in
6390            // an infinite loop of restarting processes...
6391            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6392
6393            app.resetPackageList(mProcessStats);
6394            app.unlinkDeathRecipient();
6395            startProcessLocked(app, "bind fail", processName);
6396            return false;
6397        }
6398
6399        // Remove this record from the list of starting applications.
6400        mPersistentStartingProcesses.remove(app);
6401        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6402                "Attach application locked removing on hold: " + app);
6403        mProcessesOnHold.remove(app);
6404
6405        boolean badApp = false;
6406        boolean didSomething = false;
6407
6408        // See if the top visible activity is waiting to run in this process...
6409        if (normalMode) {
6410            try {
6411                if (mStackSupervisor.attachApplicationLocked(app)) {
6412                    didSomething = true;
6413                }
6414            } catch (Exception e) {
6415                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6416                badApp = true;
6417            }
6418        }
6419
6420        // Find any services that should be running in this process...
6421        if (!badApp) {
6422            try {
6423                didSomething |= mServices.attachApplicationLocked(app, processName);
6424            } catch (Exception e) {
6425                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6426                badApp = true;
6427            }
6428        }
6429
6430        // Check if a next-broadcast receiver is in this process...
6431        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6432            try {
6433                didSomething |= sendPendingBroadcastsLocked(app);
6434            } catch (Exception e) {
6435                // If the app died trying to launch the receiver we declare it 'bad'
6436                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6437                badApp = true;
6438            }
6439        }
6440
6441        // Check whether the next backup agent is in this process...
6442        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6443            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6444                    "New app is backup target, launching agent for " + app);
6445            notifyPackageUse(mBackupTarget.appInfo.packageName);
6446            try {
6447                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6448                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6449                        mBackupTarget.backupMode);
6450            } catch (Exception e) {
6451                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6452                badApp = true;
6453            }
6454        }
6455
6456        if (badApp) {
6457            app.kill("error during init", true);
6458            handleAppDiedLocked(app, false, true);
6459            return false;
6460        }
6461
6462        if (!didSomething) {
6463            updateOomAdjLocked();
6464        }
6465
6466        return true;
6467    }
6468
6469    @Override
6470    public final void attachApplication(IApplicationThread thread) {
6471        synchronized (this) {
6472            int callingPid = Binder.getCallingPid();
6473            final long origId = Binder.clearCallingIdentity();
6474            attachApplicationLocked(thread, callingPid);
6475            Binder.restoreCallingIdentity(origId);
6476        }
6477    }
6478
6479    @Override
6480    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6481        final long origId = Binder.clearCallingIdentity();
6482        synchronized (this) {
6483            ActivityStack stack = ActivityRecord.getStackLocked(token);
6484            if (stack != null) {
6485                ActivityRecord r =
6486                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6487                if (stopProfiling) {
6488                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6489                        try {
6490                            mProfileFd.close();
6491                        } catch (IOException e) {
6492                        }
6493                        clearProfilerLocked();
6494                    }
6495                }
6496            }
6497        }
6498        Binder.restoreCallingIdentity(origId);
6499    }
6500
6501    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6502        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6503                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6504    }
6505
6506    void enableScreenAfterBoot() {
6507        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6508                SystemClock.uptimeMillis());
6509        mWindowManager.enableScreenAfterBoot();
6510
6511        synchronized (this) {
6512            updateEventDispatchingLocked();
6513        }
6514    }
6515
6516    @Override
6517    public void showBootMessage(final CharSequence msg, final boolean always) {
6518        if (Binder.getCallingUid() != Process.myUid()) {
6519            // These days only the core system can call this, so apps can't get in
6520            // the way of what we show about running them.
6521        }
6522        mWindowManager.showBootMessage(msg, always);
6523    }
6524
6525    @Override
6526    public void keyguardWaitingForActivityDrawn() {
6527        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6528        final long token = Binder.clearCallingIdentity();
6529        try {
6530            synchronized (this) {
6531                if (DEBUG_LOCKSCREEN) logLockScreen("");
6532                mWindowManager.keyguardWaitingForActivityDrawn();
6533                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6534                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6535                    updateSleepIfNeededLocked();
6536                }
6537            }
6538        } finally {
6539            Binder.restoreCallingIdentity(token);
6540        }
6541    }
6542
6543    @Override
6544    public void keyguardGoingAway(int flags) {
6545        enforceNotIsolatedCaller("keyguardGoingAway");
6546        final long token = Binder.clearCallingIdentity();
6547        try {
6548            synchronized (this) {
6549                if (DEBUG_LOCKSCREEN) logLockScreen("");
6550                mWindowManager.keyguardGoingAway(flags);
6551                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6552                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6553                    updateSleepIfNeededLocked();
6554
6555                    // Some stack visibility might change (e.g. docked stack)
6556                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6557                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6558                }
6559            }
6560        } finally {
6561            Binder.restoreCallingIdentity(token);
6562        }
6563    }
6564
6565    final void finishBooting() {
6566        synchronized (this) {
6567            if (!mBootAnimationComplete) {
6568                mCallFinishBooting = true;
6569                return;
6570            }
6571            mCallFinishBooting = false;
6572        }
6573
6574        ArraySet<String> completedIsas = new ArraySet<String>();
6575        for (String abi : Build.SUPPORTED_ABIS) {
6576            Process.establishZygoteConnectionForAbi(abi);
6577            final String instructionSet = VMRuntime.getInstructionSet(abi);
6578            if (!completedIsas.contains(instructionSet)) {
6579                try {
6580                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6581                } catch (InstallerException e) {
6582                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6583                }
6584                completedIsas.add(instructionSet);
6585            }
6586        }
6587
6588        IntentFilter pkgFilter = new IntentFilter();
6589        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6590        pkgFilter.addDataScheme("package");
6591        mContext.registerReceiver(new BroadcastReceiver() {
6592            @Override
6593            public void onReceive(Context context, Intent intent) {
6594                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6595                if (pkgs != null) {
6596                    for (String pkg : pkgs) {
6597                        synchronized (ActivityManagerService.this) {
6598                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6599                                    0, "query restart")) {
6600                                setResultCode(Activity.RESULT_OK);
6601                                return;
6602                            }
6603                        }
6604                    }
6605                }
6606            }
6607        }, pkgFilter);
6608
6609        IntentFilter dumpheapFilter = new IntentFilter();
6610        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6611        mContext.registerReceiver(new BroadcastReceiver() {
6612            @Override
6613            public void onReceive(Context context, Intent intent) {
6614                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6615                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6616                } else {
6617                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6618                }
6619            }
6620        }, dumpheapFilter);
6621
6622        // Let system services know.
6623        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6624
6625        synchronized (this) {
6626            // Ensure that any processes we had put on hold are now started
6627            // up.
6628            final int NP = mProcessesOnHold.size();
6629            if (NP > 0) {
6630                ArrayList<ProcessRecord> procs =
6631                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6632                for (int ip=0; ip<NP; ip++) {
6633                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6634                            + procs.get(ip));
6635                    startProcessLocked(procs.get(ip), "on-hold", null);
6636                }
6637            }
6638
6639            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6640                // Start looking for apps that are abusing wake locks.
6641                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6642                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6643                // Tell anyone interested that we are done booting!
6644                SystemProperties.set("sys.boot_completed", "1");
6645
6646                // And trigger dev.bootcomplete if we are not showing encryption progress
6647                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6648                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6649                    SystemProperties.set("dev.bootcomplete", "1");
6650                }
6651                mUserController.sendBootCompletedLocked(
6652                        new IIntentReceiver.Stub() {
6653                            @Override
6654                            public void performReceive(Intent intent, int resultCode,
6655                                    String data, Bundle extras, boolean ordered,
6656                                    boolean sticky, int sendingUser) {
6657                                synchronized (ActivityManagerService.this) {
6658                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6659                                            true, false);
6660                                }
6661                            }
6662                        });
6663                scheduleStartProfilesLocked();
6664            }
6665        }
6666    }
6667
6668    @Override
6669    public void bootAnimationComplete() {
6670        final boolean callFinishBooting;
6671        synchronized (this) {
6672            callFinishBooting = mCallFinishBooting;
6673            mBootAnimationComplete = true;
6674        }
6675        if (callFinishBooting) {
6676            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6677            finishBooting();
6678            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6679        }
6680    }
6681
6682    final void ensureBootCompleted() {
6683        boolean booting;
6684        boolean enableScreen;
6685        synchronized (this) {
6686            booting = mBooting;
6687            mBooting = false;
6688            enableScreen = !mBooted;
6689            mBooted = true;
6690        }
6691
6692        if (booting) {
6693            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6694            finishBooting();
6695            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6696        }
6697
6698        if (enableScreen) {
6699            enableScreenAfterBoot();
6700        }
6701    }
6702
6703    @Override
6704    public final void activityResumed(IBinder token) {
6705        final long origId = Binder.clearCallingIdentity();
6706        synchronized(this) {
6707            ActivityStack stack = ActivityRecord.getStackLocked(token);
6708            if (stack != null) {
6709                stack.activityResumedLocked(token);
6710            }
6711        }
6712        Binder.restoreCallingIdentity(origId);
6713    }
6714
6715    @Override
6716    public final void activityPaused(IBinder token) {
6717        final long origId = Binder.clearCallingIdentity();
6718        synchronized(this) {
6719            ActivityStack stack = ActivityRecord.getStackLocked(token);
6720            if (stack != null) {
6721                stack.activityPausedLocked(token, false);
6722            }
6723        }
6724        Binder.restoreCallingIdentity(origId);
6725    }
6726
6727    @Override
6728    public final void activityStopped(IBinder token, Bundle icicle,
6729            PersistableBundle persistentState, CharSequence description) {
6730        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6731
6732        // Refuse possible leaked file descriptors
6733        if (icicle != null && icicle.hasFileDescriptors()) {
6734            throw new IllegalArgumentException("File descriptors passed in Bundle");
6735        }
6736
6737        final long origId = Binder.clearCallingIdentity();
6738
6739        synchronized (this) {
6740            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6741            if (r != null) {
6742                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6743            }
6744        }
6745
6746        trimApplications();
6747
6748        Binder.restoreCallingIdentity(origId);
6749    }
6750
6751    @Override
6752    public final void activityDestroyed(IBinder token) {
6753        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6754        synchronized (this) {
6755            ActivityStack stack = ActivityRecord.getStackLocked(token);
6756            if (stack != null) {
6757                stack.activityDestroyedLocked(token, "activityDestroyed");
6758            }
6759        }
6760    }
6761
6762    @Override
6763    public final void activityRelaunched(IBinder token) {
6764        final long origId = Binder.clearCallingIdentity();
6765        synchronized (this) {
6766            mStackSupervisor.activityRelaunchedLocked(token);
6767        }
6768        Binder.restoreCallingIdentity(origId);
6769    }
6770
6771    @Override
6772    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6773            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6774        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6775                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6776        synchronized (this) {
6777            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6778            if (record == null) {
6779                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6780                        + "found for: " + token);
6781            }
6782            record.setSizeConfigurations(horizontalSizeConfiguration,
6783                    verticalSizeConfigurations, smallestSizeConfigurations);
6784        }
6785    }
6786
6787    @Override
6788    public final void backgroundResourcesReleased(IBinder token) {
6789        final long origId = Binder.clearCallingIdentity();
6790        try {
6791            synchronized (this) {
6792                ActivityStack stack = ActivityRecord.getStackLocked(token);
6793                if (stack != null) {
6794                    stack.backgroundResourcesReleased();
6795                }
6796            }
6797        } finally {
6798            Binder.restoreCallingIdentity(origId);
6799        }
6800    }
6801
6802    @Override
6803    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6804        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6805    }
6806
6807    @Override
6808    public final void notifyEnterAnimationComplete(IBinder token) {
6809        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6810    }
6811
6812    @Override
6813    public String getCallingPackage(IBinder token) {
6814        synchronized (this) {
6815            ActivityRecord r = getCallingRecordLocked(token);
6816            return r != null ? r.info.packageName : null;
6817        }
6818    }
6819
6820    @Override
6821    public ComponentName getCallingActivity(IBinder token) {
6822        synchronized (this) {
6823            ActivityRecord r = getCallingRecordLocked(token);
6824            return r != null ? r.intent.getComponent() : null;
6825        }
6826    }
6827
6828    private ActivityRecord getCallingRecordLocked(IBinder token) {
6829        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830        if (r == null) {
6831            return null;
6832        }
6833        return r.resultTo;
6834    }
6835
6836    @Override
6837    public ComponentName getActivityClassForToken(IBinder token) {
6838        synchronized(this) {
6839            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6840            if (r == null) {
6841                return null;
6842            }
6843            return r.intent.getComponent();
6844        }
6845    }
6846
6847    @Override
6848    public String getPackageForToken(IBinder token) {
6849        synchronized(this) {
6850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6851            if (r == null) {
6852                return null;
6853            }
6854            return r.packageName;
6855        }
6856    }
6857
6858    @Override
6859    public boolean isRootVoiceInteraction(IBinder token) {
6860        synchronized(this) {
6861            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6862            if (r == null) {
6863                return false;
6864            }
6865            return r.rootVoiceInteraction;
6866        }
6867    }
6868
6869    @Override
6870    public IIntentSender getIntentSender(int type,
6871            String packageName, IBinder token, String resultWho,
6872            int requestCode, Intent[] intents, String[] resolvedTypes,
6873            int flags, Bundle bOptions, int userId) {
6874        enforceNotIsolatedCaller("getIntentSender");
6875        // Refuse possible leaked file descriptors
6876        if (intents != null) {
6877            if (intents.length < 1) {
6878                throw new IllegalArgumentException("Intents array length must be >= 1");
6879            }
6880            for (int i=0; i<intents.length; i++) {
6881                Intent intent = intents[i];
6882                if (intent != null) {
6883                    if (intent.hasFileDescriptors()) {
6884                        throw new IllegalArgumentException("File descriptors passed in Intent");
6885                    }
6886                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6887                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6888                        throw new IllegalArgumentException(
6889                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6890                    }
6891                    intents[i] = new Intent(intent);
6892                }
6893            }
6894            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6895                throw new IllegalArgumentException(
6896                        "Intent array length does not match resolvedTypes length");
6897            }
6898        }
6899        if (bOptions != null) {
6900            if (bOptions.hasFileDescriptors()) {
6901                throw new IllegalArgumentException("File descriptors passed in options");
6902            }
6903        }
6904
6905        synchronized(this) {
6906            int callingUid = Binder.getCallingUid();
6907            int origUserId = userId;
6908            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6909                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6910                    ALLOW_NON_FULL, "getIntentSender", null);
6911            if (origUserId == UserHandle.USER_CURRENT) {
6912                // We don't want to evaluate this until the pending intent is
6913                // actually executed.  However, we do want to always do the
6914                // security checking for it above.
6915                userId = UserHandle.USER_CURRENT;
6916            }
6917            try {
6918                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6919                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6920                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6921                    if (!UserHandle.isSameApp(callingUid, uid)) {
6922                        String msg = "Permission Denial: getIntentSender() from pid="
6923                            + Binder.getCallingPid()
6924                            + ", uid=" + Binder.getCallingUid()
6925                            + ", (need uid=" + uid + ")"
6926                            + " is not allowed to send as package " + packageName;
6927                        Slog.w(TAG, msg);
6928                        throw new SecurityException(msg);
6929                    }
6930                }
6931
6932                return getIntentSenderLocked(type, packageName, callingUid, userId,
6933                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6934
6935            } catch (RemoteException e) {
6936                throw new SecurityException(e);
6937            }
6938        }
6939    }
6940
6941    IIntentSender getIntentSenderLocked(int type, String packageName,
6942            int callingUid, int userId, IBinder token, String resultWho,
6943            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6944            Bundle bOptions) {
6945        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6946        ActivityRecord activity = null;
6947        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6948            activity = ActivityRecord.isInStackLocked(token);
6949            if (activity == null) {
6950                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6951                return null;
6952            }
6953            if (activity.finishing) {
6954                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6955                return null;
6956            }
6957        }
6958
6959        // We're going to be splicing together extras before sending, so we're
6960        // okay poking into any contained extras.
6961        if (intents != null) {
6962            for (int i = 0; i < intents.length; i++) {
6963                intents[i].setDefusable(true);
6964            }
6965        }
6966        Bundle.setDefusable(bOptions, true);
6967
6968        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6969        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6970        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6971        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6972                |PendingIntent.FLAG_UPDATE_CURRENT);
6973
6974        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6975                type, packageName, activity, resultWho,
6976                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6977        WeakReference<PendingIntentRecord> ref;
6978        ref = mIntentSenderRecords.get(key);
6979        PendingIntentRecord rec = ref != null ? ref.get() : null;
6980        if (rec != null) {
6981            if (!cancelCurrent) {
6982                if (updateCurrent) {
6983                    if (rec.key.requestIntent != null) {
6984                        rec.key.requestIntent.replaceExtras(intents != null ?
6985                                intents[intents.length - 1] : null);
6986                    }
6987                    if (intents != null) {
6988                        intents[intents.length-1] = rec.key.requestIntent;
6989                        rec.key.allIntents = intents;
6990                        rec.key.allResolvedTypes = resolvedTypes;
6991                    } else {
6992                        rec.key.allIntents = null;
6993                        rec.key.allResolvedTypes = null;
6994                    }
6995                }
6996                return rec;
6997            }
6998            rec.canceled = true;
6999            mIntentSenderRecords.remove(key);
7000        }
7001        if (noCreate) {
7002            return rec;
7003        }
7004        rec = new PendingIntentRecord(this, key, callingUid);
7005        mIntentSenderRecords.put(key, rec.ref);
7006        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7007            if (activity.pendingResults == null) {
7008                activity.pendingResults
7009                        = new HashSet<WeakReference<PendingIntentRecord>>();
7010            }
7011            activity.pendingResults.add(rec.ref);
7012        }
7013        return rec;
7014    }
7015
7016    @Override
7017    public void cancelIntentSender(IIntentSender sender) {
7018        if (!(sender instanceof PendingIntentRecord)) {
7019            return;
7020        }
7021        synchronized(this) {
7022            PendingIntentRecord rec = (PendingIntentRecord)sender;
7023            try {
7024                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7025                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7026                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7027                    String msg = "Permission Denial: cancelIntentSender() from pid="
7028                        + Binder.getCallingPid()
7029                        + ", uid=" + Binder.getCallingUid()
7030                        + " is not allowed to cancel packges "
7031                        + rec.key.packageName;
7032                    Slog.w(TAG, msg);
7033                    throw new SecurityException(msg);
7034                }
7035            } catch (RemoteException e) {
7036                throw new SecurityException(e);
7037            }
7038            cancelIntentSenderLocked(rec, true);
7039        }
7040    }
7041
7042    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7043        rec.canceled = true;
7044        mIntentSenderRecords.remove(rec.key);
7045        if (cleanActivity && rec.key.activity != null) {
7046            rec.key.activity.pendingResults.remove(rec.ref);
7047        }
7048    }
7049
7050    @Override
7051    public String getPackageForIntentSender(IIntentSender pendingResult) {
7052        if (!(pendingResult instanceof PendingIntentRecord)) {
7053            return null;
7054        }
7055        try {
7056            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7057            return res.key.packageName;
7058        } catch (ClassCastException e) {
7059        }
7060        return null;
7061    }
7062
7063    @Override
7064    public int getUidForIntentSender(IIntentSender sender) {
7065        if (sender instanceof PendingIntentRecord) {
7066            try {
7067                PendingIntentRecord res = (PendingIntentRecord)sender;
7068                return res.uid;
7069            } catch (ClassCastException e) {
7070            }
7071        }
7072        return -1;
7073    }
7074
7075    @Override
7076    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7077        if (!(pendingResult instanceof PendingIntentRecord)) {
7078            return false;
7079        }
7080        try {
7081            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7082            if (res.key.allIntents == null) {
7083                return false;
7084            }
7085            for (int i=0; i<res.key.allIntents.length; i++) {
7086                Intent intent = res.key.allIntents[i];
7087                if (intent.getPackage() != null && intent.getComponent() != null) {
7088                    return false;
7089                }
7090            }
7091            return true;
7092        } catch (ClassCastException e) {
7093        }
7094        return false;
7095    }
7096
7097    @Override
7098    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7099        if (!(pendingResult instanceof PendingIntentRecord)) {
7100            return false;
7101        }
7102        try {
7103            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7104            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7105                return true;
7106            }
7107            return false;
7108        } catch (ClassCastException e) {
7109        }
7110        return false;
7111    }
7112
7113    @Override
7114    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7115        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7116                "getIntentForIntentSender()");
7117        if (!(pendingResult instanceof PendingIntentRecord)) {
7118            return null;
7119        }
7120        try {
7121            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7122            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7123        } catch (ClassCastException e) {
7124        }
7125        return null;
7126    }
7127
7128    @Override
7129    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7130        if (!(pendingResult instanceof PendingIntentRecord)) {
7131            return null;
7132        }
7133        try {
7134            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7135            synchronized (this) {
7136                return getTagForIntentSenderLocked(res, prefix);
7137            }
7138        } catch (ClassCastException e) {
7139        }
7140        return null;
7141    }
7142
7143    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7144        final Intent intent = res.key.requestIntent;
7145        if (intent != null) {
7146            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7147                    || res.lastTagPrefix.equals(prefix))) {
7148                return res.lastTag;
7149            }
7150            res.lastTagPrefix = prefix;
7151            final StringBuilder sb = new StringBuilder(128);
7152            if (prefix != null) {
7153                sb.append(prefix);
7154            }
7155            if (intent.getAction() != null) {
7156                sb.append(intent.getAction());
7157            } else if (intent.getComponent() != null) {
7158                intent.getComponent().appendShortString(sb);
7159            } else {
7160                sb.append("?");
7161            }
7162            return res.lastTag = sb.toString();
7163        }
7164        return null;
7165    }
7166
7167    @Override
7168    public void setProcessLimit(int max) {
7169        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7170                "setProcessLimit()");
7171        synchronized (this) {
7172            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7173            mProcessLimitOverride = max;
7174        }
7175        trimApplications();
7176    }
7177
7178    @Override
7179    public int getProcessLimit() {
7180        synchronized (this) {
7181            return mProcessLimitOverride;
7182        }
7183    }
7184
7185    void foregroundTokenDied(ForegroundToken token) {
7186        synchronized (ActivityManagerService.this) {
7187            synchronized (mPidsSelfLocked) {
7188                ForegroundToken cur
7189                    = mForegroundProcesses.get(token.pid);
7190                if (cur != token) {
7191                    return;
7192                }
7193                mForegroundProcesses.remove(token.pid);
7194                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7195                if (pr == null) {
7196                    return;
7197                }
7198                pr.forcingToForeground = null;
7199                updateProcessForegroundLocked(pr, false, false);
7200            }
7201            updateOomAdjLocked();
7202        }
7203    }
7204
7205    @Override
7206    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7207        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7208                "setProcessForeground()");
7209        synchronized(this) {
7210            boolean changed = false;
7211
7212            synchronized (mPidsSelfLocked) {
7213                ProcessRecord pr = mPidsSelfLocked.get(pid);
7214                if (pr == null && isForeground) {
7215                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7216                    return;
7217                }
7218                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7219                if (oldToken != null) {
7220                    oldToken.token.unlinkToDeath(oldToken, 0);
7221                    mForegroundProcesses.remove(pid);
7222                    if (pr != null) {
7223                        pr.forcingToForeground = null;
7224                    }
7225                    changed = true;
7226                }
7227                if (isForeground && token != null) {
7228                    ForegroundToken newToken = new ForegroundToken() {
7229                        @Override
7230                        public void binderDied() {
7231                            foregroundTokenDied(this);
7232                        }
7233                    };
7234                    newToken.pid = pid;
7235                    newToken.token = token;
7236                    try {
7237                        token.linkToDeath(newToken, 0);
7238                        mForegroundProcesses.put(pid, newToken);
7239                        pr.forcingToForeground = token;
7240                        changed = true;
7241                    } catch (RemoteException e) {
7242                        // If the process died while doing this, we will later
7243                        // do the cleanup with the process death link.
7244                    }
7245                }
7246            }
7247
7248            if (changed) {
7249                updateOomAdjLocked();
7250            }
7251        }
7252    }
7253
7254    @Override
7255    public boolean isAppForeground(int uid) throws RemoteException {
7256        synchronized (this) {
7257            UidRecord uidRec = mActiveUids.get(uid);
7258            if (uidRec == null || uidRec.idle) {
7259                return false;
7260            }
7261            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7262        }
7263    }
7264
7265    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7266    // be guarded by permission checking.
7267    int getUidState(int uid) {
7268        synchronized (this) {
7269            UidRecord uidRec = mActiveUids.get(uid);
7270            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7271        }
7272    }
7273
7274    @Override
7275    public boolean isInMultiWindowMode(IBinder token) {
7276        final long origId = Binder.clearCallingIdentity();
7277        try {
7278            synchronized(this) {
7279                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7280                if (r == null) {
7281                    return false;
7282                }
7283                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7284                return !r.task.mFullscreen;
7285            }
7286        } finally {
7287            Binder.restoreCallingIdentity(origId);
7288        }
7289    }
7290
7291    @Override
7292    public boolean isInPictureInPictureMode(IBinder token) {
7293        final long origId = Binder.clearCallingIdentity();
7294        try {
7295            synchronized(this) {
7296                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7297                if (stack == null) {
7298                    return false;
7299                }
7300                return stack.mStackId == PINNED_STACK_ID;
7301            }
7302        } finally {
7303            Binder.restoreCallingIdentity(origId);
7304        }
7305    }
7306
7307    @Override
7308    public void enterPictureInPictureMode(IBinder token) {
7309        final long origId = Binder.clearCallingIdentity();
7310        try {
7311            synchronized(this) {
7312                if (!mSupportsPictureInPicture) {
7313                    throw new IllegalStateException("enterPictureInPictureMode: "
7314                            + "Device doesn't support picture-in-picture mode.");
7315                }
7316
7317                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7318
7319                if (r == null) {
7320                    throw new IllegalStateException("enterPictureInPictureMode: "
7321                            + "Can't find activity for token=" + token);
7322                }
7323
7324                if (!r.supportsPictureInPicture()) {
7325                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7326                            + "Picture-In-Picture not supported for r=" + r);
7327                }
7328
7329                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7330                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7331                        ? mDefaultPinnedStackBounds : null;
7332
7333                mStackSupervisor.moveActivityToPinnedStackLocked(
7334                        r, "enterPictureInPictureMode", bounds);
7335            }
7336        } finally {
7337            Binder.restoreCallingIdentity(origId);
7338        }
7339    }
7340
7341    // =========================================================
7342    // PROCESS INFO
7343    // =========================================================
7344
7345    static class ProcessInfoService extends IProcessInfoService.Stub {
7346        final ActivityManagerService mActivityManagerService;
7347        ProcessInfoService(ActivityManagerService activityManagerService) {
7348            mActivityManagerService = activityManagerService;
7349        }
7350
7351        @Override
7352        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7353            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7354                    /*in*/ pids, /*out*/ states, null);
7355        }
7356
7357        @Override
7358        public void getProcessStatesAndOomScoresFromPids(
7359                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7360            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7361                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7362        }
7363    }
7364
7365    /**
7366     * For each PID in the given input array, write the current process state
7367     * for that process into the states array, or -1 to indicate that no
7368     * process with the given PID exists. If scores array is provided, write
7369     * the oom score for the process into the scores array, with INVALID_ADJ
7370     * indicating the PID doesn't exist.
7371     */
7372    public void getProcessStatesAndOomScoresForPIDs(
7373            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7374        if (scores != null) {
7375            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7376                    "getProcessStatesAndOomScoresForPIDs()");
7377        }
7378
7379        if (pids == null) {
7380            throw new NullPointerException("pids");
7381        } else if (states == null) {
7382            throw new NullPointerException("states");
7383        } else if (pids.length != states.length) {
7384            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7385        } else if (scores != null && pids.length != scores.length) {
7386            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7387        }
7388
7389        synchronized (mPidsSelfLocked) {
7390            for (int i = 0; i < pids.length; i++) {
7391                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7392                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7393                        pr.curProcState;
7394                if (scores != null) {
7395                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7396                }
7397            }
7398        }
7399    }
7400
7401    // =========================================================
7402    // PERMISSIONS
7403    // =========================================================
7404
7405    static class PermissionController extends IPermissionController.Stub {
7406        ActivityManagerService mActivityManagerService;
7407        PermissionController(ActivityManagerService activityManagerService) {
7408            mActivityManagerService = activityManagerService;
7409        }
7410
7411        @Override
7412        public boolean checkPermission(String permission, int pid, int uid) {
7413            return mActivityManagerService.checkPermission(permission, pid,
7414                    uid) == PackageManager.PERMISSION_GRANTED;
7415        }
7416
7417        @Override
7418        public String[] getPackagesForUid(int uid) {
7419            return mActivityManagerService.mContext.getPackageManager()
7420                    .getPackagesForUid(uid);
7421        }
7422
7423        @Override
7424        public boolean isRuntimePermission(String permission) {
7425            try {
7426                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7427                        .getPermissionInfo(permission, 0);
7428                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7429            } catch (NameNotFoundException nnfe) {
7430                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7431            }
7432            return false;
7433        }
7434    }
7435
7436    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7437        @Override
7438        public int checkComponentPermission(String permission, int pid, int uid,
7439                int owningUid, boolean exported) {
7440            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7441                    owningUid, exported);
7442        }
7443
7444        @Override
7445        public Object getAMSLock() {
7446            return ActivityManagerService.this;
7447        }
7448    }
7449
7450    /**
7451     * This can be called with or without the global lock held.
7452     */
7453    int checkComponentPermission(String permission, int pid, int uid,
7454            int owningUid, boolean exported) {
7455        if (pid == MY_PID) {
7456            return PackageManager.PERMISSION_GRANTED;
7457        }
7458        return ActivityManager.checkComponentPermission(permission, uid,
7459                owningUid, exported);
7460    }
7461
7462    /**
7463     * As the only public entry point for permissions checking, this method
7464     * can enforce the semantic that requesting a check on a null global
7465     * permission is automatically denied.  (Internally a null permission
7466     * string is used when calling {@link #checkComponentPermission} in cases
7467     * when only uid-based security is needed.)
7468     *
7469     * This can be called with or without the global lock held.
7470     */
7471    @Override
7472    public int checkPermission(String permission, int pid, int uid) {
7473        if (permission == null) {
7474            return PackageManager.PERMISSION_DENIED;
7475        }
7476        return checkComponentPermission(permission, pid, uid, -1, true);
7477    }
7478
7479    @Override
7480    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7481        if (permission == null) {
7482            return PackageManager.PERMISSION_DENIED;
7483        }
7484
7485        // We might be performing an operation on behalf of an indirect binder
7486        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7487        // client identity accordingly before proceeding.
7488        Identity tlsIdentity = sCallerIdentity.get();
7489        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7490            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7491                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7492            uid = tlsIdentity.uid;
7493            pid = tlsIdentity.pid;
7494        }
7495
7496        return checkComponentPermission(permission, pid, uid, -1, true);
7497    }
7498
7499    /**
7500     * Binder IPC calls go through the public entry point.
7501     * This can be called with or without the global lock held.
7502     */
7503    int checkCallingPermission(String permission) {
7504        return checkPermission(permission,
7505                Binder.getCallingPid(),
7506                UserHandle.getAppId(Binder.getCallingUid()));
7507    }
7508
7509    /**
7510     * This can be called with or without the global lock held.
7511     */
7512    void enforceCallingPermission(String permission, String func) {
7513        if (checkCallingPermission(permission)
7514                == PackageManager.PERMISSION_GRANTED) {
7515            return;
7516        }
7517
7518        String msg = "Permission Denial: " + func + " from pid="
7519                + Binder.getCallingPid()
7520                + ", uid=" + Binder.getCallingUid()
7521                + " requires " + permission;
7522        Slog.w(TAG, msg);
7523        throw new SecurityException(msg);
7524    }
7525
7526    /**
7527     * Determine if UID is holding permissions required to access {@link Uri} in
7528     * the given {@link ProviderInfo}. Final permission checking is always done
7529     * in {@link ContentProvider}.
7530     */
7531    private final boolean checkHoldingPermissionsLocked(
7532            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7533        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7534                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7535        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7536            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7537                    != PERMISSION_GRANTED) {
7538                return false;
7539            }
7540        }
7541        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7542    }
7543
7544    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7545            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7546        if (pi.applicationInfo.uid == uid) {
7547            return true;
7548        } else if (!pi.exported) {
7549            return false;
7550        }
7551
7552        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7553        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7554        try {
7555            // check if target holds top-level <provider> permissions
7556            if (!readMet && pi.readPermission != null && considerUidPermissions
7557                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7558                readMet = true;
7559            }
7560            if (!writeMet && pi.writePermission != null && considerUidPermissions
7561                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7562                writeMet = true;
7563            }
7564
7565            // track if unprotected read/write is allowed; any denied
7566            // <path-permission> below removes this ability
7567            boolean allowDefaultRead = pi.readPermission == null;
7568            boolean allowDefaultWrite = pi.writePermission == null;
7569
7570            // check if target holds any <path-permission> that match uri
7571            final PathPermission[] pps = pi.pathPermissions;
7572            if (pps != null) {
7573                final String path = grantUri.uri.getPath();
7574                int i = pps.length;
7575                while (i > 0 && (!readMet || !writeMet)) {
7576                    i--;
7577                    PathPermission pp = pps[i];
7578                    if (pp.match(path)) {
7579                        if (!readMet) {
7580                            final String pprperm = pp.getReadPermission();
7581                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7582                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7583                                    + ": match=" + pp.match(path)
7584                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7585                            if (pprperm != null) {
7586                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7587                                        == PERMISSION_GRANTED) {
7588                                    readMet = true;
7589                                } else {
7590                                    allowDefaultRead = false;
7591                                }
7592                            }
7593                        }
7594                        if (!writeMet) {
7595                            final String ppwperm = pp.getWritePermission();
7596                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7597                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7598                                    + ": match=" + pp.match(path)
7599                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7600                            if (ppwperm != null) {
7601                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7602                                        == PERMISSION_GRANTED) {
7603                                    writeMet = true;
7604                                } else {
7605                                    allowDefaultWrite = false;
7606                                }
7607                            }
7608                        }
7609                    }
7610                }
7611            }
7612
7613            // grant unprotected <provider> read/write, if not blocked by
7614            // <path-permission> above
7615            if (allowDefaultRead) readMet = true;
7616            if (allowDefaultWrite) writeMet = true;
7617
7618        } catch (RemoteException e) {
7619            return false;
7620        }
7621
7622        return readMet && writeMet;
7623    }
7624
7625    public int getAppStartMode(int uid, String packageName) {
7626        synchronized (this) {
7627            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7628        }
7629    }
7630
7631    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7632            boolean allowWhenForeground) {
7633        UidRecord uidRec = mActiveUids.get(uid);
7634        if (!mLenientBackgroundCheck) {
7635            if (!allowWhenForeground || uidRec == null
7636                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7637                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7638                        packageName) != AppOpsManager.MODE_ALLOWED) {
7639                    return ActivityManager.APP_START_MODE_DELAYED;
7640                }
7641            }
7642
7643        } else if (uidRec == null || uidRec.idle) {
7644            if (callingPid >= 0) {
7645                ProcessRecord proc;
7646                synchronized (mPidsSelfLocked) {
7647                    proc = mPidsSelfLocked.get(callingPid);
7648                }
7649                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7650                    // Whoever is instigating this is in the foreground, so we will allow it
7651                    // to go through.
7652                    return ActivityManager.APP_START_MODE_NORMAL;
7653                }
7654            }
7655            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7656                    != AppOpsManager.MODE_ALLOWED) {
7657                return ActivityManager.APP_START_MODE_DELAYED;
7658            }
7659        }
7660        return ActivityManager.APP_START_MODE_NORMAL;
7661    }
7662
7663    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7664        ProviderInfo pi = null;
7665        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7666        if (cpr != null) {
7667            pi = cpr.info;
7668        } else {
7669            try {
7670                pi = AppGlobals.getPackageManager().resolveContentProvider(
7671                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7672            } catch (RemoteException ex) {
7673            }
7674        }
7675        return pi;
7676    }
7677
7678    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7679        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7680        if (targetUris != null) {
7681            return targetUris.get(grantUri);
7682        }
7683        return null;
7684    }
7685
7686    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7687            String targetPkg, int targetUid, GrantUri grantUri) {
7688        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7689        if (targetUris == null) {
7690            targetUris = Maps.newArrayMap();
7691            mGrantedUriPermissions.put(targetUid, targetUris);
7692        }
7693
7694        UriPermission perm = targetUris.get(grantUri);
7695        if (perm == null) {
7696            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7697            targetUris.put(grantUri, perm);
7698        }
7699
7700        return perm;
7701    }
7702
7703    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7704            final int modeFlags) {
7705        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7706        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7707                : UriPermission.STRENGTH_OWNED;
7708
7709        // Root gets to do everything.
7710        if (uid == 0) {
7711            return true;
7712        }
7713
7714        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7715        if (perms == null) return false;
7716
7717        // First look for exact match
7718        final UriPermission exactPerm = perms.get(grantUri);
7719        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7720            return true;
7721        }
7722
7723        // No exact match, look for prefixes
7724        final int N = perms.size();
7725        for (int i = 0; i < N; i++) {
7726            final UriPermission perm = perms.valueAt(i);
7727            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7728                    && perm.getStrength(modeFlags) >= minStrength) {
7729                return true;
7730            }
7731        }
7732
7733        return false;
7734    }
7735
7736    /**
7737     * @param uri This uri must NOT contain an embedded userId.
7738     * @param userId The userId in which the uri is to be resolved.
7739     */
7740    @Override
7741    public int checkUriPermission(Uri uri, int pid, int uid,
7742            final int modeFlags, int userId, IBinder callerToken) {
7743        enforceNotIsolatedCaller("checkUriPermission");
7744
7745        // Another redirected-binder-call permissions check as in
7746        // {@link checkPermissionWithToken}.
7747        Identity tlsIdentity = sCallerIdentity.get();
7748        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7749            uid = tlsIdentity.uid;
7750            pid = tlsIdentity.pid;
7751        }
7752
7753        // Our own process gets to do everything.
7754        if (pid == MY_PID) {
7755            return PackageManager.PERMISSION_GRANTED;
7756        }
7757        synchronized (this) {
7758            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7759                    ? PackageManager.PERMISSION_GRANTED
7760                    : PackageManager.PERMISSION_DENIED;
7761        }
7762    }
7763
7764    /**
7765     * Check if the targetPkg can be granted permission to access uri by
7766     * the callingUid using the given modeFlags.  Throws a security exception
7767     * if callingUid is not allowed to do this.  Returns the uid of the target
7768     * if the URI permission grant should be performed; returns -1 if it is not
7769     * needed (for example targetPkg already has permission to access the URI).
7770     * If you already know the uid of the target, you can supply it in
7771     * lastTargetUid else set that to -1.
7772     */
7773    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7774            final int modeFlags, int lastTargetUid) {
7775        if (!Intent.isAccessUriMode(modeFlags)) {
7776            return -1;
7777        }
7778
7779        if (targetPkg != null) {
7780            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7781                    "Checking grant " + targetPkg + " permission to " + grantUri);
7782        }
7783
7784        final IPackageManager pm = AppGlobals.getPackageManager();
7785
7786        // If this is not a content: uri, we can't do anything with it.
7787        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7788            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7789                    "Can't grant URI permission for non-content URI: " + grantUri);
7790            return -1;
7791        }
7792
7793        final String authority = grantUri.uri.getAuthority();
7794        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7795        if (pi == null) {
7796            Slog.w(TAG, "No content provider found for permission check: " +
7797                    grantUri.uri.toSafeString());
7798            return -1;
7799        }
7800
7801        int targetUid = lastTargetUid;
7802        if (targetUid < 0 && targetPkg != null) {
7803            try {
7804                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7805                        UserHandle.getUserId(callingUid));
7806                if (targetUid < 0) {
7807                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7808                            "Can't grant URI permission no uid for: " + targetPkg);
7809                    return -1;
7810                }
7811            } catch (RemoteException ex) {
7812                return -1;
7813            }
7814        }
7815
7816        if (targetUid >= 0) {
7817            // First...  does the target actually need this permission?
7818            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7819                // No need to grant the target this permission.
7820                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821                        "Target " + targetPkg + " already has full permission to " + grantUri);
7822                return -1;
7823            }
7824        } else {
7825            // First...  there is no target package, so can anyone access it?
7826            boolean allowed = pi.exported;
7827            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7828                if (pi.readPermission != null) {
7829                    allowed = false;
7830                }
7831            }
7832            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7833                if (pi.writePermission != null) {
7834                    allowed = false;
7835                }
7836            }
7837            if (allowed) {
7838                return -1;
7839            }
7840        }
7841
7842        /* There is a special cross user grant if:
7843         * - The target is on another user.
7844         * - Apps on the current user can access the uri without any uid permissions.
7845         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7846         * grant uri permissions.
7847         */
7848        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7849                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7850                modeFlags, false /*without considering the uid permissions*/);
7851
7852        // Second...  is the provider allowing granting of URI permissions?
7853        if (!specialCrossUserGrant) {
7854            if (!pi.grantUriPermissions) {
7855                throw new SecurityException("Provider " + pi.packageName
7856                        + "/" + pi.name
7857                        + " does not allow granting of Uri permissions (uri "
7858                        + grantUri + ")");
7859            }
7860            if (pi.uriPermissionPatterns != null) {
7861                final int N = pi.uriPermissionPatterns.length;
7862                boolean allowed = false;
7863                for (int i=0; i<N; i++) {
7864                    if (pi.uriPermissionPatterns[i] != null
7865                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7866                        allowed = true;
7867                        break;
7868                    }
7869                }
7870                if (!allowed) {
7871                    throw new SecurityException("Provider " + pi.packageName
7872                            + "/" + pi.name
7873                            + " does not allow granting of permission to path of Uri "
7874                            + grantUri);
7875                }
7876            }
7877        }
7878
7879        // Third...  does the caller itself have permission to access
7880        // this uri?
7881        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7882            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7883                // Require they hold a strong enough Uri permission
7884                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7885                    throw new SecurityException("Uid " + callingUid
7886                            + " does not have permission to uri " + grantUri);
7887                }
7888            }
7889        }
7890        return targetUid;
7891    }
7892
7893    /**
7894     * @param uri This uri must NOT contain an embedded userId.
7895     * @param userId The userId in which the uri is to be resolved.
7896     */
7897    @Override
7898    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7899            final int modeFlags, int userId) {
7900        enforceNotIsolatedCaller("checkGrantUriPermission");
7901        synchronized(this) {
7902            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7903                    new GrantUri(userId, uri, false), modeFlags, -1);
7904        }
7905    }
7906
7907    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7908            final int modeFlags, UriPermissionOwner owner) {
7909        if (!Intent.isAccessUriMode(modeFlags)) {
7910            return;
7911        }
7912
7913        // So here we are: the caller has the assumed permission
7914        // to the uri, and the target doesn't.  Let's now give this to
7915        // the target.
7916
7917        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7918                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7919
7920        final String authority = grantUri.uri.getAuthority();
7921        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7922        if (pi == null) {
7923            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7924            return;
7925        }
7926
7927        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7928            grantUri.prefix = true;
7929        }
7930        final UriPermission perm = findOrCreateUriPermissionLocked(
7931                pi.packageName, targetPkg, targetUid, grantUri);
7932        perm.grantModes(modeFlags, owner);
7933    }
7934
7935    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7936            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7937        if (targetPkg == null) {
7938            throw new NullPointerException("targetPkg");
7939        }
7940        int targetUid;
7941        final IPackageManager pm = AppGlobals.getPackageManager();
7942        try {
7943            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7944        } catch (RemoteException ex) {
7945            return;
7946        }
7947
7948        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7949                targetUid);
7950        if (targetUid < 0) {
7951            return;
7952        }
7953
7954        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7955                owner);
7956    }
7957
7958    static class NeededUriGrants extends ArrayList<GrantUri> {
7959        final String targetPkg;
7960        final int targetUid;
7961        final int flags;
7962
7963        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7964            this.targetPkg = targetPkg;
7965            this.targetUid = targetUid;
7966            this.flags = flags;
7967        }
7968    }
7969
7970    /**
7971     * Like checkGrantUriPermissionLocked, but takes an Intent.
7972     */
7973    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7974            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7975        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7977                + " clip=" + (intent != null ? intent.getClipData() : null)
7978                + " from " + intent + "; flags=0x"
7979                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7980
7981        if (targetPkg == null) {
7982            throw new NullPointerException("targetPkg");
7983        }
7984
7985        if (intent == null) {
7986            return null;
7987        }
7988        Uri data = intent.getData();
7989        ClipData clip = intent.getClipData();
7990        if (data == null && clip == null) {
7991            return null;
7992        }
7993        // Default userId for uris in the intent (if they don't specify it themselves)
7994        int contentUserHint = intent.getContentUserHint();
7995        if (contentUserHint == UserHandle.USER_CURRENT) {
7996            contentUserHint = UserHandle.getUserId(callingUid);
7997        }
7998        final IPackageManager pm = AppGlobals.getPackageManager();
7999        int targetUid;
8000        if (needed != null) {
8001            targetUid = needed.targetUid;
8002        } else {
8003            try {
8004                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8005                        targetUserId);
8006            } catch (RemoteException ex) {
8007                return null;
8008            }
8009            if (targetUid < 0) {
8010                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8011                        "Can't grant URI permission no uid for: " + targetPkg
8012                        + " on user " + targetUserId);
8013                return null;
8014            }
8015        }
8016        if (data != null) {
8017            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8018            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8019                    targetUid);
8020            if (targetUid > 0) {
8021                if (needed == null) {
8022                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8023                }
8024                needed.add(grantUri);
8025            }
8026        }
8027        if (clip != null) {
8028            for (int i=0; i<clip.getItemCount(); i++) {
8029                Uri uri = clip.getItemAt(i).getUri();
8030                if (uri != null) {
8031                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8032                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8033                            targetUid);
8034                    if (targetUid > 0) {
8035                        if (needed == null) {
8036                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8037                        }
8038                        needed.add(grantUri);
8039                    }
8040                } else {
8041                    Intent clipIntent = clip.getItemAt(i).getIntent();
8042                    if (clipIntent != null) {
8043                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8044                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8045                        if (newNeeded != null) {
8046                            needed = newNeeded;
8047                        }
8048                    }
8049                }
8050            }
8051        }
8052
8053        return needed;
8054    }
8055
8056    /**
8057     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8058     */
8059    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8060            UriPermissionOwner owner) {
8061        if (needed != null) {
8062            for (int i=0; i<needed.size(); i++) {
8063                GrantUri grantUri = needed.get(i);
8064                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8065                        grantUri, needed.flags, owner);
8066            }
8067        }
8068    }
8069
8070    void grantUriPermissionFromIntentLocked(int callingUid,
8071            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8072        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8073                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8074        if (needed == null) {
8075            return;
8076        }
8077
8078        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8079    }
8080
8081    /**
8082     * @param uri This uri must NOT contain an embedded userId.
8083     * @param userId The userId in which the uri is to be resolved.
8084     */
8085    @Override
8086    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8087            final int modeFlags, int userId) {
8088        enforceNotIsolatedCaller("grantUriPermission");
8089        GrantUri grantUri = new GrantUri(userId, uri, false);
8090        synchronized(this) {
8091            final ProcessRecord r = getRecordForAppLocked(caller);
8092            if (r == null) {
8093                throw new SecurityException("Unable to find app for caller "
8094                        + caller
8095                        + " when granting permission to uri " + grantUri);
8096            }
8097            if (targetPkg == null) {
8098                throw new IllegalArgumentException("null target");
8099            }
8100            if (grantUri == null) {
8101                throw new IllegalArgumentException("null uri");
8102            }
8103
8104            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8105                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8106                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8107                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8108
8109            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8110                    UserHandle.getUserId(r.uid));
8111        }
8112    }
8113
8114    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8115        if (perm.modeFlags == 0) {
8116            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8117                    perm.targetUid);
8118            if (perms != null) {
8119                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8121
8122                perms.remove(perm.uri);
8123                if (perms.isEmpty()) {
8124                    mGrantedUriPermissions.remove(perm.targetUid);
8125                }
8126            }
8127        }
8128    }
8129
8130    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8131        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8132                "Revoking all granted permissions to " + grantUri);
8133
8134        final IPackageManager pm = AppGlobals.getPackageManager();
8135        final String authority = grantUri.uri.getAuthority();
8136        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8137        if (pi == null) {
8138            Slog.w(TAG, "No content provider found for permission revoke: "
8139                    + grantUri.toSafeString());
8140            return;
8141        }
8142
8143        // Does the caller have this permission on the URI?
8144        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8145            // If they don't have direct access to the URI, then revoke any
8146            // ownerless URI permissions that have been granted to them.
8147            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8148            if (perms != null) {
8149                boolean persistChanged = false;
8150                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8151                    final UriPermission perm = it.next();
8152                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8153                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8154                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8155                                "Revoking non-owned " + perm.targetUid
8156                                + " permission to " + perm.uri);
8157                        persistChanged |= perm.revokeModes(
8158                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8159                        if (perm.modeFlags == 0) {
8160                            it.remove();
8161                        }
8162                    }
8163                }
8164                if (perms.isEmpty()) {
8165                    mGrantedUriPermissions.remove(callingUid);
8166                }
8167                if (persistChanged) {
8168                    schedulePersistUriGrants();
8169                }
8170            }
8171            return;
8172        }
8173
8174        boolean persistChanged = false;
8175
8176        // Go through all of the permissions and remove any that match.
8177        int N = mGrantedUriPermissions.size();
8178        for (int i = 0; i < N; i++) {
8179            final int targetUid = mGrantedUriPermissions.keyAt(i);
8180            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8181
8182            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8183                final UriPermission perm = it.next();
8184                if (perm.uri.sourceUserId == grantUri.sourceUserId
8185                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8186                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8187                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8188                    persistChanged |= perm.revokeModes(
8189                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8190                    if (perm.modeFlags == 0) {
8191                        it.remove();
8192                    }
8193                }
8194            }
8195
8196            if (perms.isEmpty()) {
8197                mGrantedUriPermissions.remove(targetUid);
8198                N--;
8199                i--;
8200            }
8201        }
8202
8203        if (persistChanged) {
8204            schedulePersistUriGrants();
8205        }
8206    }
8207
8208    /**
8209     * @param uri This uri must NOT contain an embedded userId.
8210     * @param userId The userId in which the uri is to be resolved.
8211     */
8212    @Override
8213    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8214            int userId) {
8215        enforceNotIsolatedCaller("revokeUriPermission");
8216        synchronized(this) {
8217            final ProcessRecord r = getRecordForAppLocked(caller);
8218            if (r == null) {
8219                throw new SecurityException("Unable to find app for caller "
8220                        + caller
8221                        + " when revoking permission to uri " + uri);
8222            }
8223            if (uri == null) {
8224                Slog.w(TAG, "revokeUriPermission: null uri");
8225                return;
8226            }
8227
8228            if (!Intent.isAccessUriMode(modeFlags)) {
8229                return;
8230            }
8231
8232            final String authority = uri.getAuthority();
8233            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8234            if (pi == null) {
8235                Slog.w(TAG, "No content provider found for permission revoke: "
8236                        + uri.toSafeString());
8237                return;
8238            }
8239
8240            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8241        }
8242    }
8243
8244    /**
8245     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8246     * given package.
8247     *
8248     * @param packageName Package name to match, or {@code null} to apply to all
8249     *            packages.
8250     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8251     *            to all users.
8252     * @param persistable If persistable grants should be removed.
8253     */
8254    private void removeUriPermissionsForPackageLocked(
8255            String packageName, int userHandle, boolean persistable) {
8256        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8257            throw new IllegalArgumentException("Must narrow by either package or user");
8258        }
8259
8260        boolean persistChanged = false;
8261
8262        int N = mGrantedUriPermissions.size();
8263        for (int i = 0; i < N; i++) {
8264            final int targetUid = mGrantedUriPermissions.keyAt(i);
8265            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8266
8267            // Only inspect grants matching user
8268            if (userHandle == UserHandle.USER_ALL
8269                    || userHandle == UserHandle.getUserId(targetUid)) {
8270                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8271                    final UriPermission perm = it.next();
8272
8273                    // Only inspect grants matching package
8274                    if (packageName == null || perm.sourcePkg.equals(packageName)
8275                            || perm.targetPkg.equals(packageName)) {
8276                        persistChanged |= perm.revokeModes(persistable
8277                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8278
8279                        // Only remove when no modes remain; any persisted grants
8280                        // will keep this alive.
8281                        if (perm.modeFlags == 0) {
8282                            it.remove();
8283                        }
8284                    }
8285                }
8286
8287                if (perms.isEmpty()) {
8288                    mGrantedUriPermissions.remove(targetUid);
8289                    N--;
8290                    i--;
8291                }
8292            }
8293        }
8294
8295        if (persistChanged) {
8296            schedulePersistUriGrants();
8297        }
8298    }
8299
8300    @Override
8301    public IBinder newUriPermissionOwner(String name) {
8302        enforceNotIsolatedCaller("newUriPermissionOwner");
8303        synchronized(this) {
8304            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8305            return owner.getExternalTokenLocked();
8306        }
8307    }
8308
8309    @Override
8310    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8311        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8312        synchronized(this) {
8313            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8314            if (r == null) {
8315                throw new IllegalArgumentException("Activity does not exist; token="
8316                        + activityToken);
8317            }
8318            return r.getUriPermissionsLocked().getExternalTokenLocked();
8319        }
8320    }
8321    /**
8322     * @param uri This uri must NOT contain an embedded userId.
8323     * @param sourceUserId The userId in which the uri is to be resolved.
8324     * @param targetUserId The userId of the app that receives the grant.
8325     */
8326    @Override
8327    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8328            final int modeFlags, int sourceUserId, int targetUserId) {
8329        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8330                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8331                "grantUriPermissionFromOwner", null);
8332        synchronized(this) {
8333            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8334            if (owner == null) {
8335                throw new IllegalArgumentException("Unknown owner: " + token);
8336            }
8337            if (fromUid != Binder.getCallingUid()) {
8338                if (Binder.getCallingUid() != Process.myUid()) {
8339                    // Only system code can grant URI permissions on behalf
8340                    // of other users.
8341                    throw new SecurityException("nice try");
8342                }
8343            }
8344            if (targetPkg == null) {
8345                throw new IllegalArgumentException("null target");
8346            }
8347            if (uri == null) {
8348                throw new IllegalArgumentException("null uri");
8349            }
8350
8351            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8352                    modeFlags, owner, targetUserId);
8353        }
8354    }
8355
8356    /**
8357     * @param uri This uri must NOT contain an embedded userId.
8358     * @param userId The userId in which the uri is to be resolved.
8359     */
8360    @Override
8361    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8362        synchronized(this) {
8363            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8364            if (owner == null) {
8365                throw new IllegalArgumentException("Unknown owner: " + token);
8366            }
8367
8368            if (uri == null) {
8369                owner.removeUriPermissionsLocked(mode);
8370            } else {
8371                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8372            }
8373        }
8374    }
8375
8376    private void schedulePersistUriGrants() {
8377        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8378            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8379                    10 * DateUtils.SECOND_IN_MILLIS);
8380        }
8381    }
8382
8383    private void writeGrantedUriPermissions() {
8384        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8385
8386        // Snapshot permissions so we can persist without lock
8387        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8388        synchronized (this) {
8389            final int size = mGrantedUriPermissions.size();
8390            for (int i = 0; i < size; i++) {
8391                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8392                for (UriPermission perm : perms.values()) {
8393                    if (perm.persistedModeFlags != 0) {
8394                        persist.add(perm.snapshot());
8395                    }
8396                }
8397            }
8398        }
8399
8400        FileOutputStream fos = null;
8401        try {
8402            fos = mGrantFile.startWrite();
8403
8404            XmlSerializer out = new FastXmlSerializer();
8405            out.setOutput(fos, StandardCharsets.UTF_8.name());
8406            out.startDocument(null, true);
8407            out.startTag(null, TAG_URI_GRANTS);
8408            for (UriPermission.Snapshot perm : persist) {
8409                out.startTag(null, TAG_URI_GRANT);
8410                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8411                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8412                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8413                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8414                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8415                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8416                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8417                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8418                out.endTag(null, TAG_URI_GRANT);
8419            }
8420            out.endTag(null, TAG_URI_GRANTS);
8421            out.endDocument();
8422
8423            mGrantFile.finishWrite(fos);
8424        } catch (IOException e) {
8425            if (fos != null) {
8426                mGrantFile.failWrite(fos);
8427            }
8428        }
8429    }
8430
8431    private void readGrantedUriPermissionsLocked() {
8432        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8433
8434        final long now = System.currentTimeMillis();
8435
8436        FileInputStream fis = null;
8437        try {
8438            fis = mGrantFile.openRead();
8439            final XmlPullParser in = Xml.newPullParser();
8440            in.setInput(fis, StandardCharsets.UTF_8.name());
8441
8442            int type;
8443            while ((type = in.next()) != END_DOCUMENT) {
8444                final String tag = in.getName();
8445                if (type == START_TAG) {
8446                    if (TAG_URI_GRANT.equals(tag)) {
8447                        final int sourceUserId;
8448                        final int targetUserId;
8449                        final int userHandle = readIntAttribute(in,
8450                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8451                        if (userHandle != UserHandle.USER_NULL) {
8452                            // For backwards compatibility.
8453                            sourceUserId = userHandle;
8454                            targetUserId = userHandle;
8455                        } else {
8456                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8457                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8458                        }
8459                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8460                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8461                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8462                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8463                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8464                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8465
8466                        // Sanity check that provider still belongs to source package
8467                        final ProviderInfo pi = getProviderInfoLocked(
8468                                uri.getAuthority(), sourceUserId);
8469                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8470                            int targetUid = -1;
8471                            try {
8472                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8473                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8474                            } catch (RemoteException e) {
8475                            }
8476                            if (targetUid != -1) {
8477                                final UriPermission perm = findOrCreateUriPermissionLocked(
8478                                        sourcePkg, targetPkg, targetUid,
8479                                        new GrantUri(sourceUserId, uri, prefix));
8480                                perm.initPersistedModes(modeFlags, createdTime);
8481                            }
8482                        } else {
8483                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8484                                    + " but instead found " + pi);
8485                        }
8486                    }
8487                }
8488            }
8489        } catch (FileNotFoundException e) {
8490            // Missing grants is okay
8491        } catch (IOException e) {
8492            Slog.wtf(TAG, "Failed reading Uri grants", e);
8493        } catch (XmlPullParserException e) {
8494            Slog.wtf(TAG, "Failed reading Uri grants", e);
8495        } finally {
8496            IoUtils.closeQuietly(fis);
8497        }
8498    }
8499
8500    /**
8501     * @param uri This uri must NOT contain an embedded userId.
8502     * @param userId The userId in which the uri is to be resolved.
8503     */
8504    @Override
8505    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8506        enforceNotIsolatedCaller("takePersistableUriPermission");
8507
8508        Preconditions.checkFlagsArgument(modeFlags,
8509                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8510
8511        synchronized (this) {
8512            final int callingUid = Binder.getCallingUid();
8513            boolean persistChanged = false;
8514            GrantUri grantUri = new GrantUri(userId, uri, false);
8515
8516            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8517                    new GrantUri(userId, uri, false));
8518            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8519                    new GrantUri(userId, uri, true));
8520
8521            final boolean exactValid = (exactPerm != null)
8522                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8523            final boolean prefixValid = (prefixPerm != null)
8524                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8525
8526            if (!(exactValid || prefixValid)) {
8527                throw new SecurityException("No persistable permission grants found for UID "
8528                        + callingUid + " and Uri " + grantUri.toSafeString());
8529            }
8530
8531            if (exactValid) {
8532                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8533            }
8534            if (prefixValid) {
8535                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8536            }
8537
8538            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8539
8540            if (persistChanged) {
8541                schedulePersistUriGrants();
8542            }
8543        }
8544    }
8545
8546    /**
8547     * @param uri This uri must NOT contain an embedded userId.
8548     * @param userId The userId in which the uri is to be resolved.
8549     */
8550    @Override
8551    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8552        enforceNotIsolatedCaller("releasePersistableUriPermission");
8553
8554        Preconditions.checkFlagsArgument(modeFlags,
8555                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8556
8557        synchronized (this) {
8558            final int callingUid = Binder.getCallingUid();
8559            boolean persistChanged = false;
8560
8561            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8562                    new GrantUri(userId, uri, false));
8563            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8564                    new GrantUri(userId, uri, true));
8565            if (exactPerm == null && prefixPerm == null) {
8566                throw new SecurityException("No permission grants found for UID " + callingUid
8567                        + " and Uri " + uri.toSafeString());
8568            }
8569
8570            if (exactPerm != null) {
8571                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8572                removeUriPermissionIfNeededLocked(exactPerm);
8573            }
8574            if (prefixPerm != null) {
8575                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8576                removeUriPermissionIfNeededLocked(prefixPerm);
8577            }
8578
8579            if (persistChanged) {
8580                schedulePersistUriGrants();
8581            }
8582        }
8583    }
8584
8585    /**
8586     * Prune any older {@link UriPermission} for the given UID until outstanding
8587     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8588     *
8589     * @return if any mutations occured that require persisting.
8590     */
8591    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8592        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8593        if (perms == null) return false;
8594        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8595
8596        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8597        for (UriPermission perm : perms.values()) {
8598            if (perm.persistedModeFlags != 0) {
8599                persisted.add(perm);
8600            }
8601        }
8602
8603        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8604        if (trimCount <= 0) return false;
8605
8606        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8607        for (int i = 0; i < trimCount; i++) {
8608            final UriPermission perm = persisted.get(i);
8609
8610            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8611                    "Trimming grant created at " + perm.persistedCreateTime);
8612
8613            perm.releasePersistableModes(~0);
8614            removeUriPermissionIfNeededLocked(perm);
8615        }
8616
8617        return true;
8618    }
8619
8620    @Override
8621    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8622            String packageName, boolean incoming) {
8623        enforceNotIsolatedCaller("getPersistedUriPermissions");
8624        Preconditions.checkNotNull(packageName, "packageName");
8625
8626        final int callingUid = Binder.getCallingUid();
8627        final IPackageManager pm = AppGlobals.getPackageManager();
8628        try {
8629            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8630                    UserHandle.getUserId(callingUid));
8631            if (packageUid != callingUid) {
8632                throw new SecurityException(
8633                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8634            }
8635        } catch (RemoteException e) {
8636            throw new SecurityException("Failed to verify package name ownership");
8637        }
8638
8639        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8640        synchronized (this) {
8641            if (incoming) {
8642                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8643                        callingUid);
8644                if (perms == null) {
8645                    Slog.w(TAG, "No permission grants found for " + packageName);
8646                } else {
8647                    for (UriPermission perm : perms.values()) {
8648                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8649                            result.add(perm.buildPersistedPublicApiObject());
8650                        }
8651                    }
8652                }
8653            } else {
8654                final int size = mGrantedUriPermissions.size();
8655                for (int i = 0; i < size; i++) {
8656                    final ArrayMap<GrantUri, UriPermission> perms =
8657                            mGrantedUriPermissions.valueAt(i);
8658                    for (UriPermission perm : perms.values()) {
8659                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8660                            result.add(perm.buildPersistedPublicApiObject());
8661                        }
8662                    }
8663                }
8664            }
8665        }
8666        return new ParceledListSlice<android.content.UriPermission>(result);
8667    }
8668
8669    @Override
8670    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8671            String packageName, int userId) {
8672        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8673                "getGrantedUriPermissions");
8674
8675        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8676        synchronized (this) {
8677            final int size = mGrantedUriPermissions.size();
8678            for (int i = 0; i < size; i++) {
8679                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8680                for (UriPermission perm : perms.values()) {
8681                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8682                            && perm.persistedModeFlags != 0) {
8683                        result.add(perm.buildPersistedPublicApiObject());
8684                    }
8685                }
8686            }
8687        }
8688        return new ParceledListSlice<android.content.UriPermission>(result);
8689    }
8690
8691    @Override
8692    public void clearGrantedUriPermissions(String packageName, int userId) {
8693        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8694                "clearGrantedUriPermissions");
8695        removeUriPermissionsForPackageLocked(packageName, userId, true);
8696    }
8697
8698    @Override
8699    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8700        synchronized (this) {
8701            ProcessRecord app =
8702                who != null ? getRecordForAppLocked(who) : null;
8703            if (app == null) return;
8704
8705            Message msg = Message.obtain();
8706            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8707            msg.obj = app;
8708            msg.arg1 = waiting ? 1 : 0;
8709            mUiHandler.sendMessage(msg);
8710        }
8711    }
8712
8713    @Override
8714    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8715        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8716        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8717        outInfo.availMem = Process.getFreeMemory();
8718        outInfo.totalMem = Process.getTotalMemory();
8719        outInfo.threshold = homeAppMem;
8720        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8721        outInfo.hiddenAppThreshold = cachedAppMem;
8722        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8723                ProcessList.SERVICE_ADJ);
8724        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8725                ProcessList.VISIBLE_APP_ADJ);
8726        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8727                ProcessList.FOREGROUND_APP_ADJ);
8728    }
8729
8730    // =========================================================
8731    // TASK MANAGEMENT
8732    // =========================================================
8733
8734    @Override
8735    public List<IAppTask> getAppTasks(String callingPackage) {
8736        int callingUid = Binder.getCallingUid();
8737        long ident = Binder.clearCallingIdentity();
8738
8739        synchronized(this) {
8740            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8741            try {
8742                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8743
8744                final int N = mRecentTasks.size();
8745                for (int i = 0; i < N; i++) {
8746                    TaskRecord tr = mRecentTasks.get(i);
8747                    // Skip tasks that do not match the caller.  We don't need to verify
8748                    // callingPackage, because we are also limiting to callingUid and know
8749                    // that will limit to the correct security sandbox.
8750                    if (tr.effectiveUid != callingUid) {
8751                        continue;
8752                    }
8753                    Intent intent = tr.getBaseIntent();
8754                    if (intent == null ||
8755                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8756                        continue;
8757                    }
8758                    ActivityManager.RecentTaskInfo taskInfo =
8759                            createRecentTaskInfoFromTaskRecord(tr);
8760                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8761                    list.add(taskImpl);
8762                }
8763            } finally {
8764                Binder.restoreCallingIdentity(ident);
8765            }
8766            return list;
8767        }
8768    }
8769
8770    @Override
8771    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8772        final int callingUid = Binder.getCallingUid();
8773        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8774
8775        synchronized(this) {
8776            if (DEBUG_ALL) Slog.v(
8777                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8778
8779            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8780                    callingUid);
8781
8782            // TODO: Improve with MRU list from all ActivityStacks.
8783            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8784        }
8785
8786        return list;
8787    }
8788
8789    /**
8790     * Creates a new RecentTaskInfo from a TaskRecord.
8791     */
8792    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8793        // Update the task description to reflect any changes in the task stack
8794        tr.updateTaskDescription();
8795
8796        // Compose the recent task info
8797        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8798        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8799        rti.persistentId = tr.taskId;
8800        rti.baseIntent = new Intent(tr.getBaseIntent());
8801        rti.origActivity = tr.origActivity;
8802        rti.realActivity = tr.realActivity;
8803        rti.description = tr.lastDescription;
8804        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8805        rti.userId = tr.userId;
8806        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8807        rti.firstActiveTime = tr.firstActiveTime;
8808        rti.lastActiveTime = tr.lastActiveTime;
8809        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8810        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8811        rti.numActivities = 0;
8812        if (tr.mBounds != null) {
8813            rti.bounds = new Rect(tr.mBounds);
8814        }
8815        rti.isDockable = tr.canGoInDockedStack();
8816        rti.resizeMode = tr.mResizeMode;
8817
8818        ActivityRecord base = null;
8819        ActivityRecord top = null;
8820        ActivityRecord tmp;
8821
8822        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8823            tmp = tr.mActivities.get(i);
8824            if (tmp.finishing) {
8825                continue;
8826            }
8827            base = tmp;
8828            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8829                top = base;
8830            }
8831            rti.numActivities++;
8832        }
8833
8834        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8835        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8836
8837        return rti;
8838    }
8839
8840    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8841        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8842                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8843        if (!allowed) {
8844            if (checkPermission(android.Manifest.permission.GET_TASKS,
8845                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8846                // Temporary compatibility: some existing apps on the system image may
8847                // still be requesting the old permission and not switched to the new
8848                // one; if so, we'll still allow them full access.  This means we need
8849                // to see if they are holding the old permission and are a system app.
8850                try {
8851                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8852                        allowed = true;
8853                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8854                                + " is using old GET_TASKS but privileged; allowing");
8855                    }
8856                } catch (RemoteException e) {
8857                }
8858            }
8859        }
8860        if (!allowed) {
8861            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8862                    + " does not hold REAL_GET_TASKS; limiting output");
8863        }
8864        return allowed;
8865    }
8866
8867    @Override
8868    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8869        final int callingUid = Binder.getCallingUid();
8870        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8871                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8872
8873        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8874        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8875        synchronized (this) {
8876            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8877                    callingUid);
8878            final boolean detailed = checkCallingPermission(
8879                    android.Manifest.permission.GET_DETAILED_TASKS)
8880                    == PackageManager.PERMISSION_GRANTED;
8881
8882            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8883                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8884                return Collections.emptyList();
8885            }
8886            mRecentTasks.loadUserRecentsLocked(userId);
8887
8888            final int recentsCount = mRecentTasks.size();
8889            ArrayList<ActivityManager.RecentTaskInfo> res =
8890                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8891
8892            final Set<Integer> includedUsers;
8893            if (includeProfiles) {
8894                includedUsers = mUserController.getProfileIds(userId);
8895            } else {
8896                includedUsers = new HashSet<>();
8897            }
8898            includedUsers.add(Integer.valueOf(userId));
8899
8900            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8901                TaskRecord tr = mRecentTasks.get(i);
8902                // Only add calling user or related users recent tasks
8903                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8904                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8905                    continue;
8906                }
8907
8908                if (tr.realActivitySuspended) {
8909                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8910                    continue;
8911                }
8912
8913                // Return the entry if desired by the caller.  We always return
8914                // the first entry, because callers always expect this to be the
8915                // foreground app.  We may filter others if the caller has
8916                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8917                // we should exclude the entry.
8918
8919                if (i == 0
8920                        || withExcluded
8921                        || (tr.intent == null)
8922                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8923                                == 0)) {
8924                    if (!allowed) {
8925                        // If the caller doesn't have the GET_TASKS permission, then only
8926                        // allow them to see a small subset of tasks -- their own and home.
8927                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8928                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8929                            continue;
8930                        }
8931                    }
8932                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8933                        if (tr.stack != null && tr.stack.isHomeStack()) {
8934                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8935                                    "Skipping, home stack task: " + tr);
8936                            continue;
8937                        }
8938                    }
8939                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8940                        final ActivityStack stack = tr.stack;
8941                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8942                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8943                                    "Skipping, top task in docked stack: " + tr);
8944                            continue;
8945                        }
8946                    }
8947                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8948                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8949                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8950                                    "Skipping, pinned stack task: " + tr);
8951                            continue;
8952                        }
8953                    }
8954                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8955                        // Don't include auto remove tasks that are finished or finishing.
8956                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8957                                "Skipping, auto-remove without activity: " + tr);
8958                        continue;
8959                    }
8960                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8961                            && !tr.isAvailable) {
8962                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8963                                "Skipping, unavail real act: " + tr);
8964                        continue;
8965                    }
8966
8967                    if (!tr.mUserSetupComplete) {
8968                        // Don't include task launched while user is not done setting-up.
8969                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8970                                "Skipping, user setup not complete: " + tr);
8971                        continue;
8972                    }
8973
8974                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8975                    if (!detailed) {
8976                        rti.baseIntent.replaceExtras((Bundle)null);
8977                    }
8978
8979                    res.add(rti);
8980                    maxNum--;
8981                }
8982            }
8983            return res;
8984        }
8985    }
8986
8987    @Override
8988    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8989        synchronized (this) {
8990            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8991                    "getTaskThumbnail()");
8992            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8993                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8994            if (tr != null) {
8995                return tr.getTaskThumbnailLocked();
8996            }
8997        }
8998        return null;
8999    }
9000
9001    @Override
9002    public int addAppTask(IBinder activityToken, Intent intent,
9003            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9004        final int callingUid = Binder.getCallingUid();
9005        final long callingIdent = Binder.clearCallingIdentity();
9006
9007        try {
9008            synchronized (this) {
9009                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9010                if (r == null) {
9011                    throw new IllegalArgumentException("Activity does not exist; token="
9012                            + activityToken);
9013                }
9014                ComponentName comp = intent.getComponent();
9015                if (comp == null) {
9016                    throw new IllegalArgumentException("Intent " + intent
9017                            + " must specify explicit component");
9018                }
9019                if (thumbnail.getWidth() != mThumbnailWidth
9020                        || thumbnail.getHeight() != mThumbnailHeight) {
9021                    throw new IllegalArgumentException("Bad thumbnail size: got "
9022                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9023                            + mThumbnailWidth + "x" + mThumbnailHeight);
9024                }
9025                if (intent.getSelector() != null) {
9026                    intent.setSelector(null);
9027                }
9028                if (intent.getSourceBounds() != null) {
9029                    intent.setSourceBounds(null);
9030                }
9031                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9032                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9033                        // The caller has added this as an auto-remove task...  that makes no
9034                        // sense, so turn off auto-remove.
9035                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9036                    }
9037                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9038                    // Must be a new task.
9039                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9040                }
9041                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9042                    mLastAddedTaskActivity = null;
9043                }
9044                ActivityInfo ainfo = mLastAddedTaskActivity;
9045                if (ainfo == null) {
9046                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9047                            comp, 0, UserHandle.getUserId(callingUid));
9048                    if (ainfo.applicationInfo.uid != callingUid) {
9049                        throw new SecurityException(
9050                                "Can't add task for another application: target uid="
9051                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9052                    }
9053                }
9054
9055                // Use the full screen as the context for the task thumbnail
9056                final Point displaySize = new Point();
9057                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9058                r.task.stack.getDisplaySize(displaySize);
9059                thumbnailInfo.taskWidth = displaySize.x;
9060                thumbnailInfo.taskHeight = displaySize.y;
9061                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9062
9063                TaskRecord task = new TaskRecord(this,
9064                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9065                        ainfo, intent, description, thumbnailInfo);
9066
9067                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9068                if (trimIdx >= 0) {
9069                    // If this would have caused a trim, then we'll abort because that
9070                    // means it would be added at the end of the list but then just removed.
9071                    return INVALID_TASK_ID;
9072                }
9073
9074                final int N = mRecentTasks.size();
9075                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9076                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9077                    tr.removedFromRecents();
9078                }
9079
9080                task.inRecents = true;
9081                mRecentTasks.add(task);
9082                r.task.stack.addTask(task, false, "addAppTask");
9083
9084                task.setLastThumbnailLocked(thumbnail);
9085                task.freeLastThumbnail();
9086
9087                return task.taskId;
9088            }
9089        } finally {
9090            Binder.restoreCallingIdentity(callingIdent);
9091        }
9092    }
9093
9094    @Override
9095    public Point getAppTaskThumbnailSize() {
9096        synchronized (this) {
9097            return new Point(mThumbnailWidth,  mThumbnailHeight);
9098        }
9099    }
9100
9101    @Override
9102    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9103        synchronized (this) {
9104            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9105            if (r != null) {
9106                r.setTaskDescription(td);
9107                r.task.updateTaskDescription();
9108            }
9109        }
9110    }
9111
9112    @Override
9113    public void setTaskResizeable(int taskId, int resizeableMode) {
9114        synchronized (this) {
9115            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9116                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9117            if (task == null) {
9118                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9119                return;
9120            }
9121            if (task.mResizeMode != resizeableMode) {
9122                task.mResizeMode = resizeableMode;
9123                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9124                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9125                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9126            }
9127        }
9128    }
9129
9130    @Override
9131    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9132        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9133        long ident = Binder.clearCallingIdentity();
9134        try {
9135            synchronized (this) {
9136                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9137                if (task == null) {
9138                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9139                    return;
9140                }
9141                int stackId = task.stack.mStackId;
9142                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9143                // in crop windows resize mode or if the task size is affected by the docked stack
9144                // changing size. No need to update configuration.
9145                if (bounds != null && task.inCropWindowsResizeMode()
9146                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9147                    mWindowManager.scrollTask(task.taskId, bounds);
9148                    return;
9149                }
9150
9151                // Place the task in the right stack if it isn't there already based on
9152                // the requested bounds.
9153                // The stack transition logic is:
9154                // - a null bounds on a freeform task moves that task to fullscreen
9155                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9156                //   that task to freeform
9157                // - otherwise the task is not moved
9158                if (!StackId.isTaskResizeAllowed(stackId)) {
9159                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9160                }
9161                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9162                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9163                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9164                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9165                }
9166                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9167                if (stackId != task.stack.mStackId) {
9168                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9169                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9170                    preserveWindow = false;
9171                }
9172
9173                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9174                        false /* deferResume */);
9175            }
9176        } finally {
9177            Binder.restoreCallingIdentity(ident);
9178        }
9179    }
9180
9181    @Override
9182    public Rect getTaskBounds(int taskId) {
9183        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9184        long ident = Binder.clearCallingIdentity();
9185        Rect rect = new Rect();
9186        try {
9187            synchronized (this) {
9188                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9189                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9190                if (task == null) {
9191                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9192                    return rect;
9193                }
9194                if (task.stack != null) {
9195                    // Return the bounds from window manager since it will be adjusted for various
9196                    // things like the presense of a docked stack for tasks that aren't resizeable.
9197                    mWindowManager.getTaskBounds(task.taskId, rect);
9198                } else {
9199                    // Task isn't in window manager yet since it isn't associated with a stack.
9200                    // Return the persist value from activity manager
9201                    if (task.mBounds != null) {
9202                        rect.set(task.mBounds);
9203                    } else if (task.mLastNonFullscreenBounds != null) {
9204                        rect.set(task.mLastNonFullscreenBounds);
9205                    }
9206                }
9207            }
9208        } finally {
9209            Binder.restoreCallingIdentity(ident);
9210        }
9211        return rect;
9212    }
9213
9214    @Override
9215    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9216        if (userId != UserHandle.getCallingUserId()) {
9217            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9218                    "getTaskDescriptionIcon");
9219        }
9220        final File passedIconFile = new File(filePath);
9221        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9222                passedIconFile.getName());
9223        if (!legitIconFile.getPath().equals(filePath)
9224                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9225            throw new IllegalArgumentException("Bad file path: " + filePath
9226                    + " passed for userId " + userId);
9227        }
9228        return mRecentTasks.getTaskDescriptionIcon(filePath);
9229    }
9230
9231    @Override
9232    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9233            throws RemoteException {
9234        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9235                opts.getCustomInPlaceResId() == 0) {
9236            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9237                    "with valid animation");
9238        }
9239        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9240        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9241                opts.getCustomInPlaceResId());
9242        mWindowManager.executeAppTransition();
9243    }
9244
9245    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9246            boolean removeFromRecents) {
9247        if (removeFromRecents) {
9248            mRecentTasks.remove(tr);
9249            tr.removedFromRecents();
9250        }
9251        ComponentName component = tr.getBaseIntent().getComponent();
9252        if (component == null) {
9253            Slog.w(TAG, "No component for base intent of task: " + tr);
9254            return;
9255        }
9256
9257        // Find any running services associated with this app and stop if needed.
9258        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9259
9260        if (!killProcess) {
9261            return;
9262        }
9263
9264        // Determine if the process(es) for this task should be killed.
9265        final String pkg = component.getPackageName();
9266        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9267        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9268        for (int i = 0; i < pmap.size(); i++) {
9269
9270            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9271            for (int j = 0; j < uids.size(); j++) {
9272                ProcessRecord proc = uids.valueAt(j);
9273                if (proc.userId != tr.userId) {
9274                    // Don't kill process for a different user.
9275                    continue;
9276                }
9277                if (proc == mHomeProcess) {
9278                    // Don't kill the home process along with tasks from the same package.
9279                    continue;
9280                }
9281                if (!proc.pkgList.containsKey(pkg)) {
9282                    // Don't kill process that is not associated with this task.
9283                    continue;
9284                }
9285
9286                for (int k = 0; k < proc.activities.size(); k++) {
9287                    TaskRecord otherTask = proc.activities.get(k).task;
9288                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9289                        // Don't kill process(es) that has an activity in a different task that is
9290                        // also in recents.
9291                        return;
9292                    }
9293                }
9294
9295                if (proc.foregroundServices) {
9296                    // Don't kill process(es) with foreground service.
9297                    return;
9298                }
9299
9300                // Add process to kill list.
9301                procsToKill.add(proc);
9302            }
9303        }
9304
9305        // Kill the running processes.
9306        for (int i = 0; i < procsToKill.size(); i++) {
9307            ProcessRecord pr = procsToKill.get(i);
9308            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9309                    && pr.curReceiver == null) {
9310                pr.kill("remove task", true);
9311            } else {
9312                // We delay killing processes that are not in the background or running a receiver.
9313                pr.waitingToKill = "remove task";
9314            }
9315        }
9316    }
9317
9318    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9319        // Remove all tasks with activities in the specified package from the list of recent tasks
9320        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9321            TaskRecord tr = mRecentTasks.get(i);
9322            if (tr.userId != userId) continue;
9323
9324            ComponentName cn = tr.intent.getComponent();
9325            if (cn != null && cn.getPackageName().equals(packageName)) {
9326                // If the package name matches, remove the task.
9327                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9328            }
9329        }
9330    }
9331
9332    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9333            int userId) {
9334
9335        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9336            TaskRecord tr = mRecentTasks.get(i);
9337            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9338                continue;
9339            }
9340
9341            ComponentName cn = tr.intent.getComponent();
9342            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9343                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9344            if (sameComponent) {
9345                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9346            }
9347        }
9348    }
9349
9350    /**
9351     * Removes the task with the specified task id.
9352     *
9353     * @param taskId Identifier of the task to be removed.
9354     * @param killProcess Kill any process associated with the task if possible.
9355     * @param removeFromRecents Whether to also remove the task from recents.
9356     * @return Returns true if the given task was found and removed.
9357     */
9358    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9359            boolean removeFromRecents) {
9360        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9361                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9362        if (tr != null) {
9363            tr.removeTaskActivitiesLocked();
9364            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9365            if (tr.isPersistable) {
9366                notifyTaskPersisterLocked(null, true);
9367            }
9368            return true;
9369        }
9370        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9371        return false;
9372    }
9373
9374    @Override
9375    public void removeStack(int stackId) {
9376        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9377        if (stackId == HOME_STACK_ID) {
9378            throw new IllegalArgumentException("Removing home stack is not allowed.");
9379        }
9380
9381        synchronized (this) {
9382            final long ident = Binder.clearCallingIdentity();
9383            try {
9384                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9385                if (stack == null) {
9386                    return;
9387                }
9388                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9389                for (int i = tasks.size() - 1; i >= 0; i--) {
9390                    removeTaskByIdLocked(
9391                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9392                }
9393            } finally {
9394                Binder.restoreCallingIdentity(ident);
9395            }
9396        }
9397    }
9398
9399    @Override
9400    public boolean removeTask(int taskId) {
9401        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9402        synchronized (this) {
9403            final long ident = Binder.clearCallingIdentity();
9404            try {
9405                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9406            } finally {
9407                Binder.restoreCallingIdentity(ident);
9408            }
9409        }
9410    }
9411
9412    /**
9413     * TODO: Add mController hook
9414     */
9415    @Override
9416    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9417        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9418
9419        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9420        synchronized(this) {
9421            moveTaskToFrontLocked(taskId, flags, bOptions);
9422        }
9423    }
9424
9425    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9426        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9427
9428        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9429                Binder.getCallingUid(), -1, -1, "Task to front")) {
9430            ActivityOptions.abort(options);
9431            return;
9432        }
9433        final long origId = Binder.clearCallingIdentity();
9434        try {
9435            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9436            if (task == null) {
9437                Slog.d(TAG, "Could not find task for id: "+ taskId);
9438                return;
9439            }
9440            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9441                mStackSupervisor.showLockTaskToast();
9442                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9443                return;
9444            }
9445            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9446            if (prev != null && prev.isRecentsActivity()) {
9447                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9448            }
9449            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9450                    false /* forceNonResizable */);
9451        } finally {
9452            Binder.restoreCallingIdentity(origId);
9453        }
9454        ActivityOptions.abort(options);
9455    }
9456
9457    /**
9458     * Moves an activity, and all of the other activities within the same task, to the bottom
9459     * of the history stack.  The activity's order within the task is unchanged.
9460     *
9461     * @param token A reference to the activity we wish to move
9462     * @param nonRoot If false then this only works if the activity is the root
9463     *                of a task; if true it will work for any activity in a task.
9464     * @return Returns true if the move completed, false if not.
9465     */
9466    @Override
9467    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9468        enforceNotIsolatedCaller("moveActivityTaskToBack");
9469        synchronized(this) {
9470            final long origId = Binder.clearCallingIdentity();
9471            try {
9472                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9473                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9474                if (task != null) {
9475                    if (mStackSupervisor.isLockedTask(task)) {
9476                        mStackSupervisor.showLockTaskToast();
9477                        return false;
9478                    }
9479                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9480                }
9481            } finally {
9482                Binder.restoreCallingIdentity(origId);
9483            }
9484        }
9485        return false;
9486    }
9487
9488    @Override
9489    public void moveTaskBackwards(int task) {
9490        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9491                "moveTaskBackwards()");
9492
9493        synchronized(this) {
9494            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9495                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9496                return;
9497            }
9498            final long origId = Binder.clearCallingIdentity();
9499            moveTaskBackwardsLocked(task);
9500            Binder.restoreCallingIdentity(origId);
9501        }
9502    }
9503
9504    private final void moveTaskBackwardsLocked(int task) {
9505        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9506    }
9507
9508    @Override
9509    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9510            IActivityContainerCallback callback) throws RemoteException {
9511        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9512        synchronized (this) {
9513            if (parentActivityToken == null) {
9514                throw new IllegalArgumentException("parent token must not be null");
9515            }
9516            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9517            if (r == null) {
9518                return null;
9519            }
9520            if (callback == null) {
9521                throw new IllegalArgumentException("callback must not be null");
9522            }
9523            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9524        }
9525    }
9526
9527    @Override
9528    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9529        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9530        synchronized (this) {
9531            mStackSupervisor.deleteActivityContainer(container);
9532        }
9533    }
9534
9535    @Override
9536    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9537        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9538        synchronized (this) {
9539            final int stackId = mStackSupervisor.getNextStackId();
9540            final ActivityStack stack =
9541                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9542            if (stack == null) {
9543                return null;
9544            }
9545            return stack.mActivityContainer;
9546        }
9547    }
9548
9549    @Override
9550    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9551        synchronized (this) {
9552            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9553            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9554                return stack.mActivityContainer.getDisplayId();
9555            }
9556            return Display.DEFAULT_DISPLAY;
9557        }
9558    }
9559
9560    @Override
9561    public int getActivityStackId(IBinder token) throws RemoteException {
9562        synchronized (this) {
9563            ActivityStack stack = ActivityRecord.getStackLocked(token);
9564            if (stack == null) {
9565                return INVALID_STACK_ID;
9566            }
9567            return stack.mStackId;
9568        }
9569    }
9570
9571    @Override
9572    public void exitFreeformMode(IBinder token) throws RemoteException {
9573        synchronized (this) {
9574            long ident = Binder.clearCallingIdentity();
9575            try {
9576                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9577                if (r == null) {
9578                    throw new IllegalArgumentException(
9579                            "exitFreeformMode: No activity record matching token=" + token);
9580                }
9581                final ActivityStack stack = r.getStackLocked(token);
9582                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9583                    throw new IllegalStateException(
9584                            "exitFreeformMode: You can only go fullscreen from freeform.");
9585                }
9586                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9587                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9588                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9589            } finally {
9590                Binder.restoreCallingIdentity(ident);
9591            }
9592        }
9593    }
9594
9595    @Override
9596    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9597        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9598        if (stackId == HOME_STACK_ID) {
9599            throw new IllegalArgumentException(
9600                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9601        }
9602        synchronized (this) {
9603            long ident = Binder.clearCallingIdentity();
9604            try {
9605                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9606                        + " to stackId=" + stackId + " toTop=" + toTop);
9607                if (stackId == DOCKED_STACK_ID) {
9608                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9609                            null /* initialBounds */);
9610                }
9611                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9612                        "moveTaskToStack", ANIMATE);
9613            } finally {
9614                Binder.restoreCallingIdentity(ident);
9615            }
9616        }
9617    }
9618
9619    @Override
9620    public void swapDockedAndFullscreenStack() throws RemoteException {
9621        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9622        synchronized (this) {
9623            long ident = Binder.clearCallingIdentity();
9624            try {
9625                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9626                        FULLSCREEN_WORKSPACE_STACK_ID);
9627                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9628                        : null;
9629                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9630                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9631                        : null;
9632                if (topTask == null || tasks == null || tasks.size() == 0) {
9633                    Slog.w(TAG,
9634                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9635                    return;
9636                }
9637
9638                // TODO: App transition
9639                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9640
9641                // Defer the resume so resume/pausing while moving stacks is dangerous.
9642                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9643                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9644                        ANIMATE, true /* deferResume */);
9645                final int size = tasks.size();
9646                for (int i = 0; i < size; i++) {
9647                    final int id = tasks.get(i).taskId;
9648                    if (id == topTask.taskId) {
9649                        continue;
9650                    }
9651                    mStackSupervisor.moveTaskToStackLocked(id,
9652                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9653                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9654                }
9655
9656                // Because we deferred the resume, to avoid conflicts with stack switches while
9657                // resuming, we need to do it after all the tasks are moved.
9658                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9659                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9660
9661                mWindowManager.executeAppTransition();
9662            } finally {
9663                Binder.restoreCallingIdentity(ident);
9664            }
9665        }
9666    }
9667
9668    /**
9669     * Moves the input task to the docked stack.
9670     *
9671     * @param taskId Id of task to move.
9672     * @param createMode The mode the docked stack should be created in if it doesn't exist
9673     *                   already. See
9674     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9675     *                   and
9676     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9677     * @param toTop If the task and stack should be moved to the top.
9678     * @param animate Whether we should play an animation for the moving the task
9679     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9680     *                      docked stack. Pass {@code null} to use default bounds.
9681     */
9682    @Override
9683    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9684            Rect initialBounds) {
9685        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9686        synchronized (this) {
9687            long ident = Binder.clearCallingIdentity();
9688            try {
9689                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9690                        + " to createMode=" + createMode + " toTop=" + toTop);
9691                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9692                return mStackSupervisor.moveTaskToStackLocked(
9693                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9694                        "moveTaskToDockedStack", animate);
9695            } finally {
9696                Binder.restoreCallingIdentity(ident);
9697            }
9698        }
9699    }
9700
9701    /**
9702     * Moves the top activity in the input stackId to the pinned stack.
9703     *
9704     * @param stackId Id of stack to move the top activity to pinned stack.
9705     * @param bounds Bounds to use for pinned stack.
9706     *
9707     * @return True if the top activity of the input stack was successfully moved to the pinned
9708     *          stack.
9709     */
9710    @Override
9711    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9712        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9713        synchronized (this) {
9714            if (!mSupportsPictureInPicture) {
9715                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9716                        + "Device doesn't support picture-in-pciture mode");
9717            }
9718
9719            long ident = Binder.clearCallingIdentity();
9720            try {
9721                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9730            boolean preserveWindows, boolean animate, int animationDuration) {
9731        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9732        long ident = Binder.clearCallingIdentity();
9733        try {
9734            synchronized (this) {
9735                if (animate) {
9736                    if (stackId == PINNED_STACK_ID) {
9737                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9738                    } else {
9739                        throw new IllegalArgumentException("Stack: " + stackId
9740                                + " doesn't support animated resize.");
9741                    }
9742                } else {
9743                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9744                            null /* tempTaskInsetBounds */, preserveWindows,
9745                            allowResizeInDockedMode);
9746                }
9747            }
9748        } finally {
9749            Binder.restoreCallingIdentity(ident);
9750        }
9751    }
9752
9753    @Override
9754    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9755            Rect tempDockedTaskInsetBounds,
9756            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9758                "resizeDockedStack()");
9759        long ident = Binder.clearCallingIdentity();
9760        try {
9761            synchronized (this) {
9762                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9763                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9764                        PRESERVE_WINDOWS);
9765            }
9766        } finally {
9767            Binder.restoreCallingIdentity(ident);
9768        }
9769    }
9770
9771    @Override
9772    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9773        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9774                "resizePinnedStack()");
9775        final long ident = Binder.clearCallingIdentity();
9776        try {
9777            synchronized (this) {
9778                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9779            }
9780        } finally {
9781            Binder.restoreCallingIdentity(ident);
9782        }
9783    }
9784
9785    @Override
9786    public void positionTaskInStack(int taskId, int stackId, int position) {
9787        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9788        if (stackId == HOME_STACK_ID) {
9789            throw new IllegalArgumentException(
9790                    "positionTaskInStack: Attempt to change the position of task "
9791                    + taskId + " in/to home stack");
9792        }
9793        synchronized (this) {
9794            long ident = Binder.clearCallingIdentity();
9795            try {
9796                if (DEBUG_STACK) Slog.d(TAG_STACK,
9797                        "positionTaskInStack: positioning task=" + taskId
9798                        + " in stackId=" + stackId + " at position=" + position);
9799                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9800            } finally {
9801                Binder.restoreCallingIdentity(ident);
9802            }
9803        }
9804    }
9805
9806    @Override
9807    public List<StackInfo> getAllStackInfos() {
9808        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9809        long ident = Binder.clearCallingIdentity();
9810        try {
9811            synchronized (this) {
9812                return mStackSupervisor.getAllStackInfosLocked();
9813            }
9814        } finally {
9815            Binder.restoreCallingIdentity(ident);
9816        }
9817    }
9818
9819    @Override
9820    public StackInfo getStackInfo(int stackId) {
9821        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9822        long ident = Binder.clearCallingIdentity();
9823        try {
9824            synchronized (this) {
9825                return mStackSupervisor.getStackInfoLocked(stackId);
9826            }
9827        } finally {
9828            Binder.restoreCallingIdentity(ident);
9829        }
9830    }
9831
9832    @Override
9833    public boolean isInHomeStack(int taskId) {
9834        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9835        long ident = Binder.clearCallingIdentity();
9836        try {
9837            synchronized (this) {
9838                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9839                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9840                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9841            }
9842        } finally {
9843            Binder.restoreCallingIdentity(ident);
9844        }
9845    }
9846
9847    @Override
9848    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9849        synchronized(this) {
9850            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9851        }
9852    }
9853
9854    @Override
9855    public void updateDeviceOwner(String packageName) {
9856        final int callingUid = Binder.getCallingUid();
9857        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9858            throw new SecurityException("updateDeviceOwner called from non-system process");
9859        }
9860        synchronized (this) {
9861            mDeviceOwnerName = packageName;
9862        }
9863    }
9864
9865    @Override
9866    public void updateLockTaskPackages(int userId, String[] packages) {
9867        final int callingUid = Binder.getCallingUid();
9868        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9869            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9870                    "updateLockTaskPackages()");
9871        }
9872        synchronized (this) {
9873            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9874                    Arrays.toString(packages));
9875            mLockTaskPackages.put(userId, packages);
9876            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9877        }
9878    }
9879
9880
9881    void startLockTaskModeLocked(TaskRecord task) {
9882        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9883        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9884            return;
9885        }
9886
9887        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9888        // is initiated by system after the pinning request was shown and locked mode is initiated
9889        // by an authorized app directly
9890        final int callingUid = Binder.getCallingUid();
9891        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9892        long ident = Binder.clearCallingIdentity();
9893        try {
9894            if (!isSystemInitiated) {
9895                task.mLockTaskUid = callingUid;
9896                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9897                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9898                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9899                    StatusBarManagerInternal statusBarManager =
9900                            LocalServices.getService(StatusBarManagerInternal.class);
9901                    if (statusBarManager != null) {
9902                        statusBarManager.showScreenPinningRequest(task.taskId);
9903                    }
9904                    return;
9905                }
9906
9907                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9908                if (stack == null || task != stack.topTask()) {
9909                    throw new IllegalArgumentException("Invalid task, not in foreground");
9910                }
9911            }
9912            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9913                    "Locking fully");
9914            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9915                    ActivityManager.LOCK_TASK_MODE_PINNED :
9916                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9917                    "startLockTask", true);
9918        } finally {
9919            Binder.restoreCallingIdentity(ident);
9920        }
9921    }
9922
9923    @Override
9924    public void startLockTaskMode(int taskId) {
9925        synchronized (this) {
9926            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9927            if (task != null) {
9928                startLockTaskModeLocked(task);
9929            }
9930        }
9931    }
9932
9933    @Override
9934    public void startLockTaskMode(IBinder token) {
9935        synchronized (this) {
9936            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9937            if (r == null) {
9938                return;
9939            }
9940            final TaskRecord task = r.task;
9941            if (task != null) {
9942                startLockTaskModeLocked(task);
9943            }
9944        }
9945    }
9946
9947    @Override
9948    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9949        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9950        // This makes inner call to look as if it was initiated by system.
9951        long ident = Binder.clearCallingIdentity();
9952        try {
9953            synchronized (this) {
9954                startLockTaskMode(taskId);
9955            }
9956        } finally {
9957            Binder.restoreCallingIdentity(ident);
9958        }
9959    }
9960
9961    @Override
9962    public void stopLockTaskMode() {
9963        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9964        if (lockTask == null) {
9965            // Our work here is done.
9966            return;
9967        }
9968
9969        final int callingUid = Binder.getCallingUid();
9970        final int lockTaskUid = lockTask.mLockTaskUid;
9971        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9972        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9973            // Done.
9974            return;
9975        } else {
9976            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9977            // It is possible lockTaskMode was started by the system process because
9978            // android:lockTaskMode is set to a locking value in the application manifest
9979            // instead of the app calling startLockTaskMode. In this case
9980            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9981            // {@link TaskRecord.effectiveUid} instead. Also caller with
9982            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9983            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9984                    && callingUid != lockTaskUid
9985                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9986                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9987                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9988            }
9989        }
9990        long ident = Binder.clearCallingIdentity();
9991        try {
9992            Log.d(TAG, "stopLockTaskMode");
9993            // Stop lock task
9994            synchronized (this) {
9995                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9996                        "stopLockTask", true);
9997            }
9998        } finally {
9999            Binder.restoreCallingIdentity(ident);
10000        }
10001    }
10002
10003    /**
10004     * This API should be called by SystemUI only when user perform certain action to dismiss
10005     * lock task mode. We should only dismiss pinned lock task mode in this case.
10006     */
10007    @Override
10008    public void stopSystemLockTaskMode() throws RemoteException {
10009        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10010            stopLockTaskMode();
10011        } else {
10012            mStackSupervisor.showLockTaskToast();
10013        }
10014    }
10015
10016    @Override
10017    public boolean isInLockTaskMode() {
10018        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10019    }
10020
10021    @Override
10022    public int getLockTaskModeState() {
10023        synchronized (this) {
10024            return mStackSupervisor.getLockTaskModeState();
10025        }
10026    }
10027
10028    @Override
10029    public void showLockTaskEscapeMessage(IBinder token) {
10030        synchronized (this) {
10031            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10032            if (r == null) {
10033                return;
10034            }
10035            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10036        }
10037    }
10038
10039    // =========================================================
10040    // CONTENT PROVIDERS
10041    // =========================================================
10042
10043    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10044        List<ProviderInfo> providers = null;
10045        try {
10046            providers = AppGlobals.getPackageManager()
10047                    .queryContentProviders(app.processName, app.uid,
10048                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10049                                    | MATCH_DEBUG_TRIAGED_MISSING)
10050                    .getList();
10051        } catch (RemoteException ex) {
10052        }
10053        if (DEBUG_MU) Slog.v(TAG_MU,
10054                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10055        int userId = app.userId;
10056        if (providers != null) {
10057            int N = providers.size();
10058            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10059            for (int i=0; i<N; i++) {
10060                ProviderInfo cpi =
10061                    (ProviderInfo)providers.get(i);
10062                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10063                        cpi.name, cpi.flags);
10064                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10065                    // This is a singleton provider, but a user besides the
10066                    // default user is asking to initialize a process it runs
10067                    // in...  well, no, it doesn't actually run in this process,
10068                    // it runs in the process of the default user.  Get rid of it.
10069                    providers.remove(i);
10070                    N--;
10071                    i--;
10072                    continue;
10073                }
10074
10075                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10076                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10077                if (cpr == null) {
10078                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10079                    mProviderMap.putProviderByClass(comp, cpr);
10080                }
10081                if (DEBUG_MU) Slog.v(TAG_MU,
10082                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10083                app.pubProviders.put(cpi.name, cpr);
10084                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10085                    // Don't add this if it is a platform component that is marked
10086                    // to run in multiple processes, because this is actually
10087                    // part of the framework so doesn't make sense to track as a
10088                    // separate apk in the process.
10089                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10090                            mProcessStats);
10091                }
10092                notifyPackageUse(cpi.applicationInfo.packageName);
10093            }
10094        }
10095        return providers;
10096    }
10097
10098    /**
10099     * Check if {@link ProcessRecord} has a possible chance at accessing the
10100     * given {@link ProviderInfo}. Final permission checking is always done
10101     * in {@link ContentProvider}.
10102     */
10103    private final String checkContentProviderPermissionLocked(
10104            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10105        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10106        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10107        boolean checkedGrants = false;
10108        if (checkUser) {
10109            // Looking for cross-user grants before enforcing the typical cross-users permissions
10110            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10111            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10112                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10113                    return null;
10114                }
10115                checkedGrants = true;
10116            }
10117            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10118                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10119            if (userId != tmpTargetUserId) {
10120                // When we actually went to determine the final targer user ID, this ended
10121                // up different than our initial check for the authority.  This is because
10122                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10123                // SELF.  So we need to re-check the grants again.
10124                checkedGrants = false;
10125            }
10126        }
10127        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10128                cpi.applicationInfo.uid, cpi.exported)
10129                == PackageManager.PERMISSION_GRANTED) {
10130            return null;
10131        }
10132        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10133                cpi.applicationInfo.uid, cpi.exported)
10134                == PackageManager.PERMISSION_GRANTED) {
10135            return null;
10136        }
10137
10138        PathPermission[] pps = cpi.pathPermissions;
10139        if (pps != null) {
10140            int i = pps.length;
10141            while (i > 0) {
10142                i--;
10143                PathPermission pp = pps[i];
10144                String pprperm = pp.getReadPermission();
10145                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10146                        cpi.applicationInfo.uid, cpi.exported)
10147                        == PackageManager.PERMISSION_GRANTED) {
10148                    return null;
10149                }
10150                String ppwperm = pp.getWritePermission();
10151                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10152                        cpi.applicationInfo.uid, cpi.exported)
10153                        == PackageManager.PERMISSION_GRANTED) {
10154                    return null;
10155                }
10156            }
10157        }
10158        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10159            return null;
10160        }
10161
10162        String msg;
10163        if (!cpi.exported) {
10164            msg = "Permission Denial: opening provider " + cpi.name
10165                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10166                    + ", uid=" + callingUid + ") that is not exported from uid "
10167                    + cpi.applicationInfo.uid;
10168        } else {
10169            msg = "Permission Denial: opening provider " + cpi.name
10170                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10171                    + ", uid=" + callingUid + ") requires "
10172                    + cpi.readPermission + " or " + cpi.writePermission;
10173        }
10174        Slog.w(TAG, msg);
10175        return msg;
10176    }
10177
10178    /**
10179     * Returns if the ContentProvider has granted a uri to callingUid
10180     */
10181    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10182        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10183        if (perms != null) {
10184            for (int i=perms.size()-1; i>=0; i--) {
10185                GrantUri grantUri = perms.keyAt(i);
10186                if (grantUri.sourceUserId == userId || !checkUser) {
10187                    if (matchesProvider(grantUri.uri, cpi)) {
10188                        return true;
10189                    }
10190                }
10191            }
10192        }
10193        return false;
10194    }
10195
10196    /**
10197     * Returns true if the uri authority is one of the authorities specified in the provider.
10198     */
10199    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10200        String uriAuth = uri.getAuthority();
10201        String cpiAuth = cpi.authority;
10202        if (cpiAuth.indexOf(';') == -1) {
10203            return cpiAuth.equals(uriAuth);
10204        }
10205        String[] cpiAuths = cpiAuth.split(";");
10206        int length = cpiAuths.length;
10207        for (int i = 0; i < length; i++) {
10208            if (cpiAuths[i].equals(uriAuth)) return true;
10209        }
10210        return false;
10211    }
10212
10213    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10214            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10215        if (r != null) {
10216            for (int i=0; i<r.conProviders.size(); i++) {
10217                ContentProviderConnection conn = r.conProviders.get(i);
10218                if (conn.provider == cpr) {
10219                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10220                            "Adding provider requested by "
10221                            + r.processName + " from process "
10222                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10223                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10224                    if (stable) {
10225                        conn.stableCount++;
10226                        conn.numStableIncs++;
10227                    } else {
10228                        conn.unstableCount++;
10229                        conn.numUnstableIncs++;
10230                    }
10231                    return conn;
10232                }
10233            }
10234            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10235            if (stable) {
10236                conn.stableCount = 1;
10237                conn.numStableIncs = 1;
10238            } else {
10239                conn.unstableCount = 1;
10240                conn.numUnstableIncs = 1;
10241            }
10242            cpr.connections.add(conn);
10243            r.conProviders.add(conn);
10244            startAssociationLocked(r.uid, r.processName, r.curProcState,
10245                    cpr.uid, cpr.name, cpr.info.processName);
10246            return conn;
10247        }
10248        cpr.addExternalProcessHandleLocked(externalProcessToken);
10249        return null;
10250    }
10251
10252    boolean decProviderCountLocked(ContentProviderConnection conn,
10253            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10254        if (conn != null) {
10255            cpr = conn.provider;
10256            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10257                    "Removing provider requested by "
10258                    + conn.client.processName + " from process "
10259                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10260                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10261            if (stable) {
10262                conn.stableCount--;
10263            } else {
10264                conn.unstableCount--;
10265            }
10266            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10267                cpr.connections.remove(conn);
10268                conn.client.conProviders.remove(conn);
10269                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10270                    // The client is more important than last activity -- note the time this
10271                    // is happening, so we keep the old provider process around a bit as last
10272                    // activity to avoid thrashing it.
10273                    if (cpr.proc != null) {
10274                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10275                    }
10276                }
10277                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10278                return true;
10279            }
10280            return false;
10281        }
10282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10283        return false;
10284    }
10285
10286    private void checkTime(long startTime, String where) {
10287        long now = SystemClock.elapsedRealtime();
10288        if ((now-startTime) > 1000) {
10289            // If we are taking more than a second, log about it.
10290            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10291        }
10292    }
10293
10294    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10295            String name, IBinder token, boolean stable, int userId) {
10296        ContentProviderRecord cpr;
10297        ContentProviderConnection conn = null;
10298        ProviderInfo cpi = null;
10299
10300        synchronized(this) {
10301            long startTime = SystemClock.elapsedRealtime();
10302
10303            ProcessRecord r = null;
10304            if (caller != null) {
10305                r = getRecordForAppLocked(caller);
10306                if (r == null) {
10307                    throw new SecurityException(
10308                            "Unable to find app for caller " + caller
10309                          + " (pid=" + Binder.getCallingPid()
10310                          + ") when getting content provider " + name);
10311                }
10312            }
10313
10314            boolean checkCrossUser = true;
10315
10316            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10317
10318            // First check if this content provider has been published...
10319            cpr = mProviderMap.getProviderByName(name, userId);
10320            // If that didn't work, check if it exists for user 0 and then
10321            // verify that it's a singleton provider before using it.
10322            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10323                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10324                if (cpr != null) {
10325                    cpi = cpr.info;
10326                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10327                            cpi.name, cpi.flags)
10328                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10329                        userId = UserHandle.USER_SYSTEM;
10330                        checkCrossUser = false;
10331                    } else {
10332                        cpr = null;
10333                        cpi = null;
10334                    }
10335                }
10336            }
10337
10338            boolean providerRunning = cpr != null;
10339            if (providerRunning) {
10340                cpi = cpr.info;
10341                String msg;
10342                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10343                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10344                        != null) {
10345                    throw new SecurityException(msg);
10346                }
10347                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10348
10349                if (r != null && cpr.canRunHere(r)) {
10350                    // This provider has been published or is in the process
10351                    // of being published...  but it is also allowed to run
10352                    // in the caller's process, so don't make a connection
10353                    // and just let the caller instantiate its own instance.
10354                    ContentProviderHolder holder = cpr.newHolder(null);
10355                    // don't give caller the provider object, it needs
10356                    // to make its own.
10357                    holder.provider = null;
10358                    return holder;
10359                }
10360
10361                final long origId = Binder.clearCallingIdentity();
10362
10363                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10364
10365                // In this case the provider instance already exists, so we can
10366                // return it right away.
10367                conn = incProviderCountLocked(r, cpr, token, stable);
10368                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10369                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10370                        // If this is a perceptible app accessing the provider,
10371                        // make sure to count it as being accessed and thus
10372                        // back up on the LRU list.  This is good because
10373                        // content providers are often expensive to start.
10374                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10375                        updateLruProcessLocked(cpr.proc, false, null);
10376                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10377                    }
10378                }
10379
10380                if (cpr.proc != null) {
10381                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10382                    boolean success = updateOomAdjLocked(cpr.proc);
10383                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10384                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10385                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10386                    // NOTE: there is still a race here where a signal could be
10387                    // pending on the process even though we managed to update its
10388                    // adj level.  Not sure what to do about this, but at least
10389                    // the race is now smaller.
10390                    if (!success) {
10391                        // Uh oh...  it looks like the provider's process
10392                        // has been killed on us.  We need to wait for a new
10393                        // process to be started, and make sure its death
10394                        // doesn't kill our process.
10395                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10396                                + " is crashing; detaching " + r);
10397                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10398                        checkTime(startTime, "getContentProviderImpl: before appDied");
10399                        appDiedLocked(cpr.proc);
10400                        checkTime(startTime, "getContentProviderImpl: after appDied");
10401                        if (!lastRef) {
10402                            // This wasn't the last ref our process had on
10403                            // the provider...  we have now been killed, bail.
10404                            return null;
10405                        }
10406                        providerRunning = false;
10407                        conn = null;
10408                    }
10409                }
10410
10411                Binder.restoreCallingIdentity(origId);
10412            }
10413
10414            if (!providerRunning) {
10415                try {
10416                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10417                    cpi = AppGlobals.getPackageManager().
10418                        resolveContentProvider(name,
10419                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10420                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10421                } catch (RemoteException ex) {
10422                }
10423                if (cpi == null) {
10424                    return null;
10425                }
10426                // If the provider is a singleton AND
10427                // (it's a call within the same user || the provider is a
10428                // privileged app)
10429                // Then allow connecting to the singleton provider
10430                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10431                        cpi.name, cpi.flags)
10432                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10433                if (singleton) {
10434                    userId = UserHandle.USER_SYSTEM;
10435                }
10436                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10437                checkTime(startTime, "getContentProviderImpl: got app info for user");
10438
10439                String msg;
10440                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10441                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10442                        != null) {
10443                    throw new SecurityException(msg);
10444                }
10445                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10446
10447                if (!mProcessesReady
10448                        && !cpi.processName.equals("system")) {
10449                    // If this content provider does not run in the system
10450                    // process, and the system is not yet ready to run other
10451                    // processes, then fail fast instead of hanging.
10452                    throw new IllegalArgumentException(
10453                            "Attempt to launch content provider before system ready");
10454                }
10455
10456                // Make sure that the user who owns this provider is running.  If not,
10457                // we don't want to allow it to run.
10458                if (!mUserController.isUserRunningLocked(userId, 0)) {
10459                    Slog.w(TAG, "Unable to launch app "
10460                            + cpi.applicationInfo.packageName + "/"
10461                            + cpi.applicationInfo.uid + " for provider "
10462                            + name + ": user " + userId + " is stopped");
10463                    return null;
10464                }
10465
10466                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10467                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10468                cpr = mProviderMap.getProviderByClass(comp, userId);
10469                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10470                final boolean firstClass = cpr == null;
10471                if (firstClass) {
10472                    final long ident = Binder.clearCallingIdentity();
10473
10474                    // If permissions need a review before any of the app components can run,
10475                    // we return no provider and launch a review activity if the calling app
10476                    // is in the foreground.
10477                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10478                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10479                            return null;
10480                        }
10481                    }
10482
10483                    try {
10484                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10485                        ApplicationInfo ai =
10486                            AppGlobals.getPackageManager().
10487                                getApplicationInfo(
10488                                        cpi.applicationInfo.packageName,
10489                                        STOCK_PM_FLAGS, userId);
10490                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10491                        if (ai == null) {
10492                            Slog.w(TAG, "No package info for content provider "
10493                                    + cpi.name);
10494                            return null;
10495                        }
10496                        ai = getAppInfoForUser(ai, userId);
10497                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10498                    } catch (RemoteException ex) {
10499                        // pm is in same process, this will never happen.
10500                    } finally {
10501                        Binder.restoreCallingIdentity(ident);
10502                    }
10503                }
10504
10505                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10506
10507                if (r != null && cpr.canRunHere(r)) {
10508                    // If this is a multiprocess provider, then just return its
10509                    // info and allow the caller to instantiate it.  Only do
10510                    // this if the provider is the same user as the caller's
10511                    // process, or can run as root (so can be in any process).
10512                    return cpr.newHolder(null);
10513                }
10514
10515                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10516                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10517                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10518
10519                // This is single process, and our app is now connecting to it.
10520                // See if we are already in the process of launching this
10521                // provider.
10522                final int N = mLaunchingProviders.size();
10523                int i;
10524                for (i = 0; i < N; i++) {
10525                    if (mLaunchingProviders.get(i) == cpr) {
10526                        break;
10527                    }
10528                }
10529
10530                // If the provider is not already being launched, then get it
10531                // started.
10532                if (i >= N) {
10533                    final long origId = Binder.clearCallingIdentity();
10534
10535                    try {
10536                        // Content provider is now in use, its package can't be stopped.
10537                        try {
10538                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10539                            AppGlobals.getPackageManager().setPackageStoppedState(
10540                                    cpr.appInfo.packageName, false, userId);
10541                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10542                        } catch (RemoteException e) {
10543                        } catch (IllegalArgumentException e) {
10544                            Slog.w(TAG, "Failed trying to unstop package "
10545                                    + cpr.appInfo.packageName + ": " + e);
10546                        }
10547
10548                        // Use existing process if already started
10549                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10550                        ProcessRecord proc = getProcessRecordLocked(
10551                                cpi.processName, cpr.appInfo.uid, false);
10552                        if (proc != null && proc.thread != null) {
10553                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10554                                    "Installing in existing process " + proc);
10555                            if (!proc.pubProviders.containsKey(cpi.name)) {
10556                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10557                                proc.pubProviders.put(cpi.name, cpr);
10558                                try {
10559                                    proc.thread.scheduleInstallProvider(cpi);
10560                                } catch (RemoteException e) {
10561                                }
10562                            }
10563                        } else {
10564                            checkTime(startTime, "getContentProviderImpl: before start process");
10565                            proc = startProcessLocked(cpi.processName,
10566                                    cpr.appInfo, false, 0, "content provider",
10567                                    new ComponentName(cpi.applicationInfo.packageName,
10568                                            cpi.name), false, false, false);
10569                            checkTime(startTime, "getContentProviderImpl: after start process");
10570                            if (proc == null) {
10571                                Slog.w(TAG, "Unable to launch app "
10572                                        + cpi.applicationInfo.packageName + "/"
10573                                        + cpi.applicationInfo.uid + " for provider "
10574                                        + name + ": process is bad");
10575                                return null;
10576                            }
10577                        }
10578                        cpr.launchingApp = proc;
10579                        mLaunchingProviders.add(cpr);
10580                    } finally {
10581                        Binder.restoreCallingIdentity(origId);
10582                    }
10583                }
10584
10585                checkTime(startTime, "getContentProviderImpl: updating data structures");
10586
10587                // Make sure the provider is published (the same provider class
10588                // may be published under multiple names).
10589                if (firstClass) {
10590                    mProviderMap.putProviderByClass(comp, cpr);
10591                }
10592
10593                mProviderMap.putProviderByName(name, cpr);
10594                conn = incProviderCountLocked(r, cpr, token, stable);
10595                if (conn != null) {
10596                    conn.waiting = true;
10597                }
10598            }
10599            checkTime(startTime, "getContentProviderImpl: done!");
10600        }
10601
10602        // Wait for the provider to be published...
10603        synchronized (cpr) {
10604            while (cpr.provider == null) {
10605                if (cpr.launchingApp == null) {
10606                    Slog.w(TAG, "Unable to launch app "
10607                            + cpi.applicationInfo.packageName + "/"
10608                            + cpi.applicationInfo.uid + " for provider "
10609                            + name + ": launching app became null");
10610                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10611                            UserHandle.getUserId(cpi.applicationInfo.uid),
10612                            cpi.applicationInfo.packageName,
10613                            cpi.applicationInfo.uid, name);
10614                    return null;
10615                }
10616                try {
10617                    if (DEBUG_MU) Slog.v(TAG_MU,
10618                            "Waiting to start provider " + cpr
10619                            + " launchingApp=" + cpr.launchingApp);
10620                    if (conn != null) {
10621                        conn.waiting = true;
10622                    }
10623                    cpr.wait();
10624                } catch (InterruptedException ex) {
10625                } finally {
10626                    if (conn != null) {
10627                        conn.waiting = false;
10628                    }
10629                }
10630            }
10631        }
10632        return cpr != null ? cpr.newHolder(conn) : null;
10633    }
10634
10635    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10636            ProcessRecord r, final int userId) {
10637        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10638                cpi.packageName, userId)) {
10639
10640            final boolean callerForeground = r == null || r.setSchedGroup
10641                    != ProcessList.SCHED_GROUP_BACKGROUND;
10642
10643            // Show a permission review UI only for starting from a foreground app
10644            if (!callerForeground) {
10645                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10646                        + cpi.packageName + " requires a permissions review");
10647                return false;
10648            }
10649
10650            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10651            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10652                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10653            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10654
10655            if (DEBUG_PERMISSIONS_REVIEW) {
10656                Slog.i(TAG, "u" + userId + " Launching permission review "
10657                        + "for package " + cpi.packageName);
10658            }
10659
10660            final UserHandle userHandle = new UserHandle(userId);
10661            mHandler.post(new Runnable() {
10662                @Override
10663                public void run() {
10664                    mContext.startActivityAsUser(intent, userHandle);
10665                }
10666            });
10667
10668            return false;
10669        }
10670
10671        return true;
10672    }
10673
10674    PackageManagerInternal getPackageManagerInternalLocked() {
10675        if (mPackageManagerInt == null) {
10676            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10677        }
10678        return mPackageManagerInt;
10679    }
10680
10681    @Override
10682    public final ContentProviderHolder getContentProvider(
10683            IApplicationThread caller, String name, int userId, boolean stable) {
10684        enforceNotIsolatedCaller("getContentProvider");
10685        if (caller == null) {
10686            String msg = "null IApplicationThread when getting content provider "
10687                    + name;
10688            Slog.w(TAG, msg);
10689            throw new SecurityException(msg);
10690        }
10691        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10692        // with cross-user grant.
10693        return getContentProviderImpl(caller, name, null, stable, userId);
10694    }
10695
10696    public ContentProviderHolder getContentProviderExternal(
10697            String name, int userId, IBinder token) {
10698        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10699            "Do not have permission in call getContentProviderExternal()");
10700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10701                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10702        return getContentProviderExternalUnchecked(name, token, userId);
10703    }
10704
10705    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10706            IBinder token, int userId) {
10707        return getContentProviderImpl(null, name, token, true, userId);
10708    }
10709
10710    /**
10711     * Drop a content provider from a ProcessRecord's bookkeeping
10712     */
10713    public void removeContentProvider(IBinder connection, boolean stable) {
10714        enforceNotIsolatedCaller("removeContentProvider");
10715        long ident = Binder.clearCallingIdentity();
10716        try {
10717            synchronized (this) {
10718                ContentProviderConnection conn;
10719                try {
10720                    conn = (ContentProviderConnection)connection;
10721                } catch (ClassCastException e) {
10722                    String msg ="removeContentProvider: " + connection
10723                            + " not a ContentProviderConnection";
10724                    Slog.w(TAG, msg);
10725                    throw new IllegalArgumentException(msg);
10726                }
10727                if (conn == null) {
10728                    throw new NullPointerException("connection is null");
10729                }
10730                if (decProviderCountLocked(conn, null, null, stable)) {
10731                    updateOomAdjLocked();
10732                }
10733            }
10734        } finally {
10735            Binder.restoreCallingIdentity(ident);
10736        }
10737    }
10738
10739    public void removeContentProviderExternal(String name, IBinder token) {
10740        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10741            "Do not have permission in call removeContentProviderExternal()");
10742        int userId = UserHandle.getCallingUserId();
10743        long ident = Binder.clearCallingIdentity();
10744        try {
10745            removeContentProviderExternalUnchecked(name, token, userId);
10746        } finally {
10747            Binder.restoreCallingIdentity(ident);
10748        }
10749    }
10750
10751    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10752        synchronized (this) {
10753            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10754            if(cpr == null) {
10755                //remove from mProvidersByClass
10756                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10757                return;
10758            }
10759
10760            //update content provider record entry info
10761            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10762            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10763            if (localCpr.hasExternalProcessHandles()) {
10764                if (localCpr.removeExternalProcessHandleLocked(token)) {
10765                    updateOomAdjLocked();
10766                } else {
10767                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10768                            + " with no external reference for token: "
10769                            + token + ".");
10770                }
10771            } else {
10772                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10773                        + " with no external references.");
10774            }
10775        }
10776    }
10777
10778    public final void publishContentProviders(IApplicationThread caller,
10779            List<ContentProviderHolder> providers) {
10780        if (providers == null) {
10781            return;
10782        }
10783
10784        enforceNotIsolatedCaller("publishContentProviders");
10785        synchronized (this) {
10786            final ProcessRecord r = getRecordForAppLocked(caller);
10787            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10788            if (r == null) {
10789                throw new SecurityException(
10790                        "Unable to find app for caller " + caller
10791                      + " (pid=" + Binder.getCallingPid()
10792                      + ") when publishing content providers");
10793            }
10794
10795            final long origId = Binder.clearCallingIdentity();
10796
10797            final int N = providers.size();
10798            for (int i = 0; i < N; i++) {
10799                ContentProviderHolder src = providers.get(i);
10800                if (src == null || src.info == null || src.provider == null) {
10801                    continue;
10802                }
10803                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10804                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10805                if (dst != null) {
10806                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10807                    mProviderMap.putProviderByClass(comp, dst);
10808                    String names[] = dst.info.authority.split(";");
10809                    for (int j = 0; j < names.length; j++) {
10810                        mProviderMap.putProviderByName(names[j], dst);
10811                    }
10812
10813                    int launchingCount = mLaunchingProviders.size();
10814                    int j;
10815                    boolean wasInLaunchingProviders = false;
10816                    for (j = 0; j < launchingCount; j++) {
10817                        if (mLaunchingProviders.get(j) == dst) {
10818                            mLaunchingProviders.remove(j);
10819                            wasInLaunchingProviders = true;
10820                            j--;
10821                            launchingCount--;
10822                        }
10823                    }
10824                    if (wasInLaunchingProviders) {
10825                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10826                    }
10827                    synchronized (dst) {
10828                        dst.provider = src.provider;
10829                        dst.proc = r;
10830                        dst.notifyAll();
10831                    }
10832                    updateOomAdjLocked(r);
10833                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10834                            src.info.authority);
10835                }
10836            }
10837
10838            Binder.restoreCallingIdentity(origId);
10839        }
10840    }
10841
10842    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10843        ContentProviderConnection conn;
10844        try {
10845            conn = (ContentProviderConnection)connection;
10846        } catch (ClassCastException e) {
10847            String msg ="refContentProvider: " + connection
10848                    + " not a ContentProviderConnection";
10849            Slog.w(TAG, msg);
10850            throw new IllegalArgumentException(msg);
10851        }
10852        if (conn == null) {
10853            throw new NullPointerException("connection is null");
10854        }
10855
10856        synchronized (this) {
10857            if (stable > 0) {
10858                conn.numStableIncs += stable;
10859            }
10860            stable = conn.stableCount + stable;
10861            if (stable < 0) {
10862                throw new IllegalStateException("stableCount < 0: " + stable);
10863            }
10864
10865            if (unstable > 0) {
10866                conn.numUnstableIncs += unstable;
10867            }
10868            unstable = conn.unstableCount + unstable;
10869            if (unstable < 0) {
10870                throw new IllegalStateException("unstableCount < 0: " + unstable);
10871            }
10872
10873            if ((stable+unstable) <= 0) {
10874                throw new IllegalStateException("ref counts can't go to zero here: stable="
10875                        + stable + " unstable=" + unstable);
10876            }
10877            conn.stableCount = stable;
10878            conn.unstableCount = unstable;
10879            return !conn.dead;
10880        }
10881    }
10882
10883    public void unstableProviderDied(IBinder connection) {
10884        ContentProviderConnection conn;
10885        try {
10886            conn = (ContentProviderConnection)connection;
10887        } catch (ClassCastException e) {
10888            String msg ="refContentProvider: " + connection
10889                    + " not a ContentProviderConnection";
10890            Slog.w(TAG, msg);
10891            throw new IllegalArgumentException(msg);
10892        }
10893        if (conn == null) {
10894            throw new NullPointerException("connection is null");
10895        }
10896
10897        // Safely retrieve the content provider associated with the connection.
10898        IContentProvider provider;
10899        synchronized (this) {
10900            provider = conn.provider.provider;
10901        }
10902
10903        if (provider == null) {
10904            // Um, yeah, we're way ahead of you.
10905            return;
10906        }
10907
10908        // Make sure the caller is being honest with us.
10909        if (provider.asBinder().pingBinder()) {
10910            // Er, no, still looks good to us.
10911            synchronized (this) {
10912                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10913                        + " says " + conn + " died, but we don't agree");
10914                return;
10915            }
10916        }
10917
10918        // Well look at that!  It's dead!
10919        synchronized (this) {
10920            if (conn.provider.provider != provider) {
10921                // But something changed...  good enough.
10922                return;
10923            }
10924
10925            ProcessRecord proc = conn.provider.proc;
10926            if (proc == null || proc.thread == null) {
10927                // Seems like the process is already cleaned up.
10928                return;
10929            }
10930
10931            // As far as we're concerned, this is just like receiving a
10932            // death notification...  just a bit prematurely.
10933            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10934                    + ") early provider death");
10935            final long ident = Binder.clearCallingIdentity();
10936            try {
10937                appDiedLocked(proc);
10938            } finally {
10939                Binder.restoreCallingIdentity(ident);
10940            }
10941        }
10942    }
10943
10944    @Override
10945    public void appNotRespondingViaProvider(IBinder connection) {
10946        enforceCallingPermission(
10947                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10948
10949        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10950        if (conn == null) {
10951            Slog.w(TAG, "ContentProviderConnection is null");
10952            return;
10953        }
10954
10955        final ProcessRecord host = conn.provider.proc;
10956        if (host == null) {
10957            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10958            return;
10959        }
10960
10961        mHandler.post(new Runnable() {
10962            @Override
10963            public void run() {
10964                mAppErrors.appNotResponding(host, null, null, false,
10965                        "ContentProvider not responding");
10966            }
10967        });
10968    }
10969
10970    public final void installSystemProviders() {
10971        List<ProviderInfo> providers;
10972        synchronized (this) {
10973            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10974            providers = generateApplicationProvidersLocked(app);
10975            if (providers != null) {
10976                for (int i=providers.size()-1; i>=0; i--) {
10977                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10978                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10979                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10980                                + ": not system .apk");
10981                        providers.remove(i);
10982                    }
10983                }
10984            }
10985        }
10986        if (providers != null) {
10987            mSystemThread.installSystemProviders(providers);
10988        }
10989
10990        mCoreSettingsObserver = new CoreSettingsObserver(this);
10991        mFontScaleSettingObserver = new FontScaleSettingObserver();
10992
10993        //mUsageStatsService.monitorPackages();
10994    }
10995
10996    private void startPersistentApps(int matchFlags) {
10997        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10998
10999        synchronized (this) {
11000            try {
11001                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11002                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11003                for (ApplicationInfo app : apps) {
11004                    if (!"android".equals(app.packageName)) {
11005                        addAppLocked(app, false, null /* ABI override */);
11006                    }
11007                }
11008            } catch (RemoteException ex) {
11009            }
11010        }
11011    }
11012
11013    /**
11014     * When a user is unlocked, we need to install encryption-unaware providers
11015     * belonging to any running apps.
11016     */
11017    private void installEncryptionUnawareProviders(int userId) {
11018        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11019            // TODO: eventually pivot this back to look at current user state,
11020            // similar to the comment in UserManager.isUserUnlocked(), but for
11021            // now, if we started apps when "unlocked" then unaware providers
11022            // have already been spun up.
11023            return;
11024        }
11025
11026        // We're only interested in providers that are encryption unaware, and
11027        // we don't care about uninstalled apps, since there's no way they're
11028        // running at this point.
11029        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11030
11031        synchronized (this) {
11032            final int NP = mProcessNames.getMap().size();
11033            for (int ip = 0; ip < NP; ip++) {
11034                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11035                final int NA = apps.size();
11036                for (int ia = 0; ia < NA; ia++) {
11037                    final ProcessRecord app = apps.valueAt(ia);
11038                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11039
11040                    final int NG = app.pkgList.size();
11041                    for (int ig = 0; ig < NG; ig++) {
11042                        try {
11043                            final String pkgName = app.pkgList.keyAt(ig);
11044                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11045                                    .getPackageInfo(pkgName, matchFlags, userId);
11046                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11047                                for (ProviderInfo provInfo : pkgInfo.providers) {
11048                                    Log.v(TAG, "Installing " + provInfo);
11049                                    app.thread.scheduleInstallProvider(provInfo);
11050                                }
11051                            }
11052                        } catch (RemoteException ignored) {
11053                        }
11054                    }
11055                }
11056            }
11057        }
11058    }
11059
11060    /**
11061     * Allows apps to retrieve the MIME type of a URI.
11062     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11063     * users, then it does not need permission to access the ContentProvider.
11064     * Either, it needs cross-user uri grants.
11065     *
11066     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11067     *
11068     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11069     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11070     */
11071    public String getProviderMimeType(Uri uri, int userId) {
11072        enforceNotIsolatedCaller("getProviderMimeType");
11073        final String name = uri.getAuthority();
11074        int callingUid = Binder.getCallingUid();
11075        int callingPid = Binder.getCallingPid();
11076        long ident = 0;
11077        boolean clearedIdentity = false;
11078        synchronized (this) {
11079            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11080        }
11081        if (canClearIdentity(callingPid, callingUid, userId)) {
11082            clearedIdentity = true;
11083            ident = Binder.clearCallingIdentity();
11084        }
11085        ContentProviderHolder holder = null;
11086        try {
11087            holder = getContentProviderExternalUnchecked(name, null, userId);
11088            if (holder != null) {
11089                return holder.provider.getType(uri);
11090            }
11091        } catch (RemoteException e) {
11092            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11093            return null;
11094        } finally {
11095            // We need to clear the identity to call removeContentProviderExternalUnchecked
11096            if (!clearedIdentity) {
11097                ident = Binder.clearCallingIdentity();
11098            }
11099            try {
11100                if (holder != null) {
11101                    removeContentProviderExternalUnchecked(name, null, userId);
11102                }
11103            } finally {
11104                Binder.restoreCallingIdentity(ident);
11105            }
11106        }
11107
11108        return null;
11109    }
11110
11111    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11112        if (UserHandle.getUserId(callingUid) == userId) {
11113            return true;
11114        }
11115        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11116                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11117                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11118                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11119                return true;
11120        }
11121        return false;
11122    }
11123
11124    // =========================================================
11125    // GLOBAL MANAGEMENT
11126    // =========================================================
11127
11128    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11129            boolean isolated, int isolatedUid) {
11130        String proc = customProcess != null ? customProcess : info.processName;
11131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11132        final int userId = UserHandle.getUserId(info.uid);
11133        int uid = info.uid;
11134        if (isolated) {
11135            if (isolatedUid == 0) {
11136                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11137                while (true) {
11138                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11139                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11140                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11141                    }
11142                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11143                    mNextIsolatedProcessUid++;
11144                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11145                        // No process for this uid, use it.
11146                        break;
11147                    }
11148                    stepsLeft--;
11149                    if (stepsLeft <= 0) {
11150                        return null;
11151                    }
11152                }
11153            } else {
11154                // Special case for startIsolatedProcess (internal only), where
11155                // the uid of the isolated process is specified by the caller.
11156                uid = isolatedUid;
11157            }
11158        }
11159        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11160        if (!mBooted && !mBooting
11161                && userId == UserHandle.USER_SYSTEM
11162                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11163            r.persistent = true;
11164        }
11165        addProcessNameLocked(r);
11166        return r;
11167    }
11168
11169    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11170            String abiOverride) {
11171        ProcessRecord app;
11172        if (!isolated) {
11173            app = getProcessRecordLocked(info.processName, info.uid, true);
11174        } else {
11175            app = null;
11176        }
11177
11178        if (app == null) {
11179            app = newProcessRecordLocked(info, null, isolated, 0);
11180            updateLruProcessLocked(app, false, null);
11181            updateOomAdjLocked();
11182        }
11183
11184        // This package really, really can not be stopped.
11185        try {
11186            AppGlobals.getPackageManager().setPackageStoppedState(
11187                    info.packageName, false, UserHandle.getUserId(app.uid));
11188        } catch (RemoteException e) {
11189        } catch (IllegalArgumentException e) {
11190            Slog.w(TAG, "Failed trying to unstop package "
11191                    + info.packageName + ": " + e);
11192        }
11193
11194        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11195            app.persistent = true;
11196            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11197        }
11198        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11199            mPersistentStartingProcesses.add(app);
11200            startProcessLocked(app, "added application", app.processName, abiOverride,
11201                    null /* entryPoint */, null /* entryPointArgs */);
11202        }
11203
11204        return app;
11205    }
11206
11207    public void unhandledBack() {
11208        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11209                "unhandledBack()");
11210
11211        synchronized(this) {
11212            final long origId = Binder.clearCallingIdentity();
11213            try {
11214                getFocusedStack().unhandledBackLocked();
11215            } finally {
11216                Binder.restoreCallingIdentity(origId);
11217            }
11218        }
11219    }
11220
11221    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11222        enforceNotIsolatedCaller("openContentUri");
11223        final int userId = UserHandle.getCallingUserId();
11224        String name = uri.getAuthority();
11225        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11226        ParcelFileDescriptor pfd = null;
11227        if (cph != null) {
11228            // We record the binder invoker's uid in thread-local storage before
11229            // going to the content provider to open the file.  Later, in the code
11230            // that handles all permissions checks, we look for this uid and use
11231            // that rather than the Activity Manager's own uid.  The effect is that
11232            // we do the check against the caller's permissions even though it looks
11233            // to the content provider like the Activity Manager itself is making
11234            // the request.
11235            Binder token = new Binder();
11236            sCallerIdentity.set(new Identity(
11237                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11238            try {
11239                pfd = cph.provider.openFile(null, uri, "r", null, token);
11240            } catch (FileNotFoundException e) {
11241                // do nothing; pfd will be returned null
11242            } finally {
11243                // Ensure that whatever happens, we clean up the identity state
11244                sCallerIdentity.remove();
11245                // Ensure we're done with the provider.
11246                removeContentProviderExternalUnchecked(name, null, userId);
11247            }
11248        } else {
11249            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11250        }
11251        return pfd;
11252    }
11253
11254    // Actually is sleeping or shutting down or whatever else in the future
11255    // is an inactive state.
11256    public boolean isSleepingOrShuttingDown() {
11257        return isSleeping() || mShuttingDown;
11258    }
11259
11260    public boolean isSleeping() {
11261        return mSleeping;
11262    }
11263
11264    void onWakefulnessChanged(int wakefulness) {
11265        synchronized(this) {
11266            mWakefulness = wakefulness;
11267            updateSleepIfNeededLocked();
11268        }
11269    }
11270
11271    void finishRunningVoiceLocked() {
11272        if (mRunningVoice != null) {
11273            mRunningVoice = null;
11274            mVoiceWakeLock.release();
11275            updateSleepIfNeededLocked();
11276        }
11277    }
11278
11279    void startTimeTrackingFocusedActivityLocked() {
11280        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11281            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11282        }
11283    }
11284
11285    void updateSleepIfNeededLocked() {
11286        if (mSleeping && !shouldSleepLocked()) {
11287            mSleeping = false;
11288            startTimeTrackingFocusedActivityLocked();
11289            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11290            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11291            updateOomAdjLocked();
11292        } else if (!mSleeping && shouldSleepLocked()) {
11293            mSleeping = true;
11294            if (mCurAppTimeTracker != null) {
11295                mCurAppTimeTracker.stop();
11296            }
11297            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11298            mStackSupervisor.goingToSleepLocked();
11299            updateOomAdjLocked();
11300
11301            // Initialize the wake times of all processes.
11302            checkExcessivePowerUsageLocked(false);
11303            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11304            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11305            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11306        }
11307    }
11308
11309    private boolean shouldSleepLocked() {
11310        // Resume applications while running a voice interactor.
11311        if (mRunningVoice != null) {
11312            return false;
11313        }
11314
11315        // TODO: Transform the lock screen state into a sleep token instead.
11316        switch (mWakefulness) {
11317            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11318            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11319            case PowerManagerInternal.WAKEFULNESS_DOZING:
11320                // Pause applications whenever the lock screen is shown or any sleep
11321                // tokens have been acquired.
11322                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11323            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11324            default:
11325                // If we're asleep then pause applications unconditionally.
11326                return true;
11327        }
11328    }
11329
11330    /** Pokes the task persister. */
11331    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11332        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11333    }
11334
11335    /** Notifies all listeners when the task stack has changed. */
11336    void notifyTaskStackChangedLocked() {
11337        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11338        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11339        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11340        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11341    }
11342
11343    /** Notifies all listeners when an Activity is pinned. */
11344    void notifyActivityPinnedLocked() {
11345        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11346        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11347    }
11348
11349    /**
11350     * Notifies all listeners when an attempt was made to start an an activity that is already
11351     * running in the pinned stack and the activity was not actually started, but the task is
11352     * either brought to the front or a new Intent is delivered to it.
11353     */
11354    void notifyPinnedActivityRestartAttemptLocked() {
11355        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11356        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11357    }
11358
11359    /** Notifies all listeners when the pinned stack animation ends. */
11360    @Override
11361    public void notifyPinnedStackAnimationEnded() {
11362        synchronized (this) {
11363            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11364            mHandler.obtainMessage(
11365                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11366        }
11367    }
11368
11369    @Override
11370    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11371        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11372    }
11373
11374    @Override
11375    public boolean shutdown(int timeout) {
11376        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11377                != PackageManager.PERMISSION_GRANTED) {
11378            throw new SecurityException("Requires permission "
11379                    + android.Manifest.permission.SHUTDOWN);
11380        }
11381
11382        boolean timedout = false;
11383
11384        synchronized(this) {
11385            mShuttingDown = true;
11386            updateEventDispatchingLocked();
11387            timedout = mStackSupervisor.shutdownLocked(timeout);
11388        }
11389
11390        mAppOpsService.shutdown();
11391        if (mUsageStatsService != null) {
11392            mUsageStatsService.prepareShutdown();
11393        }
11394        mBatteryStatsService.shutdown();
11395        synchronized (this) {
11396            mProcessStats.shutdownLocked();
11397            notifyTaskPersisterLocked(null, true);
11398        }
11399
11400        return timedout;
11401    }
11402
11403    public final void activitySlept(IBinder token) {
11404        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11405
11406        final long origId = Binder.clearCallingIdentity();
11407
11408        synchronized (this) {
11409            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11410            if (r != null) {
11411                mStackSupervisor.activitySleptLocked(r);
11412            }
11413        }
11414
11415        Binder.restoreCallingIdentity(origId);
11416    }
11417
11418    private String lockScreenShownToString() {
11419        switch (mLockScreenShown) {
11420            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11421            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11422            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11423            default: return "Unknown=" + mLockScreenShown;
11424        }
11425    }
11426
11427    void logLockScreen(String msg) {
11428        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11429                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11430                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11431                + " mSleeping=" + mSleeping);
11432    }
11433
11434    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11435        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11436        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11437        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11438            boolean wasRunningVoice = mRunningVoice != null;
11439            mRunningVoice = session;
11440            if (!wasRunningVoice) {
11441                mVoiceWakeLock.acquire();
11442                updateSleepIfNeededLocked();
11443            }
11444        }
11445    }
11446
11447    private void updateEventDispatchingLocked() {
11448        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11449    }
11450
11451    public void setLockScreenShown(boolean shown) {
11452        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11453                != PackageManager.PERMISSION_GRANTED) {
11454            throw new SecurityException("Requires permission "
11455                    + android.Manifest.permission.DEVICE_POWER);
11456        }
11457
11458        synchronized(this) {
11459            long ident = Binder.clearCallingIdentity();
11460            try {
11461                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11462                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11463                updateSleepIfNeededLocked();
11464            } finally {
11465                Binder.restoreCallingIdentity(ident);
11466            }
11467        }
11468    }
11469
11470    @Override
11471    public void notifyLockedProfile(@UserIdInt int userId) {
11472        try {
11473            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11474                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11475            }
11476        } catch (RemoteException ex) {
11477            throw new SecurityException("Fail to check is caller a privileged app", ex);
11478        }
11479
11480        synchronized (this) {
11481            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11482                final long ident = Binder.clearCallingIdentity();
11483                try {
11484                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11485                    // Get the focused task before launching launcher.
11486
11487                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11488
11489                        // If there is no device lock, we will show the profile's credential page.
11490                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11491                        if (mFocusedActivity != null) {
11492                            mStackSupervisor.startActivityFromRecentsInner(
11493                                    mFocusedActivity.task.taskId, null);
11494                        }
11495                    } else {
11496                        // Showing launcher to avoid user entering credential twice.
11497                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11498                    }
11499                } finally {
11500                    Binder.restoreCallingIdentity(ident);
11501                }
11502            }
11503        }
11504    }
11505
11506    @Override
11507    public void stopAppSwitches() {
11508        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11509                != PackageManager.PERMISSION_GRANTED) {
11510            throw new SecurityException("viewquires permission "
11511                    + android.Manifest.permission.STOP_APP_SWITCHES);
11512        }
11513
11514        synchronized(this) {
11515            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11516                    + APP_SWITCH_DELAY_TIME;
11517            mDidAppSwitch = false;
11518            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11519            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11520            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11521        }
11522    }
11523
11524    public void resumeAppSwitches() {
11525        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11526                != PackageManager.PERMISSION_GRANTED) {
11527            throw new SecurityException("Requires permission "
11528                    + android.Manifest.permission.STOP_APP_SWITCHES);
11529        }
11530
11531        synchronized(this) {
11532            // Note that we don't execute any pending app switches... we will
11533            // let those wait until either the timeout, or the next start
11534            // activity request.
11535            mAppSwitchesAllowedTime = 0;
11536        }
11537    }
11538
11539    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11540            int callingPid, int callingUid, String name) {
11541        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11542            return true;
11543        }
11544
11545        int perm = checkComponentPermission(
11546                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11547                sourceUid, -1, true);
11548        if (perm == PackageManager.PERMISSION_GRANTED) {
11549            return true;
11550        }
11551
11552        // If the actual IPC caller is different from the logical source, then
11553        // also see if they are allowed to control app switches.
11554        if (callingUid != -1 && callingUid != sourceUid) {
11555            perm = checkComponentPermission(
11556                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11557                    callingUid, -1, true);
11558            if (perm == PackageManager.PERMISSION_GRANTED) {
11559                return true;
11560            }
11561        }
11562
11563        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11564        return false;
11565    }
11566
11567    public void setDebugApp(String packageName, boolean waitForDebugger,
11568            boolean persistent) {
11569        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11570                "setDebugApp()");
11571
11572        long ident = Binder.clearCallingIdentity();
11573        try {
11574            // Note that this is not really thread safe if there are multiple
11575            // callers into it at the same time, but that's not a situation we
11576            // care about.
11577            if (persistent) {
11578                final ContentResolver resolver = mContext.getContentResolver();
11579                Settings.Global.putString(
11580                    resolver, Settings.Global.DEBUG_APP,
11581                    packageName);
11582                Settings.Global.putInt(
11583                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11584                    waitForDebugger ? 1 : 0);
11585            }
11586
11587            synchronized (this) {
11588                if (!persistent) {
11589                    mOrigDebugApp = mDebugApp;
11590                    mOrigWaitForDebugger = mWaitForDebugger;
11591                }
11592                mDebugApp = packageName;
11593                mWaitForDebugger = waitForDebugger;
11594                mDebugTransient = !persistent;
11595                if (packageName != null) {
11596                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11597                            false, UserHandle.USER_ALL, "set debug app");
11598                }
11599            }
11600        } finally {
11601            Binder.restoreCallingIdentity(ident);
11602        }
11603    }
11604
11605    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11606        synchronized (this) {
11607            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11608            if (!isDebuggable) {
11609                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11610                    throw new SecurityException("Process not debuggable: " + app.packageName);
11611                }
11612            }
11613
11614            mTrackAllocationApp = processName;
11615        }
11616    }
11617
11618    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11619        synchronized (this) {
11620            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11621            if (!isDebuggable) {
11622                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11623                    throw new SecurityException("Process not debuggable: " + app.packageName);
11624                }
11625            }
11626            mProfileApp = processName;
11627            mProfileFile = profilerInfo.profileFile;
11628            if (mProfileFd != null) {
11629                try {
11630                    mProfileFd.close();
11631                } catch (IOException e) {
11632                }
11633                mProfileFd = null;
11634            }
11635            mProfileFd = profilerInfo.profileFd;
11636            mSamplingInterval = profilerInfo.samplingInterval;
11637            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11638            mProfileType = 0;
11639        }
11640    }
11641
11642    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11643        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11644        if (!isDebuggable) {
11645            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11646                throw new SecurityException("Process not debuggable: " + app.packageName);
11647            }
11648        }
11649        mNativeDebuggingApp = processName;
11650    }
11651
11652    @Override
11653    public void setAlwaysFinish(boolean enabled) {
11654        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11655                "setAlwaysFinish()");
11656
11657        long ident = Binder.clearCallingIdentity();
11658        try {
11659            Settings.Global.putInt(
11660                    mContext.getContentResolver(),
11661                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11662
11663            synchronized (this) {
11664                mAlwaysFinishActivities = enabled;
11665            }
11666        } finally {
11667            Binder.restoreCallingIdentity(ident);
11668        }
11669    }
11670
11671    @Override
11672    public void setLenientBackgroundCheck(boolean enabled) {
11673        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11674                "setLenientBackgroundCheck()");
11675
11676        long ident = Binder.clearCallingIdentity();
11677        try {
11678            Settings.Global.putInt(
11679                    mContext.getContentResolver(),
11680                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11681
11682            synchronized (this) {
11683                mLenientBackgroundCheck = enabled;
11684            }
11685        } finally {
11686            Binder.restoreCallingIdentity(ident);
11687        }
11688    }
11689
11690    @Override
11691    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11692        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11693                "setActivityController()");
11694        synchronized (this) {
11695            mController = controller;
11696            mControllerIsAMonkey = imAMonkey;
11697            Watchdog.getInstance().setActivityController(controller);
11698        }
11699    }
11700
11701    @Override
11702    public void setUserIsMonkey(boolean userIsMonkey) {
11703        synchronized (this) {
11704            synchronized (mPidsSelfLocked) {
11705                final int callingPid = Binder.getCallingPid();
11706                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11707                if (precessRecord == null) {
11708                    throw new SecurityException("Unknown process: " + callingPid);
11709                }
11710                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11711                    throw new SecurityException("Only an instrumentation process "
11712                            + "with a UiAutomation can call setUserIsMonkey");
11713                }
11714            }
11715            mUserIsMonkey = userIsMonkey;
11716        }
11717    }
11718
11719    @Override
11720    public boolean isUserAMonkey() {
11721        synchronized (this) {
11722            // If there is a controller also implies the user is a monkey.
11723            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11724        }
11725    }
11726
11727    public void requestBugReport(int bugreportType) {
11728        String service = null;
11729        switch (bugreportType) {
11730            case ActivityManager.BUGREPORT_OPTION_FULL:
11731                service = "bugreport";
11732                break;
11733            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11734                service = "bugreportplus";
11735                break;
11736            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11737                service = "bugreportremote";
11738                break;
11739        }
11740        if (service == null) {
11741            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11742                    + bugreportType);
11743        }
11744        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11745        SystemProperties.set("ctl.start", service);
11746    }
11747
11748    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11749        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11750    }
11751
11752    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11753        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11754            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11755        }
11756        return KEY_DISPATCHING_TIMEOUT;
11757    }
11758
11759    @Override
11760    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11761        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11762                != PackageManager.PERMISSION_GRANTED) {
11763            throw new SecurityException("Requires permission "
11764                    + android.Manifest.permission.FILTER_EVENTS);
11765        }
11766        ProcessRecord proc;
11767        long timeout;
11768        synchronized (this) {
11769            synchronized (mPidsSelfLocked) {
11770                proc = mPidsSelfLocked.get(pid);
11771            }
11772            timeout = getInputDispatchingTimeoutLocked(proc);
11773        }
11774
11775        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11776            return -1;
11777        }
11778
11779        return timeout;
11780    }
11781
11782    /**
11783     * Handle input dispatching timeouts.
11784     * Returns whether input dispatching should be aborted or not.
11785     */
11786    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11787            final ActivityRecord activity, final ActivityRecord parent,
11788            final boolean aboveSystem, String reason) {
11789        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11790                != PackageManager.PERMISSION_GRANTED) {
11791            throw new SecurityException("Requires permission "
11792                    + android.Manifest.permission.FILTER_EVENTS);
11793        }
11794
11795        final String annotation;
11796        if (reason == null) {
11797            annotation = "Input dispatching timed out";
11798        } else {
11799            annotation = "Input dispatching timed out (" + reason + ")";
11800        }
11801
11802        if (proc != null) {
11803            synchronized (this) {
11804                if (proc.debugging) {
11805                    return false;
11806                }
11807
11808                if (mDidDexOpt) {
11809                    // Give more time since we were dexopting.
11810                    mDidDexOpt = false;
11811                    return false;
11812                }
11813
11814                if (proc.instrumentationClass != null) {
11815                    Bundle info = new Bundle();
11816                    info.putString("shortMsg", "keyDispatchingTimedOut");
11817                    info.putString("longMsg", annotation);
11818                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11819                    return true;
11820                }
11821            }
11822            mHandler.post(new Runnable() {
11823                @Override
11824                public void run() {
11825                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11826                }
11827            });
11828        }
11829
11830        return true;
11831    }
11832
11833    @Override
11834    public Bundle getAssistContextExtras(int requestType) {
11835        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11836                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11837        if (pae == null) {
11838            return null;
11839        }
11840        synchronized (pae) {
11841            while (!pae.haveResult) {
11842                try {
11843                    pae.wait();
11844                } catch (InterruptedException e) {
11845                }
11846            }
11847        }
11848        synchronized (this) {
11849            buildAssistBundleLocked(pae, pae.result);
11850            mPendingAssistExtras.remove(pae);
11851            mUiHandler.removeCallbacks(pae);
11852        }
11853        return pae.extras;
11854    }
11855
11856    @Override
11857    public boolean isAssistDataAllowedOnCurrentActivity() {
11858        int userId;
11859        synchronized (this) {
11860            userId = mUserController.getCurrentUserIdLocked();
11861            ActivityRecord activity = getFocusedStack().topActivity();
11862            if (activity == null) {
11863                return false;
11864            }
11865            userId = activity.userId;
11866        }
11867        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11868                Context.DEVICE_POLICY_SERVICE);
11869        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11870    }
11871
11872    @Override
11873    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11874        long ident = Binder.clearCallingIdentity();
11875        try {
11876            synchronized (this) {
11877                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11878                ActivityRecord top = getFocusedStack().topActivity();
11879                if (top != caller) {
11880                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11881                            + " is not current top " + top);
11882                    return false;
11883                }
11884                if (!top.nowVisible) {
11885                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11886                            + " is not visible");
11887                    return false;
11888                }
11889            }
11890            AssistUtils utils = new AssistUtils(mContext);
11891            return utils.showSessionForActiveService(args,
11892                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11893        } finally {
11894            Binder.restoreCallingIdentity(ident);
11895        }
11896    }
11897
11898    @Override
11899    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11900            Bundle receiverExtras,
11901            IBinder activityToken, boolean focused) {
11902        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11903                activityToken, focused,
11904                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11905                != null;
11906    }
11907
11908    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11909            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11910            int userHandle, Bundle args, long timeout) {
11911        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11912                "enqueueAssistContext()");
11913        synchronized (this) {
11914            ActivityRecord activity = getFocusedStack().topActivity();
11915            if (activity == null) {
11916                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11917                return null;
11918            }
11919            if (activity.app == null || activity.app.thread == null) {
11920                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11921                return null;
11922            }
11923            if (focused) {
11924                if (activityToken != null) {
11925                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11926                    if (activity != caller) {
11927                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11928                                + " is not current top " + activity);
11929                        return null;
11930                    }
11931                }
11932            } else {
11933                activity = ActivityRecord.forTokenLocked(activityToken);
11934                if (activity == null) {
11935                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11936                            + " couldn't be found");
11937                    return null;
11938                }
11939            }
11940
11941            PendingAssistExtras pae;
11942            Bundle extras = new Bundle();
11943            if (args != null) {
11944                extras.putAll(args);
11945            }
11946            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11947            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11948            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11949                    userHandle);
11950            try {
11951                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11952                        requestType);
11953                mPendingAssistExtras.add(pae);
11954                mUiHandler.postDelayed(pae, timeout);
11955            } catch (RemoteException e) {
11956                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11957                return null;
11958            }
11959            return pae;
11960        }
11961    }
11962
11963    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11964        IResultReceiver receiver;
11965        synchronized (this) {
11966            mPendingAssistExtras.remove(pae);
11967            receiver = pae.receiver;
11968        }
11969        if (receiver != null) {
11970            // Caller wants result sent back to them.
11971            try {
11972                pae.receiver.send(0, null);
11973            } catch (RemoteException e) {
11974            }
11975        }
11976    }
11977
11978    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11979        if (result != null) {
11980            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11981        }
11982        if (pae.hint != null) {
11983            pae.extras.putBoolean(pae.hint, true);
11984        }
11985    }
11986
11987    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11988            AssistContent content, Uri referrer) {
11989        PendingAssistExtras pae = (PendingAssistExtras)token;
11990        synchronized (pae) {
11991            pae.result = extras;
11992            pae.structure = structure;
11993            pae.content = content;
11994            if (referrer != null) {
11995                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11996            }
11997            pae.haveResult = true;
11998            pae.notifyAll();
11999            if (pae.intent == null && pae.receiver == null) {
12000                // Caller is just waiting for the result.
12001                return;
12002            }
12003        }
12004
12005        // We are now ready to launch the assist activity.
12006        IResultReceiver sendReceiver = null;
12007        Bundle sendBundle = null;
12008        synchronized (this) {
12009            buildAssistBundleLocked(pae, extras);
12010            boolean exists = mPendingAssistExtras.remove(pae);
12011            mUiHandler.removeCallbacks(pae);
12012            if (!exists) {
12013                // Timed out.
12014                return;
12015            }
12016            if ((sendReceiver=pae.receiver) != null) {
12017                // Caller wants result sent back to them.
12018                sendBundle = new Bundle();
12019                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12020                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12021                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12022                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12023                        pae.receiverExtras);
12024            }
12025        }
12026        if (sendReceiver != null) {
12027            try {
12028                sendReceiver.send(0, sendBundle);
12029            } catch (RemoteException e) {
12030            }
12031            return;
12032        }
12033
12034        long ident = Binder.clearCallingIdentity();
12035        try {
12036            pae.intent.replaceExtras(pae.extras);
12037            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12038                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12039                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12040            closeSystemDialogs("assist");
12041            try {
12042                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12043            } catch (ActivityNotFoundException e) {
12044                Slog.w(TAG, "No activity to handle assist action.", e);
12045            }
12046        } finally {
12047            Binder.restoreCallingIdentity(ident);
12048        }
12049    }
12050
12051    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12052            Bundle args) {
12053        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12054                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12055    }
12056
12057    public void registerProcessObserver(IProcessObserver observer) {
12058        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12059                "registerProcessObserver()");
12060        synchronized (this) {
12061            mProcessObservers.register(observer);
12062        }
12063    }
12064
12065    @Override
12066    public void unregisterProcessObserver(IProcessObserver observer) {
12067        synchronized (this) {
12068            mProcessObservers.unregister(observer);
12069        }
12070    }
12071
12072    @Override
12073    public void registerUidObserver(IUidObserver observer, int which) {
12074        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12075                "registerUidObserver()");
12076        synchronized (this) {
12077            mUidObservers.register(observer, which);
12078        }
12079    }
12080
12081    @Override
12082    public void unregisterUidObserver(IUidObserver observer) {
12083        synchronized (this) {
12084            mUidObservers.unregister(observer);
12085        }
12086    }
12087
12088    @Override
12089    public boolean convertFromTranslucent(IBinder token) {
12090        final long origId = Binder.clearCallingIdentity();
12091        try {
12092            synchronized (this) {
12093                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12094                if (r == null) {
12095                    return false;
12096                }
12097                final boolean translucentChanged = r.changeWindowTranslucency(true);
12098                if (translucentChanged) {
12099                    r.task.stack.releaseBackgroundResources(r);
12100                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12101                }
12102                mWindowManager.setAppFullscreen(token, true);
12103                return translucentChanged;
12104            }
12105        } finally {
12106            Binder.restoreCallingIdentity(origId);
12107        }
12108    }
12109
12110    @Override
12111    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12112        final long origId = Binder.clearCallingIdentity();
12113        try {
12114            synchronized (this) {
12115                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12116                if (r == null) {
12117                    return false;
12118                }
12119                int index = r.task.mActivities.lastIndexOf(r);
12120                if (index > 0) {
12121                    ActivityRecord under = r.task.mActivities.get(index - 1);
12122                    under.returningOptions = options;
12123                }
12124                final boolean translucentChanged = r.changeWindowTranslucency(false);
12125                if (translucentChanged) {
12126                    r.task.stack.convertActivityToTranslucent(r);
12127                }
12128                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12129                mWindowManager.setAppFullscreen(token, false);
12130                return translucentChanged;
12131            }
12132        } finally {
12133            Binder.restoreCallingIdentity(origId);
12134        }
12135    }
12136
12137    @Override
12138    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12139        final long origId = Binder.clearCallingIdentity();
12140        try {
12141            synchronized (this) {
12142                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12143                if (r != null) {
12144                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12145                }
12146            }
12147            return false;
12148        } finally {
12149            Binder.restoreCallingIdentity(origId);
12150        }
12151    }
12152
12153    @Override
12154    public boolean isBackgroundVisibleBehind(IBinder token) {
12155        final long origId = Binder.clearCallingIdentity();
12156        try {
12157            synchronized (this) {
12158                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12159                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12160                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12161                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12162                return visible;
12163            }
12164        } finally {
12165            Binder.restoreCallingIdentity(origId);
12166        }
12167    }
12168
12169    @Override
12170    public ActivityOptions getActivityOptions(IBinder token) {
12171        final long origId = Binder.clearCallingIdentity();
12172        try {
12173            synchronized (this) {
12174                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12175                if (r != null) {
12176                    final ActivityOptions activityOptions = r.pendingOptions;
12177                    r.pendingOptions = null;
12178                    return activityOptions;
12179                }
12180                return null;
12181            }
12182        } finally {
12183            Binder.restoreCallingIdentity(origId);
12184        }
12185    }
12186
12187    @Override
12188    public void setImmersive(IBinder token, boolean immersive) {
12189        synchronized(this) {
12190            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12191            if (r == null) {
12192                throw new IllegalArgumentException();
12193            }
12194            r.immersive = immersive;
12195
12196            // update associated state if we're frontmost
12197            if (r == mFocusedActivity) {
12198                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12199                applyUpdateLockStateLocked(r);
12200            }
12201        }
12202    }
12203
12204    @Override
12205    public boolean isImmersive(IBinder token) {
12206        synchronized (this) {
12207            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12208            if (r == null) {
12209                throw new IllegalArgumentException();
12210            }
12211            return r.immersive;
12212        }
12213    }
12214
12215    @Override
12216    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12217        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12218            throw new UnsupportedOperationException("VR mode not supported on this device!");
12219        }
12220
12221        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12222
12223        ActivityRecord r;
12224        synchronized (this) {
12225            r = ActivityRecord.isInStackLocked(token);
12226        }
12227
12228        if (r == null) {
12229            throw new IllegalArgumentException();
12230        }
12231
12232        int err;
12233        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12234                VrManagerInternal.NO_ERROR) {
12235            return err;
12236        }
12237
12238        synchronized(this) {
12239            r.requestedVrComponent = (enabled) ? packageName : null;
12240
12241            // Update associated state if this activity is currently focused
12242            if (r == mFocusedActivity) {
12243                applyUpdateVrModeLocked(r);
12244            }
12245            return 0;
12246        }
12247    }
12248
12249    @Override
12250    public boolean isVrModePackageEnabled(ComponentName packageName) {
12251        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12252            throw new UnsupportedOperationException("VR mode not supported on this device!");
12253        }
12254
12255        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12256
12257        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12258                VrManagerInternal.NO_ERROR;
12259    }
12260
12261    public boolean isTopActivityImmersive() {
12262        enforceNotIsolatedCaller("startActivity");
12263        synchronized (this) {
12264            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12265            return (r != null) ? r.immersive : false;
12266        }
12267    }
12268
12269    @Override
12270    public boolean isTopOfTask(IBinder token) {
12271        synchronized (this) {
12272            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12273            if (r == null) {
12274                throw new IllegalArgumentException();
12275            }
12276            return r.task.getTopActivity() == r;
12277        }
12278    }
12279
12280    public final void enterSafeMode() {
12281        synchronized(this) {
12282            // It only makes sense to do this before the system is ready
12283            // and started launching other packages.
12284            if (!mSystemReady) {
12285                try {
12286                    AppGlobals.getPackageManager().enterSafeMode();
12287                } catch (RemoteException e) {
12288                }
12289            }
12290
12291            mSafeMode = true;
12292        }
12293    }
12294
12295    public final void showSafeModeOverlay() {
12296        View v = LayoutInflater.from(mContext).inflate(
12297                com.android.internal.R.layout.safe_mode, null);
12298        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12299        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12300        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12301        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12302        lp.gravity = Gravity.BOTTOM | Gravity.START;
12303        lp.format = v.getBackground().getOpacity();
12304        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12305                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12306        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12307        ((WindowManager)mContext.getSystemService(
12308                Context.WINDOW_SERVICE)).addView(v, lp);
12309    }
12310
12311    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, 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            if (mBatteryStatsService.isOnBattery()) {
12319                mBatteryStatsService.enforceCallingPermission();
12320                int MY_UID = Binder.getCallingUid();
12321                final int uid;
12322                if (sender == null) {
12323                    uid = sourceUid;
12324                } else {
12325                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12326                }
12327                BatteryStatsImpl.Uid.Pkg pkg =
12328                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12329                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12330                pkg.noteWakeupAlarmLocked(tag);
12331            }
12332        }
12333    }
12334
12335    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12336        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12337            return;
12338        }
12339        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12340        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12341        synchronized (stats) {
12342            mBatteryStatsService.enforceCallingPermission();
12343            int MY_UID = Binder.getCallingUid();
12344            final int uid;
12345            if (sender == null) {
12346                uid = sourceUid;
12347            } else {
12348                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12349            }
12350            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12351        }
12352    }
12353
12354    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12355        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12356            return;
12357        }
12358        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12359        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12360        synchronized (stats) {
12361            mBatteryStatsService.enforceCallingPermission();
12362            int MY_UID = Binder.getCallingUid();
12363            final int uid;
12364            if (sender == null) {
12365                uid = sourceUid;
12366            } else {
12367                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12368            }
12369            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12370        }
12371    }
12372
12373    public boolean killPids(int[] pids, String pReason, boolean secure) {
12374        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12375            throw new SecurityException("killPids only available to the system");
12376        }
12377        String reason = (pReason == null) ? "Unknown" : pReason;
12378        // XXX Note: don't acquire main activity lock here, because the window
12379        // manager calls in with its locks held.
12380
12381        boolean killed = false;
12382        synchronized (mPidsSelfLocked) {
12383            int worstType = 0;
12384            for (int i=0; i<pids.length; i++) {
12385                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12386                if (proc != null) {
12387                    int type = proc.setAdj;
12388                    if (type > worstType) {
12389                        worstType = type;
12390                    }
12391                }
12392            }
12393
12394            // If the worst oom_adj is somewhere in the cached proc LRU range,
12395            // then constrain it so we will kill all cached procs.
12396            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12397                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12398                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12399            }
12400
12401            // If this is not a secure call, don't let it kill processes that
12402            // are important.
12403            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12404                worstType = ProcessList.SERVICE_ADJ;
12405            }
12406
12407            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12408            for (int i=0; i<pids.length; i++) {
12409                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12410                if (proc == null) {
12411                    continue;
12412                }
12413                int adj = proc.setAdj;
12414                if (adj >= worstType && !proc.killedByAm) {
12415                    proc.kill(reason, true);
12416                    killed = true;
12417                }
12418            }
12419        }
12420        return killed;
12421    }
12422
12423    @Override
12424    public void killUid(int appId, int userId, String reason) {
12425        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12426        synchronized (this) {
12427            final long identity = Binder.clearCallingIdentity();
12428            try {
12429                killPackageProcessesLocked(null, appId, userId,
12430                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12431                        reason != null ? reason : "kill uid");
12432            } finally {
12433                Binder.restoreCallingIdentity(identity);
12434            }
12435        }
12436    }
12437
12438    @Override
12439    public boolean killProcessesBelowForeground(String reason) {
12440        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12441            throw new SecurityException("killProcessesBelowForeground() only available to system");
12442        }
12443
12444        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12445    }
12446
12447    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12448        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12449            throw new SecurityException("killProcessesBelowAdj() only available to system");
12450        }
12451
12452        boolean killed = false;
12453        synchronized (mPidsSelfLocked) {
12454            final int size = mPidsSelfLocked.size();
12455            for (int i = 0; i < size; i++) {
12456                final int pid = mPidsSelfLocked.keyAt(i);
12457                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12458                if (proc == null) continue;
12459
12460                final int adj = proc.setAdj;
12461                if (adj > belowAdj && !proc.killedByAm) {
12462                    proc.kill(reason, true);
12463                    killed = true;
12464                }
12465            }
12466        }
12467        return killed;
12468    }
12469
12470    @Override
12471    public void hang(final IBinder who, boolean allowRestart) {
12472        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12473                != PackageManager.PERMISSION_GRANTED) {
12474            throw new SecurityException("Requires permission "
12475                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12476        }
12477
12478        final IBinder.DeathRecipient death = new DeathRecipient() {
12479            @Override
12480            public void binderDied() {
12481                synchronized (this) {
12482                    notifyAll();
12483                }
12484            }
12485        };
12486
12487        try {
12488            who.linkToDeath(death, 0);
12489        } catch (RemoteException e) {
12490            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12491            return;
12492        }
12493
12494        synchronized (this) {
12495            Watchdog.getInstance().setAllowRestart(allowRestart);
12496            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12497            synchronized (death) {
12498                while (who.isBinderAlive()) {
12499                    try {
12500                        death.wait();
12501                    } catch (InterruptedException e) {
12502                    }
12503                }
12504            }
12505            Watchdog.getInstance().setAllowRestart(true);
12506        }
12507    }
12508
12509    @Override
12510    public void restart() {
12511        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12512                != PackageManager.PERMISSION_GRANTED) {
12513            throw new SecurityException("Requires permission "
12514                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12515        }
12516
12517        Log.i(TAG, "Sending shutdown broadcast...");
12518
12519        BroadcastReceiver br = new BroadcastReceiver() {
12520            @Override public void onReceive(Context context, Intent intent) {
12521                // Now the broadcast is done, finish up the low-level shutdown.
12522                Log.i(TAG, "Shutting down activity manager...");
12523                shutdown(10000);
12524                Log.i(TAG, "Shutdown complete, restarting!");
12525                Process.killProcess(Process.myPid());
12526                System.exit(10);
12527            }
12528        };
12529
12530        // First send the high-level shut down broadcast.
12531        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12532        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12533        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12534        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12535        mContext.sendOrderedBroadcastAsUser(intent,
12536                UserHandle.ALL, null, br, mHandler, 0, null, null);
12537        */
12538        br.onReceive(mContext, intent);
12539    }
12540
12541    private long getLowRamTimeSinceIdle(long now) {
12542        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12543    }
12544
12545    @Override
12546    public void performIdleMaintenance() {
12547        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12548                != PackageManager.PERMISSION_GRANTED) {
12549            throw new SecurityException("Requires permission "
12550                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12551        }
12552
12553        synchronized (this) {
12554            final long now = SystemClock.uptimeMillis();
12555            final long timeSinceLastIdle = now - mLastIdleTime;
12556            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12557            mLastIdleTime = now;
12558            mLowRamTimeSinceLastIdle = 0;
12559            if (mLowRamStartTime != 0) {
12560                mLowRamStartTime = now;
12561            }
12562
12563            StringBuilder sb = new StringBuilder(128);
12564            sb.append("Idle maintenance over ");
12565            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12566            sb.append(" low RAM for ");
12567            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12568            Slog.i(TAG, sb.toString());
12569
12570            // If at least 1/3 of our time since the last idle period has been spent
12571            // with RAM low, then we want to kill processes.
12572            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12573
12574            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12575                ProcessRecord proc = mLruProcesses.get(i);
12576                if (proc.notCachedSinceIdle) {
12577                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12578                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12579                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12580                        if (doKilling && proc.initialIdlePss != 0
12581                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12582                            sb = new StringBuilder(128);
12583                            sb.append("Kill");
12584                            sb.append(proc.processName);
12585                            sb.append(" in idle maint: pss=");
12586                            sb.append(proc.lastPss);
12587                            sb.append(", swapPss=");
12588                            sb.append(proc.lastSwapPss);
12589                            sb.append(", initialPss=");
12590                            sb.append(proc.initialIdlePss);
12591                            sb.append(", period=");
12592                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12593                            sb.append(", lowRamPeriod=");
12594                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12595                            Slog.wtfQuiet(TAG, sb.toString());
12596                            proc.kill("idle maint (pss " + proc.lastPss
12597                                    + " from " + proc.initialIdlePss + ")", true);
12598                        }
12599                    }
12600                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12601                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12602                    proc.notCachedSinceIdle = true;
12603                    proc.initialIdlePss = 0;
12604                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12605                            mTestPssMode, isSleeping(), now);
12606                }
12607            }
12608
12609            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12610            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12611        }
12612    }
12613
12614    private void retrieveSettings() {
12615        final ContentResolver resolver = mContext.getContentResolver();
12616        final boolean freeformWindowManagement =
12617                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12618                        || Settings.Global.getInt(
12619                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12620        final boolean supportsPictureInPicture =
12621                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12622
12623        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12624        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12625        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12626        final boolean alwaysFinishActivities =
12627                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12628        final boolean lenientBackgroundCheck =
12629                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12630        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12631        final boolean forceResizable = Settings.Global.getInt(
12632                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12633        // Transfer any global setting for forcing RTL layout, into a System Property
12634        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12635
12636        final Configuration configuration = new Configuration();
12637        Settings.System.getConfiguration(resolver, configuration);
12638        if (forceRtl) {
12639            // This will take care of setting the correct layout direction flags
12640            configuration.setLayoutDirection(configuration.locale);
12641        }
12642
12643        synchronized (this) {
12644            mDebugApp = mOrigDebugApp = debugApp;
12645            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12646            mAlwaysFinishActivities = alwaysFinishActivities;
12647            mLenientBackgroundCheck = lenientBackgroundCheck;
12648            mForceResizableActivities = forceResizable;
12649            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12650            if (supportsMultiWindow || forceResizable) {
12651                mSupportsMultiWindow = true;
12652                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12653                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12654            } else {
12655                mSupportsMultiWindow = false;
12656                mSupportsFreeformWindowManagement = false;
12657                mSupportsPictureInPicture = false;
12658            }
12659            // This happens before any activities are started, so we can
12660            // change mConfiguration in-place.
12661            updateConfigurationLocked(configuration, null, true);
12662            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12663                    "Initial config: " + mConfiguration);
12664
12665            // Load resources only after the current configuration has been set.
12666            final Resources res = mContext.getResources();
12667            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12668            mThumbnailWidth = res.getDimensionPixelSize(
12669                    com.android.internal.R.dimen.thumbnail_width);
12670            mThumbnailHeight = res.getDimensionPixelSize(
12671                    com.android.internal.R.dimen.thumbnail_height);
12672            mFullscreenThumbnailScale = res.getFraction(
12673                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12674            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12675                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12676            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12677                    com.android.internal.R.string.config_appsNotReportingCrashes));
12678        }
12679    }
12680
12681    public boolean testIsSystemReady() {
12682        // no need to synchronize(this) just to read & return the value
12683        return mSystemReady;
12684    }
12685
12686    public void systemReady(final Runnable goingCallback) {
12687        synchronized(this) {
12688            if (mSystemReady) {
12689                // If we're done calling all the receivers, run the next "boot phase" passed in
12690                // by the SystemServer
12691                if (goingCallback != null) {
12692                    goingCallback.run();
12693                }
12694                return;
12695            }
12696
12697            mLocalDeviceIdleController
12698                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12699
12700            // Make sure we have the current profile info, since it is needed for security checks.
12701            mUserController.onSystemReady();
12702            mRecentTasks.onSystemReadyLocked();
12703            mAppOpsService.systemReady();
12704            mSystemReady = true;
12705        }
12706
12707        ArrayList<ProcessRecord> procsToKill = null;
12708        synchronized(mPidsSelfLocked) {
12709            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12710                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12711                if (!isAllowedWhileBooting(proc.info)){
12712                    if (procsToKill == null) {
12713                        procsToKill = new ArrayList<ProcessRecord>();
12714                    }
12715                    procsToKill.add(proc);
12716                }
12717            }
12718        }
12719
12720        synchronized(this) {
12721            if (procsToKill != null) {
12722                for (int i=procsToKill.size()-1; i>=0; i--) {
12723                    ProcessRecord proc = procsToKill.get(i);
12724                    Slog.i(TAG, "Removing system update proc: " + proc);
12725                    removeProcessLocked(proc, true, false, "system update done");
12726                }
12727            }
12728
12729            // Now that we have cleaned up any update processes, we
12730            // are ready to start launching real processes and know that
12731            // we won't trample on them any more.
12732            mProcessesReady = true;
12733        }
12734
12735        Slog.i(TAG, "System now ready");
12736        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12737            SystemClock.uptimeMillis());
12738
12739        synchronized(this) {
12740            // Make sure we have no pre-ready processes sitting around.
12741
12742            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12743                ResolveInfo ri = mContext.getPackageManager()
12744                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12745                                STOCK_PM_FLAGS);
12746                CharSequence errorMsg = null;
12747                if (ri != null) {
12748                    ActivityInfo ai = ri.activityInfo;
12749                    ApplicationInfo app = ai.applicationInfo;
12750                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12751                        mTopAction = Intent.ACTION_FACTORY_TEST;
12752                        mTopData = null;
12753                        mTopComponent = new ComponentName(app.packageName,
12754                                ai.name);
12755                    } else {
12756                        errorMsg = mContext.getResources().getText(
12757                                com.android.internal.R.string.factorytest_not_system);
12758                    }
12759                } else {
12760                    errorMsg = mContext.getResources().getText(
12761                            com.android.internal.R.string.factorytest_no_action);
12762                }
12763                if (errorMsg != null) {
12764                    mTopAction = null;
12765                    mTopData = null;
12766                    mTopComponent = null;
12767                    Message msg = Message.obtain();
12768                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12769                    msg.getData().putCharSequence("msg", errorMsg);
12770                    mUiHandler.sendMessage(msg);
12771                }
12772            }
12773        }
12774
12775        retrieveSettings();
12776        final int currentUserId;
12777        synchronized (this) {
12778            currentUserId = mUserController.getCurrentUserIdLocked();
12779            readGrantedUriPermissionsLocked();
12780        }
12781
12782        if (goingCallback != null) goingCallback.run();
12783
12784        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12785                Integer.toString(currentUserId), currentUserId);
12786        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12787                Integer.toString(currentUserId), currentUserId);
12788        mSystemServiceManager.startUser(currentUserId);
12789
12790        synchronized (this) {
12791            // Only start up encryption-aware persistent apps; once user is
12792            // unlocked we'll come back around and start unaware apps
12793            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12794
12795            // Start up initial activity.
12796            mBooting = true;
12797            // Enable home activity for system user, so that the system can always boot
12798            if (UserManager.isSplitSystemUser()) {
12799                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12800                try {
12801                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12802                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12803                            UserHandle.USER_SYSTEM);
12804                } catch (RemoteException e) {
12805                    throw e.rethrowAsRuntimeException();
12806                }
12807            }
12808            startHomeActivityLocked(currentUserId, "systemReady");
12809
12810            try {
12811                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12812                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12813                            + " data partition or your device will be unstable.");
12814                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12815                }
12816            } catch (RemoteException e) {
12817            }
12818
12819            if (!Build.isBuildConsistent()) {
12820                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12821                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12822            }
12823
12824            long ident = Binder.clearCallingIdentity();
12825            try {
12826                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12827                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12828                        | Intent.FLAG_RECEIVER_FOREGROUND);
12829                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12830                broadcastIntentLocked(null, null, intent,
12831                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12832                        null, false, false, MY_PID, Process.SYSTEM_UID,
12833                        currentUserId);
12834                intent = new Intent(Intent.ACTION_USER_STARTING);
12835                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12836                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12837                broadcastIntentLocked(null, null, intent,
12838                        null, new IIntentReceiver.Stub() {
12839                            @Override
12840                            public void performReceive(Intent intent, int resultCode, String data,
12841                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12842                                    throws RemoteException {
12843                            }
12844                        }, 0, null, null,
12845                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12846                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12847            } catch (Throwable t) {
12848                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12849            } finally {
12850                Binder.restoreCallingIdentity(ident);
12851            }
12852            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12853            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12854        }
12855    }
12856
12857    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12858        synchronized (this) {
12859            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12860        }
12861    }
12862
12863    void skipCurrentReceiverLocked(ProcessRecord app) {
12864        for (BroadcastQueue queue : mBroadcastQueues) {
12865            queue.skipCurrentReceiverLocked(app);
12866        }
12867    }
12868
12869    /**
12870     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12871     * The application process will exit immediately after this call returns.
12872     * @param app object of the crashing app, null for the system server
12873     * @param crashInfo describing the exception
12874     */
12875    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12876        ProcessRecord r = findAppProcess(app, "Crash");
12877        final String processName = app == null ? "system_server"
12878                : (r == null ? "unknown" : r.processName);
12879
12880        handleApplicationCrashInner("crash", r, processName, crashInfo);
12881    }
12882
12883    /* Native crash reporting uses this inner version because it needs to be somewhat
12884     * decoupled from the AM-managed cleanup lifecycle
12885     */
12886    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12887            ApplicationErrorReport.CrashInfo crashInfo) {
12888        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12889                UserHandle.getUserId(Binder.getCallingUid()), processName,
12890                r == null ? -1 : r.info.flags,
12891                crashInfo.exceptionClassName,
12892                crashInfo.exceptionMessage,
12893                crashInfo.throwFileName,
12894                crashInfo.throwLineNumber);
12895
12896        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12897
12898        mAppErrors.crashApplication(r, crashInfo);
12899    }
12900
12901    public void handleApplicationStrictModeViolation(
12902            IBinder app,
12903            int violationMask,
12904            StrictMode.ViolationInfo info) {
12905        ProcessRecord r = findAppProcess(app, "StrictMode");
12906        if (r == null) {
12907            return;
12908        }
12909
12910        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12911            Integer stackFingerprint = info.hashCode();
12912            boolean logIt = true;
12913            synchronized (mAlreadyLoggedViolatedStacks) {
12914                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12915                    logIt = false;
12916                    // TODO: sub-sample into EventLog for these, with
12917                    // the info.durationMillis?  Then we'd get
12918                    // the relative pain numbers, without logging all
12919                    // the stack traces repeatedly.  We'd want to do
12920                    // likewise in the client code, which also does
12921                    // dup suppression, before the Binder call.
12922                } else {
12923                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12924                        mAlreadyLoggedViolatedStacks.clear();
12925                    }
12926                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12927                }
12928            }
12929            if (logIt) {
12930                logStrictModeViolationToDropBox(r, info);
12931            }
12932        }
12933
12934        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12935            AppErrorResult result = new AppErrorResult();
12936            synchronized (this) {
12937                final long origId = Binder.clearCallingIdentity();
12938
12939                Message msg = Message.obtain();
12940                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12941                HashMap<String, Object> data = new HashMap<String, Object>();
12942                data.put("result", result);
12943                data.put("app", r);
12944                data.put("violationMask", violationMask);
12945                data.put("info", info);
12946                msg.obj = data;
12947                mUiHandler.sendMessage(msg);
12948
12949                Binder.restoreCallingIdentity(origId);
12950            }
12951            int res = result.get();
12952            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12953        }
12954    }
12955
12956    // Depending on the policy in effect, there could be a bunch of
12957    // these in quick succession so we try to batch these together to
12958    // minimize disk writes, number of dropbox entries, and maximize
12959    // compression, by having more fewer, larger records.
12960    private void logStrictModeViolationToDropBox(
12961            ProcessRecord process,
12962            StrictMode.ViolationInfo info) {
12963        if (info == null) {
12964            return;
12965        }
12966        final boolean isSystemApp = process == null ||
12967                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12968                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12969        final String processName = process == null ? "unknown" : process.processName;
12970        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12971        final DropBoxManager dbox = (DropBoxManager)
12972                mContext.getSystemService(Context.DROPBOX_SERVICE);
12973
12974        // Exit early if the dropbox isn't configured to accept this report type.
12975        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12976
12977        boolean bufferWasEmpty;
12978        boolean needsFlush;
12979        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12980        synchronized (sb) {
12981            bufferWasEmpty = sb.length() == 0;
12982            appendDropBoxProcessHeaders(process, processName, sb);
12983            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12984            sb.append("System-App: ").append(isSystemApp).append("\n");
12985            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12986            if (info.violationNumThisLoop != 0) {
12987                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12988            }
12989            if (info.numAnimationsRunning != 0) {
12990                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12991            }
12992            if (info.broadcastIntentAction != null) {
12993                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12994            }
12995            if (info.durationMillis != -1) {
12996                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12997            }
12998            if (info.numInstances != -1) {
12999                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13000            }
13001            if (info.tags != null) {
13002                for (String tag : info.tags) {
13003                    sb.append("Span-Tag: ").append(tag).append("\n");
13004                }
13005            }
13006            sb.append("\n");
13007            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13008                sb.append(info.crashInfo.stackTrace);
13009                sb.append("\n");
13010            }
13011            if (info.message != null) {
13012                sb.append(info.message);
13013                sb.append("\n");
13014            }
13015
13016            // Only buffer up to ~64k.  Various logging bits truncate
13017            // things at 128k.
13018            needsFlush = (sb.length() > 64 * 1024);
13019        }
13020
13021        // Flush immediately if the buffer's grown too large, or this
13022        // is a non-system app.  Non-system apps are isolated with a
13023        // different tag & policy and not batched.
13024        //
13025        // Batching is useful during internal testing with
13026        // StrictMode settings turned up high.  Without batching,
13027        // thousands of separate files could be created on boot.
13028        if (!isSystemApp || needsFlush) {
13029            new Thread("Error dump: " + dropboxTag) {
13030                @Override
13031                public void run() {
13032                    String report;
13033                    synchronized (sb) {
13034                        report = sb.toString();
13035                        sb.delete(0, sb.length());
13036                        sb.trimToSize();
13037                    }
13038                    if (report.length() != 0) {
13039                        dbox.addText(dropboxTag, report);
13040                    }
13041                }
13042            }.start();
13043            return;
13044        }
13045
13046        // System app batching:
13047        if (!bufferWasEmpty) {
13048            // An existing dropbox-writing thread is outstanding, so
13049            // we don't need to start it up.  The existing thread will
13050            // catch the buffer appends we just did.
13051            return;
13052        }
13053
13054        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13055        // (After this point, we shouldn't access AMS internal data structures.)
13056        new Thread("Error dump: " + dropboxTag) {
13057            @Override
13058            public void run() {
13059                // 5 second sleep to let stacks arrive and be batched together
13060                try {
13061                    Thread.sleep(5000);  // 5 seconds
13062                } catch (InterruptedException e) {}
13063
13064                String errorReport;
13065                synchronized (mStrictModeBuffer) {
13066                    errorReport = mStrictModeBuffer.toString();
13067                    if (errorReport.length() == 0) {
13068                        return;
13069                    }
13070                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13071                    mStrictModeBuffer.trimToSize();
13072                }
13073                dbox.addText(dropboxTag, errorReport);
13074            }
13075        }.start();
13076    }
13077
13078    /**
13079     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13080     * @param app object of the crashing app, null for the system server
13081     * @param tag reported by the caller
13082     * @param system whether this wtf is coming from the system
13083     * @param crashInfo describing the context of the error
13084     * @return true if the process should exit immediately (WTF is fatal)
13085     */
13086    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13087            final ApplicationErrorReport.CrashInfo crashInfo) {
13088        final int callingUid = Binder.getCallingUid();
13089        final int callingPid = Binder.getCallingPid();
13090
13091        if (system) {
13092            // If this is coming from the system, we could very well have low-level
13093            // system locks held, so we want to do this all asynchronously.  And we
13094            // never want this to become fatal, so there is that too.
13095            mHandler.post(new Runnable() {
13096                @Override public void run() {
13097                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13098                }
13099            });
13100            return false;
13101        }
13102
13103        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13104                crashInfo);
13105
13106        if (r != null && r.pid != Process.myPid() &&
13107                Settings.Global.getInt(mContext.getContentResolver(),
13108                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13109            mAppErrors.crashApplication(r, crashInfo);
13110            return true;
13111        } else {
13112            return false;
13113        }
13114    }
13115
13116    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13117            final ApplicationErrorReport.CrashInfo crashInfo) {
13118        final ProcessRecord r = findAppProcess(app, "WTF");
13119        final String processName = app == null ? "system_server"
13120                : (r == null ? "unknown" : r.processName);
13121
13122        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13123                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13124
13125        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13126
13127        return r;
13128    }
13129
13130    /**
13131     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13132     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13133     */
13134    private ProcessRecord findAppProcess(IBinder app, String reason) {
13135        if (app == null) {
13136            return null;
13137        }
13138
13139        synchronized (this) {
13140            final int NP = mProcessNames.getMap().size();
13141            for (int ip=0; ip<NP; ip++) {
13142                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13143                final int NA = apps.size();
13144                for (int ia=0; ia<NA; ia++) {
13145                    ProcessRecord p = apps.valueAt(ia);
13146                    if (p.thread != null && p.thread.asBinder() == app) {
13147                        return p;
13148                    }
13149                }
13150            }
13151
13152            Slog.w(TAG, "Can't find mystery application for " + reason
13153                    + " from pid=" + Binder.getCallingPid()
13154                    + " uid=" + Binder.getCallingUid() + ": " + app);
13155            return null;
13156        }
13157    }
13158
13159    /**
13160     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13161     * to append various headers to the dropbox log text.
13162     */
13163    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13164            StringBuilder sb) {
13165        // Watchdog thread ends up invoking this function (with
13166        // a null ProcessRecord) to add the stack file to dropbox.
13167        // Do not acquire a lock on this (am) in such cases, as it
13168        // could cause a potential deadlock, if and when watchdog
13169        // is invoked due to unavailability of lock on am and it
13170        // would prevent watchdog from killing system_server.
13171        if (process == null) {
13172            sb.append("Process: ").append(processName).append("\n");
13173            return;
13174        }
13175        // Note: ProcessRecord 'process' is guarded by the service
13176        // instance.  (notably process.pkgList, which could otherwise change
13177        // concurrently during execution of this method)
13178        synchronized (this) {
13179            sb.append("Process: ").append(processName).append("\n");
13180            int flags = process.info.flags;
13181            IPackageManager pm = AppGlobals.getPackageManager();
13182            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13183            for (int ip=0; ip<process.pkgList.size(); ip++) {
13184                String pkg = process.pkgList.keyAt(ip);
13185                sb.append("Package: ").append(pkg);
13186                try {
13187                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13188                    if (pi != null) {
13189                        sb.append(" v").append(pi.versionCode);
13190                        if (pi.versionName != null) {
13191                            sb.append(" (").append(pi.versionName).append(")");
13192                        }
13193                    }
13194                } catch (RemoteException e) {
13195                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13196                }
13197                sb.append("\n");
13198            }
13199        }
13200    }
13201
13202    private static String processClass(ProcessRecord process) {
13203        if (process == null || process.pid == MY_PID) {
13204            return "system_server";
13205        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13206            return "system_app";
13207        } else {
13208            return "data_app";
13209        }
13210    }
13211
13212    private volatile long mWtfClusterStart;
13213    private volatile int mWtfClusterCount;
13214
13215    /**
13216     * Write a description of an error (crash, WTF, ANR) to the drop box.
13217     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13218     * @param process which caused the error, null means the system server
13219     * @param activity which triggered the error, null if unknown
13220     * @param parent activity related to the error, null if unknown
13221     * @param subject line related to the error, null if absent
13222     * @param report in long form describing the error, null if absent
13223     * @param logFile to include in the report, null if none
13224     * @param crashInfo giving an application stack trace, null if absent
13225     */
13226    public void addErrorToDropBox(String eventType,
13227            ProcessRecord process, String processName, ActivityRecord activity,
13228            ActivityRecord parent, String subject,
13229            final String report, final File logFile,
13230            final ApplicationErrorReport.CrashInfo crashInfo) {
13231        // NOTE -- this must never acquire the ActivityManagerService lock,
13232        // otherwise the watchdog may be prevented from resetting the system.
13233
13234        final String dropboxTag = processClass(process) + "_" + eventType;
13235        final DropBoxManager dbox = (DropBoxManager)
13236                mContext.getSystemService(Context.DROPBOX_SERVICE);
13237
13238        // Exit early if the dropbox isn't configured to accept this report type.
13239        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13240
13241        // Rate-limit how often we're willing to do the heavy lifting below to
13242        // collect and record logs; currently 5 logs per 10 second period.
13243        final long now = SystemClock.elapsedRealtime();
13244        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13245            mWtfClusterStart = now;
13246            mWtfClusterCount = 1;
13247        } else {
13248            if (mWtfClusterCount++ >= 5) return;
13249        }
13250
13251        final StringBuilder sb = new StringBuilder(1024);
13252        appendDropBoxProcessHeaders(process, processName, sb);
13253        if (process != null) {
13254            sb.append("Foreground: ")
13255                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13256                    .append("\n");
13257        }
13258        if (activity != null) {
13259            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13260        }
13261        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13262            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13263        }
13264        if (parent != null && parent != activity) {
13265            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13266        }
13267        if (subject != null) {
13268            sb.append("Subject: ").append(subject).append("\n");
13269        }
13270        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13271        if (Debug.isDebuggerConnected()) {
13272            sb.append("Debugger: Connected\n");
13273        }
13274        sb.append("\n");
13275
13276        // Do the rest in a worker thread to avoid blocking the caller on I/O
13277        // (After this point, we shouldn't access AMS internal data structures.)
13278        Thread worker = new Thread("Error dump: " + dropboxTag) {
13279            @Override
13280            public void run() {
13281                if (report != null) {
13282                    sb.append(report);
13283                }
13284                if (logFile != null) {
13285                    try {
13286                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13287                                    "\n\n[[TRUNCATED]]"));
13288                    } catch (IOException e) {
13289                        Slog.e(TAG, "Error reading " + logFile, e);
13290                    }
13291                }
13292                if (crashInfo != null && crashInfo.stackTrace != null) {
13293                    sb.append(crashInfo.stackTrace);
13294                }
13295
13296                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13297                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13298                if (lines > 0) {
13299                    sb.append("\n");
13300
13301                    // Merge several logcat streams, and take the last N lines
13302                    InputStreamReader input = null;
13303                    try {
13304                        java.lang.Process logcat = new ProcessBuilder(
13305                                "/system/bin/timeout", "-k", "15s", "10s",
13306                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13307                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13308                                        .redirectErrorStream(true).start();
13309
13310                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13311                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13312                        input = new InputStreamReader(logcat.getInputStream());
13313
13314                        int num;
13315                        char[] buf = new char[8192];
13316                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13317                    } catch (IOException e) {
13318                        Slog.e(TAG, "Error running logcat", e);
13319                    } finally {
13320                        if (input != null) try { input.close(); } catch (IOException e) {}
13321                    }
13322                }
13323
13324                dbox.addText(dropboxTag, sb.toString());
13325            }
13326        };
13327
13328        if (process == null) {
13329            // If process is null, we are being called from some internal code
13330            // and may be about to die -- run this synchronously.
13331            worker.run();
13332        } else {
13333            worker.start();
13334        }
13335    }
13336
13337    @Override
13338    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13339        enforceNotIsolatedCaller("getProcessesInErrorState");
13340        // assume our apps are happy - lazy create the list
13341        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13342
13343        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13344                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13345        int userId = UserHandle.getUserId(Binder.getCallingUid());
13346
13347        synchronized (this) {
13348
13349            // iterate across all processes
13350            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13351                ProcessRecord app = mLruProcesses.get(i);
13352                if (!allUsers && app.userId != userId) {
13353                    continue;
13354                }
13355                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13356                    // This one's in trouble, so we'll generate a report for it
13357                    // crashes are higher priority (in case there's a crash *and* an anr)
13358                    ActivityManager.ProcessErrorStateInfo report = null;
13359                    if (app.crashing) {
13360                        report = app.crashingReport;
13361                    } else if (app.notResponding) {
13362                        report = app.notRespondingReport;
13363                    }
13364
13365                    if (report != null) {
13366                        if (errList == null) {
13367                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13368                        }
13369                        errList.add(report);
13370                    } else {
13371                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13372                                " crashing = " + app.crashing +
13373                                " notResponding = " + app.notResponding);
13374                    }
13375                }
13376            }
13377        }
13378
13379        return errList;
13380    }
13381
13382    static int procStateToImportance(int procState, int memAdj,
13383            ActivityManager.RunningAppProcessInfo currApp) {
13384        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13385        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13386            currApp.lru = memAdj;
13387        } else {
13388            currApp.lru = 0;
13389        }
13390        return imp;
13391    }
13392
13393    private void fillInProcMemInfo(ProcessRecord app,
13394            ActivityManager.RunningAppProcessInfo outInfo) {
13395        outInfo.pid = app.pid;
13396        outInfo.uid = app.info.uid;
13397        if (mHeavyWeightProcess == app) {
13398            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13399        }
13400        if (app.persistent) {
13401            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13402        }
13403        if (app.activities.size() > 0) {
13404            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13405        }
13406        outInfo.lastTrimLevel = app.trimMemoryLevel;
13407        int adj = app.curAdj;
13408        int procState = app.curProcState;
13409        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13410        outInfo.importanceReasonCode = app.adjTypeCode;
13411        outInfo.processState = app.curProcState;
13412    }
13413
13414    @Override
13415    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13416        enforceNotIsolatedCaller("getRunningAppProcesses");
13417
13418        final int callingUid = Binder.getCallingUid();
13419
13420        // Lazy instantiation of list
13421        List<ActivityManager.RunningAppProcessInfo> runList = null;
13422        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13423                callingUid) == PackageManager.PERMISSION_GRANTED;
13424        final int userId = UserHandle.getUserId(callingUid);
13425        final boolean allUids = isGetTasksAllowed(
13426                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13427
13428        synchronized (this) {
13429            // Iterate across all processes
13430            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13431                ProcessRecord app = mLruProcesses.get(i);
13432                if ((!allUsers && app.userId != userId)
13433                        || (!allUids && app.uid != callingUid)) {
13434                    continue;
13435                }
13436                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13437                    // Generate process state info for running application
13438                    ActivityManager.RunningAppProcessInfo currApp =
13439                        new ActivityManager.RunningAppProcessInfo(app.processName,
13440                                app.pid, app.getPackageList());
13441                    fillInProcMemInfo(app, currApp);
13442                    if (app.adjSource instanceof ProcessRecord) {
13443                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13444                        currApp.importanceReasonImportance =
13445                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13446                                        app.adjSourceProcState);
13447                    } else if (app.adjSource instanceof ActivityRecord) {
13448                        ActivityRecord r = (ActivityRecord)app.adjSource;
13449                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13450                    }
13451                    if (app.adjTarget instanceof ComponentName) {
13452                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13453                    }
13454                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13455                    //        + " lru=" + currApp.lru);
13456                    if (runList == null) {
13457                        runList = new ArrayList<>();
13458                    }
13459                    runList.add(currApp);
13460                }
13461            }
13462        }
13463        return runList;
13464    }
13465
13466    @Override
13467    public List<ApplicationInfo> getRunningExternalApplications() {
13468        enforceNotIsolatedCaller("getRunningExternalApplications");
13469        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13470        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13471        if (runningApps != null && runningApps.size() > 0) {
13472            Set<String> extList = new HashSet<String>();
13473            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13474                if (app.pkgList != null) {
13475                    for (String pkg : app.pkgList) {
13476                        extList.add(pkg);
13477                    }
13478                }
13479            }
13480            IPackageManager pm = AppGlobals.getPackageManager();
13481            for (String pkg : extList) {
13482                try {
13483                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13484                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13485                        retList.add(info);
13486                    }
13487                } catch (RemoteException e) {
13488                }
13489            }
13490        }
13491        return retList;
13492    }
13493
13494    @Override
13495    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13496        enforceNotIsolatedCaller("getMyMemoryState");
13497        synchronized (this) {
13498            ProcessRecord proc;
13499            synchronized (mPidsSelfLocked) {
13500                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13501            }
13502            fillInProcMemInfo(proc, outInfo);
13503        }
13504    }
13505
13506    @Override
13507    public int getMemoryTrimLevel() {
13508        enforceNotIsolatedCaller("getMyMemoryState");
13509        synchronized (this) {
13510            return mLastMemoryLevel;
13511        }
13512    }
13513
13514    @Override
13515    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13516            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13517        (new ActivityManagerShellCommand(this, false)).exec(
13518                this, in, out, err, args, resultReceiver);
13519    }
13520
13521    @Override
13522    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13523        if (checkCallingPermission(android.Manifest.permission.DUMP)
13524                != PackageManager.PERMISSION_GRANTED) {
13525            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13526                    + Binder.getCallingPid()
13527                    + ", uid=" + Binder.getCallingUid()
13528                    + " without permission "
13529                    + android.Manifest.permission.DUMP);
13530            return;
13531        }
13532
13533        boolean dumpAll = false;
13534        boolean dumpClient = false;
13535        String dumpPackage = null;
13536
13537        int opti = 0;
13538        while (opti < args.length) {
13539            String opt = args[opti];
13540            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13541                break;
13542            }
13543            opti++;
13544            if ("-a".equals(opt)) {
13545                dumpAll = true;
13546            } else if ("-c".equals(opt)) {
13547                dumpClient = true;
13548            } else if ("-p".equals(opt)) {
13549                if (opti < args.length) {
13550                    dumpPackage = args[opti];
13551                    opti++;
13552                } else {
13553                    pw.println("Error: -p option requires package argument");
13554                    return;
13555                }
13556                dumpClient = true;
13557            } else if ("-h".equals(opt)) {
13558                ActivityManagerShellCommand.dumpHelp(pw, true);
13559                return;
13560            } else {
13561                pw.println("Unknown argument: " + opt + "; use -h for help");
13562            }
13563        }
13564
13565        long origId = Binder.clearCallingIdentity();
13566        boolean more = false;
13567        // Is the caller requesting to dump a particular piece of data?
13568        if (opti < args.length) {
13569            String cmd = args[opti];
13570            opti++;
13571            if ("activities".equals(cmd) || "a".equals(cmd)) {
13572                synchronized (this) {
13573                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13574                }
13575            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13576                synchronized (this) {
13577                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13578                }
13579            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13580                String[] newArgs;
13581                String name;
13582                if (opti >= args.length) {
13583                    name = null;
13584                    newArgs = EMPTY_STRING_ARRAY;
13585                } else {
13586                    dumpPackage = args[opti];
13587                    opti++;
13588                    newArgs = new String[args.length - opti];
13589                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13590                            args.length - opti);
13591                }
13592                synchronized (this) {
13593                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13594                }
13595            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13596                String[] newArgs;
13597                String name;
13598                if (opti >= args.length) {
13599                    name = null;
13600                    newArgs = EMPTY_STRING_ARRAY;
13601                } else {
13602                    dumpPackage = args[opti];
13603                    opti++;
13604                    newArgs = new String[args.length - opti];
13605                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13606                            args.length - opti);
13607                }
13608                synchronized (this) {
13609                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13610                }
13611            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13612                String[] newArgs;
13613                String name;
13614                if (opti >= args.length) {
13615                    name = null;
13616                    newArgs = EMPTY_STRING_ARRAY;
13617                } else {
13618                    dumpPackage = args[opti];
13619                    opti++;
13620                    newArgs = new String[args.length - opti];
13621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13622                            args.length - opti);
13623                }
13624                synchronized (this) {
13625                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13626                }
13627            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13628                synchronized (this) {
13629                    dumpOomLocked(fd, pw, args, opti, true);
13630                }
13631            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13632                synchronized (this) {
13633                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13634                }
13635            } else if ("provider".equals(cmd)) {
13636                String[] newArgs;
13637                String name;
13638                if (opti >= args.length) {
13639                    name = null;
13640                    newArgs = EMPTY_STRING_ARRAY;
13641                } else {
13642                    name = args[opti];
13643                    opti++;
13644                    newArgs = new String[args.length - opti];
13645                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13646                }
13647                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13648                    pw.println("No providers match: " + name);
13649                    pw.println("Use -h for help.");
13650                }
13651            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13652                synchronized (this) {
13653                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13654                }
13655            } else if ("service".equals(cmd)) {
13656                String[] newArgs;
13657                String name;
13658                if (opti >= args.length) {
13659                    name = null;
13660                    newArgs = EMPTY_STRING_ARRAY;
13661                } else {
13662                    name = args[opti];
13663                    opti++;
13664                    newArgs = new String[args.length - opti];
13665                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13666                            args.length - opti);
13667                }
13668                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13669                    pw.println("No services match: " + name);
13670                    pw.println("Use -h for help.");
13671                }
13672            } else if ("package".equals(cmd)) {
13673                String[] newArgs;
13674                if (opti >= args.length) {
13675                    pw.println("package: no package name specified");
13676                    pw.println("Use -h for help.");
13677                } else {
13678                    dumpPackage = args[opti];
13679                    opti++;
13680                    newArgs = new String[args.length - opti];
13681                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13682                            args.length - opti);
13683                    args = newArgs;
13684                    opti = 0;
13685                    more = true;
13686                }
13687            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13688                synchronized (this) {
13689                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13690                }
13691            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13692                synchronized (this) {
13693                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13694                }
13695            } else if ("locks".equals(cmd)) {
13696                LockGuard.dump(fd, pw, args);
13697            } else {
13698                // Dumping a single activity?
13699                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13700                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13701                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13702                    if (res < 0) {
13703                        pw.println("Bad activity command, or no activities match: " + cmd);
13704                        pw.println("Use -h for help.");
13705                    }
13706                }
13707            }
13708            if (!more) {
13709                Binder.restoreCallingIdentity(origId);
13710                return;
13711            }
13712        }
13713
13714        // No piece of data specified, dump everything.
13715        synchronized (this) {
13716            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13717            pw.println();
13718            if (dumpAll) {
13719                pw.println("-------------------------------------------------------------------------------");
13720            }
13721            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13722            pw.println();
13723            if (dumpAll) {
13724                pw.println("-------------------------------------------------------------------------------");
13725            }
13726            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13727            pw.println();
13728            if (dumpAll) {
13729                pw.println("-------------------------------------------------------------------------------");
13730            }
13731            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13732            pw.println();
13733            if (dumpAll) {
13734                pw.println("-------------------------------------------------------------------------------");
13735            }
13736            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13737            pw.println();
13738            if (dumpAll) {
13739                pw.println("-------------------------------------------------------------------------------");
13740            }
13741            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13742            pw.println();
13743            if (dumpAll) {
13744                pw.println("-------------------------------------------------------------------------------");
13745            }
13746            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13747            if (mAssociations.size() > 0) {
13748                pw.println();
13749                if (dumpAll) {
13750                    pw.println("-------------------------------------------------------------------------------");
13751                }
13752                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13753            }
13754            pw.println();
13755            if (dumpAll) {
13756                pw.println("-------------------------------------------------------------------------------");
13757            }
13758            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13759        }
13760        Binder.restoreCallingIdentity(origId);
13761    }
13762
13763    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13764            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13765        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13766
13767        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13768                dumpPackage);
13769        boolean needSep = printedAnything;
13770
13771        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13772                dumpPackage, needSep, "  mFocusedActivity: ");
13773        if (printed) {
13774            printedAnything = true;
13775            needSep = false;
13776        }
13777
13778        if (dumpPackage == null) {
13779            if (needSep) {
13780                pw.println();
13781            }
13782            needSep = true;
13783            printedAnything = true;
13784            mStackSupervisor.dump(pw, "  ");
13785        }
13786
13787        if (!printedAnything) {
13788            pw.println("  (nothing)");
13789        }
13790    }
13791
13792    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13793            int opti, boolean dumpAll, String dumpPackage) {
13794        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13795
13796        boolean printedAnything = false;
13797
13798        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13799            boolean printedHeader = false;
13800
13801            final int N = mRecentTasks.size();
13802            for (int i=0; i<N; i++) {
13803                TaskRecord tr = mRecentTasks.get(i);
13804                if (dumpPackage != null) {
13805                    if (tr.realActivity == null ||
13806                            !dumpPackage.equals(tr.realActivity)) {
13807                        continue;
13808                    }
13809                }
13810                if (!printedHeader) {
13811                    pw.println("  Recent tasks:");
13812                    printedHeader = true;
13813                    printedAnything = true;
13814                }
13815                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13816                        pw.println(tr);
13817                if (dumpAll) {
13818                    mRecentTasks.get(i).dump(pw, "    ");
13819                }
13820            }
13821        }
13822
13823        if (!printedAnything) {
13824            pw.println("  (nothing)");
13825        }
13826    }
13827
13828    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13829            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13830        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13831
13832        int dumpUid = 0;
13833        if (dumpPackage != null) {
13834            IPackageManager pm = AppGlobals.getPackageManager();
13835            try {
13836                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13837            } catch (RemoteException e) {
13838            }
13839        }
13840
13841        boolean printedAnything = false;
13842
13843        final long now = SystemClock.uptimeMillis();
13844
13845        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13846            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13847                    = mAssociations.valueAt(i1);
13848            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13849                SparseArray<ArrayMap<String, Association>> sourceUids
13850                        = targetComponents.valueAt(i2);
13851                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13852                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13853                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13854                        Association ass = sourceProcesses.valueAt(i4);
13855                        if (dumpPackage != null) {
13856                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13857                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13858                                continue;
13859                            }
13860                        }
13861                        printedAnything = true;
13862                        pw.print("  ");
13863                        pw.print(ass.mTargetProcess);
13864                        pw.print("/");
13865                        UserHandle.formatUid(pw, ass.mTargetUid);
13866                        pw.print(" <- ");
13867                        pw.print(ass.mSourceProcess);
13868                        pw.print("/");
13869                        UserHandle.formatUid(pw, ass.mSourceUid);
13870                        pw.println();
13871                        pw.print("    via ");
13872                        pw.print(ass.mTargetComponent.flattenToShortString());
13873                        pw.println();
13874                        pw.print("    ");
13875                        long dur = ass.mTime;
13876                        if (ass.mNesting > 0) {
13877                            dur += now - ass.mStartTime;
13878                        }
13879                        TimeUtils.formatDuration(dur, pw);
13880                        pw.print(" (");
13881                        pw.print(ass.mCount);
13882                        pw.print(" times)");
13883                        pw.print("  ");
13884                        for (int i=0; i<ass.mStateTimes.length; i++) {
13885                            long amt = ass.mStateTimes[i];
13886                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13887                                amt += now - ass.mLastStateUptime;
13888                            }
13889                            if (amt != 0) {
13890                                pw.print(" ");
13891                                pw.print(ProcessList.makeProcStateString(
13892                                            i + ActivityManager.MIN_PROCESS_STATE));
13893                                pw.print("=");
13894                                TimeUtils.formatDuration(amt, pw);
13895                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13896                                    pw.print("*");
13897                                }
13898                            }
13899                        }
13900                        pw.println();
13901                        if (ass.mNesting > 0) {
13902                            pw.print("    Currently active: ");
13903                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13904                            pw.println();
13905                        }
13906                    }
13907                }
13908            }
13909
13910        }
13911
13912        if (!printedAnything) {
13913            pw.println("  (nothing)");
13914        }
13915    }
13916
13917    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13918            String header, boolean needSep) {
13919        boolean printed = false;
13920        int whichAppId = -1;
13921        if (dumpPackage != null) {
13922            try {
13923                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13924                        dumpPackage, 0);
13925                whichAppId = UserHandle.getAppId(info.uid);
13926            } catch (NameNotFoundException e) {
13927                e.printStackTrace();
13928            }
13929        }
13930        for (int i=0; i<uids.size(); i++) {
13931            UidRecord uidRec = uids.valueAt(i);
13932            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13933                continue;
13934            }
13935            if (!printed) {
13936                printed = true;
13937                if (needSep) {
13938                    pw.println();
13939                }
13940                pw.print("  ");
13941                pw.println(header);
13942                needSep = true;
13943            }
13944            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13945            pw.print(": "); pw.println(uidRec);
13946        }
13947        return printed;
13948    }
13949
13950    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13951            int opti, boolean dumpAll, String dumpPackage) {
13952        boolean needSep = false;
13953        boolean printedAnything = false;
13954        int numPers = 0;
13955
13956        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13957
13958        if (dumpAll) {
13959            final int NP = mProcessNames.getMap().size();
13960            for (int ip=0; ip<NP; ip++) {
13961                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13962                final int NA = procs.size();
13963                for (int ia=0; ia<NA; ia++) {
13964                    ProcessRecord r = procs.valueAt(ia);
13965                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13966                        continue;
13967                    }
13968                    if (!needSep) {
13969                        pw.println("  All known processes:");
13970                        needSep = true;
13971                        printedAnything = true;
13972                    }
13973                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13974                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13975                        pw.print(" "); pw.println(r);
13976                    r.dump(pw, "    ");
13977                    if (r.persistent) {
13978                        numPers++;
13979                    }
13980                }
13981            }
13982        }
13983
13984        if (mIsolatedProcesses.size() > 0) {
13985            boolean printed = false;
13986            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13987                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13988                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13989                    continue;
13990                }
13991                if (!printed) {
13992                    if (needSep) {
13993                        pw.println();
13994                    }
13995                    pw.println("  Isolated process list (sorted by uid):");
13996                    printedAnything = true;
13997                    printed = true;
13998                    needSep = true;
13999                }
14000                pw.println(String.format("%sIsolated #%2d: %s",
14001                        "    ", i, r.toString()));
14002            }
14003        }
14004
14005        if (mActiveUids.size() > 0) {
14006            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14007                printedAnything = needSep = true;
14008            }
14009        }
14010        if (mValidateUids.size() > 0) {
14011            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14012                printedAnything = needSep = true;
14013            }
14014        }
14015
14016        if (mLruProcesses.size() > 0) {
14017            if (needSep) {
14018                pw.println();
14019            }
14020            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14021                    pw.print(" total, non-act at ");
14022                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14023                    pw.print(", non-svc at ");
14024                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14025                    pw.println("):");
14026            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14027            needSep = true;
14028            printedAnything = true;
14029        }
14030
14031        if (dumpAll || dumpPackage != null) {
14032            synchronized (mPidsSelfLocked) {
14033                boolean printed = false;
14034                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14035                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14036                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14037                        continue;
14038                    }
14039                    if (!printed) {
14040                        if (needSep) pw.println();
14041                        needSep = true;
14042                        pw.println("  PID mappings:");
14043                        printed = true;
14044                        printedAnything = true;
14045                    }
14046                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14047                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14048                }
14049            }
14050        }
14051
14052        if (mForegroundProcesses.size() > 0) {
14053            synchronized (mPidsSelfLocked) {
14054                boolean printed = false;
14055                for (int i=0; i<mForegroundProcesses.size(); i++) {
14056                    ProcessRecord r = mPidsSelfLocked.get(
14057                            mForegroundProcesses.valueAt(i).pid);
14058                    if (dumpPackage != null && (r == null
14059                            || !r.pkgList.containsKey(dumpPackage))) {
14060                        continue;
14061                    }
14062                    if (!printed) {
14063                        if (needSep) pw.println();
14064                        needSep = true;
14065                        pw.println("  Foreground Processes:");
14066                        printed = true;
14067                        printedAnything = true;
14068                    }
14069                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14070                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14071                }
14072            }
14073        }
14074
14075        if (mPersistentStartingProcesses.size() > 0) {
14076            if (needSep) pw.println();
14077            needSep = true;
14078            printedAnything = true;
14079            pw.println("  Persisent processes that are starting:");
14080            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14081                    "Starting Norm", "Restarting PERS", dumpPackage);
14082        }
14083
14084        if (mRemovedProcesses.size() > 0) {
14085            if (needSep) pw.println();
14086            needSep = true;
14087            printedAnything = true;
14088            pw.println("  Processes that are being removed:");
14089            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14090                    "Removed Norm", "Removed PERS", dumpPackage);
14091        }
14092
14093        if (mProcessesOnHold.size() > 0) {
14094            if (needSep) pw.println();
14095            needSep = true;
14096            printedAnything = true;
14097            pw.println("  Processes that are on old until the system is ready:");
14098            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14099                    "OnHold Norm", "OnHold PERS", dumpPackage);
14100        }
14101
14102        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14103
14104        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14105        if (needSep) {
14106            printedAnything = true;
14107        }
14108
14109        if (dumpPackage == null) {
14110            pw.println();
14111            needSep = false;
14112            mUserController.dump(pw, dumpAll);
14113        }
14114        if (mHomeProcess != null && (dumpPackage == null
14115                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14116            if (needSep) {
14117                pw.println();
14118                needSep = false;
14119            }
14120            pw.println("  mHomeProcess: " + mHomeProcess);
14121        }
14122        if (mPreviousProcess != null && (dumpPackage == null
14123                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14124            if (needSep) {
14125                pw.println();
14126                needSep = false;
14127            }
14128            pw.println("  mPreviousProcess: " + mPreviousProcess);
14129        }
14130        if (dumpAll) {
14131            StringBuilder sb = new StringBuilder(128);
14132            sb.append("  mPreviousProcessVisibleTime: ");
14133            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14134            pw.println(sb);
14135        }
14136        if (mHeavyWeightProcess != null && (dumpPackage == null
14137                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14138            if (needSep) {
14139                pw.println();
14140                needSep = false;
14141            }
14142            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14143        }
14144        if (dumpPackage == null) {
14145            pw.println("  mConfiguration: " + mConfiguration);
14146        }
14147        if (dumpAll) {
14148            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14149            if (mCompatModePackages.getPackages().size() > 0) {
14150                boolean printed = false;
14151                for (Map.Entry<String, Integer> entry
14152                        : mCompatModePackages.getPackages().entrySet()) {
14153                    String pkg = entry.getKey();
14154                    int mode = entry.getValue();
14155                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14156                        continue;
14157                    }
14158                    if (!printed) {
14159                        pw.println("  mScreenCompatPackages:");
14160                        printed = true;
14161                    }
14162                    pw.print("    "); pw.print(pkg); pw.print(": ");
14163                            pw.print(mode); pw.println();
14164                }
14165            }
14166        }
14167        if (dumpPackage == null) {
14168            pw.println("  mWakefulness="
14169                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14170            pw.println("  mSleepTokens=" + mSleepTokens);
14171            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14172                    + lockScreenShownToString());
14173            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14174            if (mRunningVoice != null) {
14175                pw.println("  mRunningVoice=" + mRunningVoice);
14176                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14177            }
14178        }
14179        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14180                || mOrigWaitForDebugger) {
14181            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14182                    || dumpPackage.equals(mOrigDebugApp)) {
14183                if (needSep) {
14184                    pw.println();
14185                    needSep = false;
14186                }
14187                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14188                        + " mDebugTransient=" + mDebugTransient
14189                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14190            }
14191        }
14192        if (mCurAppTimeTracker != null) {
14193            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14194        }
14195        if (mMemWatchProcesses.getMap().size() > 0) {
14196            pw.println("  Mem watch processes:");
14197            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14198                    = mMemWatchProcesses.getMap();
14199            for (int i=0; i<procs.size(); i++) {
14200                final String proc = procs.keyAt(i);
14201                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14202                for (int j=0; j<uids.size(); j++) {
14203                    if (needSep) {
14204                        pw.println();
14205                        needSep = false;
14206                    }
14207                    StringBuilder sb = new StringBuilder();
14208                    sb.append("    ").append(proc).append('/');
14209                    UserHandle.formatUid(sb, uids.keyAt(j));
14210                    Pair<Long, String> val = uids.valueAt(j);
14211                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14212                    if (val.second != null) {
14213                        sb.append(", report to ").append(val.second);
14214                    }
14215                    pw.println(sb.toString());
14216                }
14217            }
14218            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14219            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14220            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14221                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14222        }
14223        if (mTrackAllocationApp != null) {
14224            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14225                if (needSep) {
14226                    pw.println();
14227                    needSep = false;
14228                }
14229                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14230            }
14231        }
14232        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14233                || mProfileFd != null) {
14234            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14235                if (needSep) {
14236                    pw.println();
14237                    needSep = false;
14238                }
14239                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14240                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14241                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14242                        + mAutoStopProfiler);
14243                pw.println("  mProfileType=" + mProfileType);
14244            }
14245        }
14246        if (mNativeDebuggingApp != null) {
14247            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14248                if (needSep) {
14249                    pw.println();
14250                    needSep = false;
14251                }
14252                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14253            }
14254        }
14255        if (dumpPackage == null) {
14256            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14257                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14258                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14259            }
14260            if (mController != null) {
14261                pw.println("  mController=" + mController
14262                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14263            }
14264            if (dumpAll) {
14265                pw.println("  Total persistent processes: " + numPers);
14266                pw.println("  mProcessesReady=" + mProcessesReady
14267                        + " mSystemReady=" + mSystemReady
14268                        + " mBooted=" + mBooted
14269                        + " mFactoryTest=" + mFactoryTest);
14270                pw.println("  mBooting=" + mBooting
14271                        + " mCallFinishBooting=" + mCallFinishBooting
14272                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14273                pw.print("  mLastPowerCheckRealtime=");
14274                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14275                        pw.println("");
14276                pw.print("  mLastPowerCheckUptime=");
14277                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14278                        pw.println("");
14279                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14280                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14281                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14282                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14283                        + " (" + mLruProcesses.size() + " total)"
14284                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14285                        + " mNumServiceProcs=" + mNumServiceProcs
14286                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14287                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14288                        + " mLastMemoryLevel" + mLastMemoryLevel
14289                        + " mLastNumProcesses" + mLastNumProcesses);
14290                long now = SystemClock.uptimeMillis();
14291                pw.print("  mLastIdleTime=");
14292                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14293                        pw.print(" mLowRamSinceLastIdle=");
14294                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14295                        pw.println();
14296            }
14297        }
14298
14299        if (!printedAnything) {
14300            pw.println("  (nothing)");
14301        }
14302    }
14303
14304    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14305            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14306        if (mProcessesToGc.size() > 0) {
14307            boolean printed = false;
14308            long now = SystemClock.uptimeMillis();
14309            for (int i=0; i<mProcessesToGc.size(); i++) {
14310                ProcessRecord proc = mProcessesToGc.get(i);
14311                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14312                    continue;
14313                }
14314                if (!printed) {
14315                    if (needSep) pw.println();
14316                    needSep = true;
14317                    pw.println("  Processes that are waiting to GC:");
14318                    printed = true;
14319                }
14320                pw.print("    Process "); pw.println(proc);
14321                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14322                        pw.print(", last gced=");
14323                        pw.print(now-proc.lastRequestedGc);
14324                        pw.print(" ms ago, last lowMem=");
14325                        pw.print(now-proc.lastLowMemory);
14326                        pw.println(" ms ago");
14327
14328            }
14329        }
14330        return needSep;
14331    }
14332
14333    void printOomLevel(PrintWriter pw, String name, int adj) {
14334        pw.print("    ");
14335        if (adj >= 0) {
14336            pw.print(' ');
14337            if (adj < 10) pw.print(' ');
14338        } else {
14339            if (adj > -10) pw.print(' ');
14340        }
14341        pw.print(adj);
14342        pw.print(": ");
14343        pw.print(name);
14344        pw.print(" (");
14345        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14346        pw.println(")");
14347    }
14348
14349    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14350            int opti, boolean dumpAll) {
14351        boolean needSep = false;
14352
14353        if (mLruProcesses.size() > 0) {
14354            if (needSep) pw.println();
14355            needSep = true;
14356            pw.println("  OOM levels:");
14357            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14358            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14359            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14360            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14361            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14362            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14363            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14364            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14365            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14366            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14367            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14368            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14369            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14370            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14371
14372            if (needSep) pw.println();
14373            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14374                    pw.print(" total, non-act at ");
14375                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14376                    pw.print(", non-svc at ");
14377                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14378                    pw.println("):");
14379            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14380            needSep = true;
14381        }
14382
14383        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14384
14385        pw.println();
14386        pw.println("  mHomeProcess: " + mHomeProcess);
14387        pw.println("  mPreviousProcess: " + mPreviousProcess);
14388        if (mHeavyWeightProcess != null) {
14389            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14390        }
14391
14392        return true;
14393    }
14394
14395    /**
14396     * There are three ways to call this:
14397     *  - no provider specified: dump all the providers
14398     *  - a flattened component name that matched an existing provider was specified as the
14399     *    first arg: dump that one provider
14400     *  - the first arg isn't the flattened component name of an existing provider:
14401     *    dump all providers whose component contains the first arg as a substring
14402     */
14403    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14404            int opti, boolean dumpAll) {
14405        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14406    }
14407
14408    static class ItemMatcher {
14409        ArrayList<ComponentName> components;
14410        ArrayList<String> strings;
14411        ArrayList<Integer> objects;
14412        boolean all;
14413
14414        ItemMatcher() {
14415            all = true;
14416        }
14417
14418        void build(String name) {
14419            ComponentName componentName = ComponentName.unflattenFromString(name);
14420            if (componentName != null) {
14421                if (components == null) {
14422                    components = new ArrayList<ComponentName>();
14423                }
14424                components.add(componentName);
14425                all = false;
14426            } else {
14427                int objectId = 0;
14428                // Not a '/' separated full component name; maybe an object ID?
14429                try {
14430                    objectId = Integer.parseInt(name, 16);
14431                    if (objects == null) {
14432                        objects = new ArrayList<Integer>();
14433                    }
14434                    objects.add(objectId);
14435                    all = false;
14436                } catch (RuntimeException e) {
14437                    // Not an integer; just do string match.
14438                    if (strings == null) {
14439                        strings = new ArrayList<String>();
14440                    }
14441                    strings.add(name);
14442                    all = false;
14443                }
14444            }
14445        }
14446
14447        int build(String[] args, int opti) {
14448            for (; opti<args.length; opti++) {
14449                String name = args[opti];
14450                if ("--".equals(name)) {
14451                    return opti+1;
14452                }
14453                build(name);
14454            }
14455            return opti;
14456        }
14457
14458        boolean match(Object object, ComponentName comp) {
14459            if (all) {
14460                return true;
14461            }
14462            if (components != null) {
14463                for (int i=0; i<components.size(); i++) {
14464                    if (components.get(i).equals(comp)) {
14465                        return true;
14466                    }
14467                }
14468            }
14469            if (objects != null) {
14470                for (int i=0; i<objects.size(); i++) {
14471                    if (System.identityHashCode(object) == objects.get(i)) {
14472                        return true;
14473                    }
14474                }
14475            }
14476            if (strings != null) {
14477                String flat = comp.flattenToString();
14478                for (int i=0; i<strings.size(); i++) {
14479                    if (flat.contains(strings.get(i))) {
14480                        return true;
14481                    }
14482                }
14483            }
14484            return false;
14485        }
14486    }
14487
14488    /**
14489     * There are three things that cmd can be:
14490     *  - a flattened component name that matches an existing activity
14491     *  - the cmd arg isn't the flattened component name of an existing activity:
14492     *    dump all activity whose component contains the cmd as a substring
14493     *  - A hex number of the ActivityRecord object instance.
14494     */
14495    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14496            int opti, boolean dumpAll) {
14497        ArrayList<ActivityRecord> activities;
14498
14499        synchronized (this) {
14500            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14501        }
14502
14503        if (activities.size() <= 0) {
14504            return false;
14505        }
14506
14507        String[] newArgs = new String[args.length - opti];
14508        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14509
14510        TaskRecord lastTask = null;
14511        boolean needSep = false;
14512        for (int i=activities.size()-1; i>=0; i--) {
14513            ActivityRecord r = activities.get(i);
14514            if (needSep) {
14515                pw.println();
14516            }
14517            needSep = true;
14518            synchronized (this) {
14519                if (lastTask != r.task) {
14520                    lastTask = r.task;
14521                    pw.print("TASK "); pw.print(lastTask.affinity);
14522                            pw.print(" id="); pw.println(lastTask.taskId);
14523                    if (dumpAll) {
14524                        lastTask.dump(pw, "  ");
14525                    }
14526                }
14527            }
14528            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14529        }
14530        return true;
14531    }
14532
14533    /**
14534     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14535     * there is a thread associated with the activity.
14536     */
14537    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14538            final ActivityRecord r, String[] args, boolean dumpAll) {
14539        String innerPrefix = prefix + "  ";
14540        synchronized (this) {
14541            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14542                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14543                    pw.print(" pid=");
14544                    if (r.app != null) pw.println(r.app.pid);
14545                    else pw.println("(not running)");
14546            if (dumpAll) {
14547                r.dump(pw, innerPrefix);
14548            }
14549        }
14550        if (r.app != null && r.app.thread != null) {
14551            // flush anything that is already in the PrintWriter since the thread is going
14552            // to write to the file descriptor directly
14553            pw.flush();
14554            try {
14555                TransferPipe tp = new TransferPipe();
14556                try {
14557                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14558                            r.appToken, innerPrefix, args);
14559                    tp.go(fd);
14560                } finally {
14561                    tp.kill();
14562                }
14563            } catch (IOException e) {
14564                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14565            } catch (RemoteException e) {
14566                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14567            }
14568        }
14569    }
14570
14571    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14572            int opti, boolean dumpAll, String dumpPackage) {
14573        boolean needSep = false;
14574        boolean onlyHistory = false;
14575        boolean printedAnything = false;
14576
14577        if ("history".equals(dumpPackage)) {
14578            if (opti < args.length && "-s".equals(args[opti])) {
14579                dumpAll = false;
14580            }
14581            onlyHistory = true;
14582            dumpPackage = null;
14583        }
14584
14585        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14586        if (!onlyHistory && dumpAll) {
14587            if (mRegisteredReceivers.size() > 0) {
14588                boolean printed = false;
14589                Iterator it = mRegisteredReceivers.values().iterator();
14590                while (it.hasNext()) {
14591                    ReceiverList r = (ReceiverList)it.next();
14592                    if (dumpPackage != null && (r.app == null ||
14593                            !dumpPackage.equals(r.app.info.packageName))) {
14594                        continue;
14595                    }
14596                    if (!printed) {
14597                        pw.println("  Registered Receivers:");
14598                        needSep = true;
14599                        printed = true;
14600                        printedAnything = true;
14601                    }
14602                    pw.print("  * "); pw.println(r);
14603                    r.dump(pw, "    ");
14604                }
14605            }
14606
14607            if (mReceiverResolver.dump(pw, needSep ?
14608                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14609                    "    ", dumpPackage, false, false)) {
14610                needSep = true;
14611                printedAnything = true;
14612            }
14613        }
14614
14615        for (BroadcastQueue q : mBroadcastQueues) {
14616            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14617            printedAnything |= needSep;
14618        }
14619
14620        needSep = true;
14621
14622        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14623            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14624                if (needSep) {
14625                    pw.println();
14626                }
14627                needSep = true;
14628                printedAnything = true;
14629                pw.print("  Sticky broadcasts for user ");
14630                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14631                StringBuilder sb = new StringBuilder(128);
14632                for (Map.Entry<String, ArrayList<Intent>> ent
14633                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14634                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14635                    if (dumpAll) {
14636                        pw.println(":");
14637                        ArrayList<Intent> intents = ent.getValue();
14638                        final int N = intents.size();
14639                        for (int i=0; i<N; i++) {
14640                            sb.setLength(0);
14641                            sb.append("    Intent: ");
14642                            intents.get(i).toShortString(sb, false, true, false, false);
14643                            pw.println(sb.toString());
14644                            Bundle bundle = intents.get(i).getExtras();
14645                            if (bundle != null) {
14646                                pw.print("      ");
14647                                pw.println(bundle.toString());
14648                            }
14649                        }
14650                    } else {
14651                        pw.println("");
14652                    }
14653                }
14654            }
14655        }
14656
14657        if (!onlyHistory && dumpAll) {
14658            pw.println();
14659            for (BroadcastQueue queue : mBroadcastQueues) {
14660                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14661                        + queue.mBroadcastsScheduled);
14662            }
14663            pw.println("  mHandler:");
14664            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14665            needSep = true;
14666            printedAnything = true;
14667        }
14668
14669        if (!printedAnything) {
14670            pw.println("  (nothing)");
14671        }
14672    }
14673
14674    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14675            int opti, boolean dumpAll, String dumpPackage) {
14676        boolean needSep;
14677        boolean printedAnything = false;
14678
14679        ItemMatcher matcher = new ItemMatcher();
14680        matcher.build(args, opti);
14681
14682        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14683
14684        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14685        printedAnything |= needSep;
14686
14687        if (mLaunchingProviders.size() > 0) {
14688            boolean printed = false;
14689            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14690                ContentProviderRecord r = mLaunchingProviders.get(i);
14691                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14692                    continue;
14693                }
14694                if (!printed) {
14695                    if (needSep) pw.println();
14696                    needSep = true;
14697                    pw.println("  Launching content providers:");
14698                    printed = true;
14699                    printedAnything = true;
14700                }
14701                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14702                        pw.println(r);
14703            }
14704        }
14705
14706        if (!printedAnything) {
14707            pw.println("  (nothing)");
14708        }
14709    }
14710
14711    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14712            int opti, boolean dumpAll, String dumpPackage) {
14713        boolean needSep = false;
14714        boolean printedAnything = false;
14715
14716        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14717
14718        if (mGrantedUriPermissions.size() > 0) {
14719            boolean printed = false;
14720            int dumpUid = -2;
14721            if (dumpPackage != null) {
14722                try {
14723                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14724                            MATCH_UNINSTALLED_PACKAGES, 0);
14725                } catch (NameNotFoundException e) {
14726                    dumpUid = -1;
14727                }
14728            }
14729            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14730                int uid = mGrantedUriPermissions.keyAt(i);
14731                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14732                    continue;
14733                }
14734                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14735                if (!printed) {
14736                    if (needSep) pw.println();
14737                    needSep = true;
14738                    pw.println("  Granted Uri Permissions:");
14739                    printed = true;
14740                    printedAnything = true;
14741                }
14742                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14743                for (UriPermission perm : perms.values()) {
14744                    pw.print("    "); pw.println(perm);
14745                    if (dumpAll) {
14746                        perm.dump(pw, "      ");
14747                    }
14748                }
14749            }
14750        }
14751
14752        if (!printedAnything) {
14753            pw.println("  (nothing)");
14754        }
14755    }
14756
14757    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14758            int opti, boolean dumpAll, String dumpPackage) {
14759        boolean printed = false;
14760
14761        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14762
14763        if (mIntentSenderRecords.size() > 0) {
14764            Iterator<WeakReference<PendingIntentRecord>> it
14765                    = mIntentSenderRecords.values().iterator();
14766            while (it.hasNext()) {
14767                WeakReference<PendingIntentRecord> ref = it.next();
14768                PendingIntentRecord rec = ref != null ? ref.get(): null;
14769                if (dumpPackage != null && (rec == null
14770                        || !dumpPackage.equals(rec.key.packageName))) {
14771                    continue;
14772                }
14773                printed = true;
14774                if (rec != null) {
14775                    pw.print("  * "); pw.println(rec);
14776                    if (dumpAll) {
14777                        rec.dump(pw, "    ");
14778                    }
14779                } else {
14780                    pw.print("  * "); pw.println(ref);
14781                }
14782            }
14783        }
14784
14785        if (!printed) {
14786            pw.println("  (nothing)");
14787        }
14788    }
14789
14790    private static final int dumpProcessList(PrintWriter pw,
14791            ActivityManagerService service, List list,
14792            String prefix, String normalLabel, String persistentLabel,
14793            String dumpPackage) {
14794        int numPers = 0;
14795        final int N = list.size()-1;
14796        for (int i=N; i>=0; i--) {
14797            ProcessRecord r = (ProcessRecord)list.get(i);
14798            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14799                continue;
14800            }
14801            pw.println(String.format("%s%s #%2d: %s",
14802                    prefix, (r.persistent ? persistentLabel : normalLabel),
14803                    i, r.toString()));
14804            if (r.persistent) {
14805                numPers++;
14806            }
14807        }
14808        return numPers;
14809    }
14810
14811    private static final boolean dumpProcessOomList(PrintWriter pw,
14812            ActivityManagerService service, List<ProcessRecord> origList,
14813            String prefix, String normalLabel, String persistentLabel,
14814            boolean inclDetails, String dumpPackage) {
14815
14816        ArrayList<Pair<ProcessRecord, Integer>> list
14817                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14818        for (int i=0; i<origList.size(); i++) {
14819            ProcessRecord r = origList.get(i);
14820            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14821                continue;
14822            }
14823            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14824        }
14825
14826        if (list.size() <= 0) {
14827            return false;
14828        }
14829
14830        Comparator<Pair<ProcessRecord, Integer>> comparator
14831                = new Comparator<Pair<ProcessRecord, Integer>>() {
14832            @Override
14833            public int compare(Pair<ProcessRecord, Integer> object1,
14834                    Pair<ProcessRecord, Integer> object2) {
14835                if (object1.first.setAdj != object2.first.setAdj) {
14836                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14837                }
14838                if (object1.first.setProcState != object2.first.setProcState) {
14839                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14840                }
14841                if (object1.second.intValue() != object2.second.intValue()) {
14842                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14843                }
14844                return 0;
14845            }
14846        };
14847
14848        Collections.sort(list, comparator);
14849
14850        final long curRealtime = SystemClock.elapsedRealtime();
14851        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14852        final long curUptime = SystemClock.uptimeMillis();
14853        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14854
14855        for (int i=list.size()-1; i>=0; i--) {
14856            ProcessRecord r = list.get(i).first;
14857            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14858            char schedGroup;
14859            switch (r.setSchedGroup) {
14860                case ProcessList.SCHED_GROUP_BACKGROUND:
14861                    schedGroup = 'B';
14862                    break;
14863                case ProcessList.SCHED_GROUP_DEFAULT:
14864                    schedGroup = 'F';
14865                    break;
14866                case ProcessList.SCHED_GROUP_TOP_APP:
14867                    schedGroup = 'T';
14868                    break;
14869                default:
14870                    schedGroup = '?';
14871                    break;
14872            }
14873            char foreground;
14874            if (r.foregroundActivities) {
14875                foreground = 'A';
14876            } else if (r.foregroundServices) {
14877                foreground = 'S';
14878            } else {
14879                foreground = ' ';
14880            }
14881            String procState = ProcessList.makeProcStateString(r.curProcState);
14882            pw.print(prefix);
14883            pw.print(r.persistent ? persistentLabel : normalLabel);
14884            pw.print(" #");
14885            int num = (origList.size()-1)-list.get(i).second;
14886            if (num < 10) pw.print(' ');
14887            pw.print(num);
14888            pw.print(": ");
14889            pw.print(oomAdj);
14890            pw.print(' ');
14891            pw.print(schedGroup);
14892            pw.print('/');
14893            pw.print(foreground);
14894            pw.print('/');
14895            pw.print(procState);
14896            pw.print(" trm:");
14897            if (r.trimMemoryLevel < 10) pw.print(' ');
14898            pw.print(r.trimMemoryLevel);
14899            pw.print(' ');
14900            pw.print(r.toShortString());
14901            pw.print(" (");
14902            pw.print(r.adjType);
14903            pw.println(')');
14904            if (r.adjSource != null || r.adjTarget != null) {
14905                pw.print(prefix);
14906                pw.print("    ");
14907                if (r.adjTarget instanceof ComponentName) {
14908                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14909                } else if (r.adjTarget != null) {
14910                    pw.print(r.adjTarget.toString());
14911                } else {
14912                    pw.print("{null}");
14913                }
14914                pw.print("<=");
14915                if (r.adjSource instanceof ProcessRecord) {
14916                    pw.print("Proc{");
14917                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14918                    pw.println("}");
14919                } else if (r.adjSource != null) {
14920                    pw.println(r.adjSource.toString());
14921                } else {
14922                    pw.println("{null}");
14923                }
14924            }
14925            if (inclDetails) {
14926                pw.print(prefix);
14927                pw.print("    ");
14928                pw.print("oom: max="); pw.print(r.maxAdj);
14929                pw.print(" curRaw="); pw.print(r.curRawAdj);
14930                pw.print(" setRaw="); pw.print(r.setRawAdj);
14931                pw.print(" cur="); pw.print(r.curAdj);
14932                pw.print(" set="); pw.println(r.setAdj);
14933                pw.print(prefix);
14934                pw.print("    ");
14935                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14936                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14937                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14938                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14939                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14940                pw.println();
14941                pw.print(prefix);
14942                pw.print("    ");
14943                pw.print("cached="); pw.print(r.cached);
14944                pw.print(" empty="); pw.print(r.empty);
14945                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14946
14947                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14948                    if (r.lastWakeTime != 0) {
14949                        long wtime;
14950                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14951                        synchronized (stats) {
14952                            wtime = stats.getProcessWakeTime(r.info.uid,
14953                                    r.pid, curRealtime);
14954                        }
14955                        long timeUsed = wtime - r.lastWakeTime;
14956                        pw.print(prefix);
14957                        pw.print("    ");
14958                        pw.print("keep awake over ");
14959                        TimeUtils.formatDuration(realtimeSince, pw);
14960                        pw.print(" used ");
14961                        TimeUtils.formatDuration(timeUsed, pw);
14962                        pw.print(" (");
14963                        pw.print((timeUsed*100)/realtimeSince);
14964                        pw.println("%)");
14965                    }
14966                    if (r.lastCpuTime != 0) {
14967                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14968                        pw.print(prefix);
14969                        pw.print("    ");
14970                        pw.print("run cpu over ");
14971                        TimeUtils.formatDuration(uptimeSince, pw);
14972                        pw.print(" used ");
14973                        TimeUtils.formatDuration(timeUsed, pw);
14974                        pw.print(" (");
14975                        pw.print((timeUsed*100)/uptimeSince);
14976                        pw.println("%)");
14977                    }
14978                }
14979            }
14980        }
14981        return true;
14982    }
14983
14984    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14985            String[] args) {
14986        ArrayList<ProcessRecord> procs;
14987        synchronized (this) {
14988            if (args != null && args.length > start
14989                    && args[start].charAt(0) != '-') {
14990                procs = new ArrayList<ProcessRecord>();
14991                int pid = -1;
14992                try {
14993                    pid = Integer.parseInt(args[start]);
14994                } catch (NumberFormatException e) {
14995                }
14996                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14997                    ProcessRecord proc = mLruProcesses.get(i);
14998                    if (proc.pid == pid) {
14999                        procs.add(proc);
15000                    } else if (allPkgs && proc.pkgList != null
15001                            && proc.pkgList.containsKey(args[start])) {
15002                        procs.add(proc);
15003                    } else if (proc.processName.equals(args[start])) {
15004                        procs.add(proc);
15005                    }
15006                }
15007                if (procs.size() <= 0) {
15008                    return null;
15009                }
15010            } else {
15011                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15012            }
15013        }
15014        return procs;
15015    }
15016
15017    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15018            PrintWriter pw, String[] args) {
15019        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15020        if (procs == null) {
15021            pw.println("No process found for: " + args[0]);
15022            return;
15023        }
15024
15025        long uptime = SystemClock.uptimeMillis();
15026        long realtime = SystemClock.elapsedRealtime();
15027        pw.println("Applications Graphics Acceleration Info:");
15028        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15029
15030        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15031            ProcessRecord r = procs.get(i);
15032            if (r.thread != null) {
15033                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15034                pw.flush();
15035                try {
15036                    TransferPipe tp = new TransferPipe();
15037                    try {
15038                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15039                        tp.go(fd);
15040                    } finally {
15041                        tp.kill();
15042                    }
15043                } catch (IOException e) {
15044                    pw.println("Failure while dumping the app: " + r);
15045                    pw.flush();
15046                } catch (RemoteException e) {
15047                    pw.println("Got a RemoteException while dumping the app " + r);
15048                    pw.flush();
15049                }
15050            }
15051        }
15052    }
15053
15054    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15055        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15056        if (procs == null) {
15057            pw.println("No process found for: " + args[0]);
15058            return;
15059        }
15060
15061        pw.println("Applications Database Info:");
15062
15063        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15064            ProcessRecord r = procs.get(i);
15065            if (r.thread != null) {
15066                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15067                pw.flush();
15068                try {
15069                    TransferPipe tp = new TransferPipe();
15070                    try {
15071                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15072                        tp.go(fd);
15073                    } finally {
15074                        tp.kill();
15075                    }
15076                } catch (IOException e) {
15077                    pw.println("Failure while dumping the app: " + r);
15078                    pw.flush();
15079                } catch (RemoteException e) {
15080                    pw.println("Got a RemoteException while dumping the app " + r);
15081                    pw.flush();
15082                }
15083            }
15084        }
15085    }
15086
15087    final static class MemItem {
15088        final boolean isProc;
15089        final String label;
15090        final String shortLabel;
15091        final long pss;
15092        final long swapPss;
15093        final int id;
15094        final boolean hasActivities;
15095        ArrayList<MemItem> subitems;
15096
15097        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15098                boolean _hasActivities) {
15099            isProc = true;
15100            label = _label;
15101            shortLabel = _shortLabel;
15102            pss = _pss;
15103            swapPss = _swapPss;
15104            id = _id;
15105            hasActivities = _hasActivities;
15106        }
15107
15108        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15109            isProc = false;
15110            label = _label;
15111            shortLabel = _shortLabel;
15112            pss = _pss;
15113            swapPss = _swapPss;
15114            id = _id;
15115            hasActivities = false;
15116        }
15117    }
15118
15119    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15120            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15121        if (sort && !isCompact) {
15122            Collections.sort(items, new Comparator<MemItem>() {
15123                @Override
15124                public int compare(MemItem lhs, MemItem rhs) {
15125                    if (lhs.pss < rhs.pss) {
15126                        return 1;
15127                    } else if (lhs.pss > rhs.pss) {
15128                        return -1;
15129                    }
15130                    return 0;
15131                }
15132            });
15133        }
15134
15135        for (int i=0; i<items.size(); i++) {
15136            MemItem mi = items.get(i);
15137            if (!isCompact) {
15138                if (dumpSwapPss) {
15139                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15140                            mi.label, stringifyKBSize(mi.swapPss));
15141                } else {
15142                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15143                }
15144            } else if (mi.isProc) {
15145                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15146                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15147                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15148                pw.println(mi.hasActivities ? ",a" : ",e");
15149            } else {
15150                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15151                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15152            }
15153            if (mi.subitems != null) {
15154                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15155                        true, isCompact, dumpSwapPss);
15156            }
15157        }
15158    }
15159
15160    // These are in KB.
15161    static final long[] DUMP_MEM_BUCKETS = new long[] {
15162        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15163        120*1024, 160*1024, 200*1024,
15164        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15165        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15166    };
15167
15168    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15169            boolean stackLike) {
15170        int start = label.lastIndexOf('.');
15171        if (start >= 0) start++;
15172        else start = 0;
15173        int end = label.length();
15174        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15175            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15176                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15177                out.append(bucket);
15178                out.append(stackLike ? "MB." : "MB ");
15179                out.append(label, start, end);
15180                return;
15181            }
15182        }
15183        out.append(memKB/1024);
15184        out.append(stackLike ? "MB." : "MB ");
15185        out.append(label, start, end);
15186    }
15187
15188    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15189            ProcessList.NATIVE_ADJ,
15190            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15191            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15192            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15193            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15194            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15195            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15196    };
15197    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15198            "Native",
15199            "System", "Persistent", "Persistent Service", "Foreground",
15200            "Visible", "Perceptible",
15201            "Heavy Weight", "Backup",
15202            "A Services", "Home",
15203            "Previous", "B Services", "Cached"
15204    };
15205    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15206            "native",
15207            "sys", "pers", "persvc", "fore",
15208            "vis", "percept",
15209            "heavy", "backup",
15210            "servicea", "home",
15211            "prev", "serviceb", "cached"
15212    };
15213
15214    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15215            long realtime, boolean isCheckinRequest, boolean isCompact) {
15216        if (isCompact) {
15217            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15218        }
15219        if (isCheckinRequest || isCompact) {
15220            // short checkin version
15221            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15222        } else {
15223            pw.println("Applications Memory Usage (in Kilobytes):");
15224            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15225        }
15226    }
15227
15228    private static final int KSM_SHARED = 0;
15229    private static final int KSM_SHARING = 1;
15230    private static final int KSM_UNSHARED = 2;
15231    private static final int KSM_VOLATILE = 3;
15232
15233    private final long[] getKsmInfo() {
15234        long[] longOut = new long[4];
15235        final int[] SINGLE_LONG_FORMAT = new int[] {
15236            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15237        };
15238        long[] longTmp = new long[1];
15239        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15240                SINGLE_LONG_FORMAT, null, longTmp, null);
15241        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15242        longTmp[0] = 0;
15243        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15244                SINGLE_LONG_FORMAT, null, longTmp, null);
15245        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15246        longTmp[0] = 0;
15247        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15248                SINGLE_LONG_FORMAT, null, longTmp, null);
15249        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15250        longTmp[0] = 0;
15251        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15252                SINGLE_LONG_FORMAT, null, longTmp, null);
15253        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15254        return longOut;
15255    }
15256
15257    private static String stringifySize(long size, int order) {
15258        Locale locale = Locale.US;
15259        switch (order) {
15260            case 1:
15261                return String.format(locale, "%,13d", size);
15262            case 1024:
15263                return String.format(locale, "%,9dK", size / 1024);
15264            case 1024 * 1024:
15265                return String.format(locale, "%,5dM", size / 1024 / 1024);
15266            case 1024 * 1024 * 1024:
15267                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15268            default:
15269                throw new IllegalArgumentException("Invalid size order");
15270        }
15271    }
15272
15273    private static String stringifyKBSize(long size) {
15274        return stringifySize(size * 1024, 1024);
15275    }
15276
15277    // Update this version number in case you change the 'compact' format
15278    private static final int MEMINFO_COMPACT_VERSION = 1;
15279
15280    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15281            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15282        boolean dumpDetails = false;
15283        boolean dumpFullDetails = false;
15284        boolean dumpDalvik = false;
15285        boolean dumpSummaryOnly = false;
15286        boolean dumpUnreachable = false;
15287        boolean oomOnly = false;
15288        boolean isCompact = false;
15289        boolean localOnly = false;
15290        boolean packages = false;
15291        boolean isCheckinRequest = false;
15292        boolean dumpSwapPss = false;
15293
15294        int opti = 0;
15295        while (opti < args.length) {
15296            String opt = args[opti];
15297            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15298                break;
15299            }
15300            opti++;
15301            if ("-a".equals(opt)) {
15302                dumpDetails = true;
15303                dumpFullDetails = true;
15304                dumpDalvik = true;
15305                dumpSwapPss = true;
15306            } else if ("-d".equals(opt)) {
15307                dumpDalvik = true;
15308            } else if ("-c".equals(opt)) {
15309                isCompact = true;
15310            } else if ("-s".equals(opt)) {
15311                dumpDetails = true;
15312                dumpSummaryOnly = true;
15313            } else if ("-S".equals(opt)) {
15314                dumpSwapPss = true;
15315            } else if ("--unreachable".equals(opt)) {
15316                dumpUnreachable = true;
15317            } else if ("--oom".equals(opt)) {
15318                oomOnly = true;
15319            } else if ("--local".equals(opt)) {
15320                localOnly = true;
15321            } else if ("--package".equals(opt)) {
15322                packages = true;
15323            } else if ("--checkin".equals(opt)) {
15324                isCheckinRequest = true;
15325
15326            } else if ("-h".equals(opt)) {
15327                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15328                pw.println("  -a: include all available information for each process.");
15329                pw.println("  -d: include dalvik details.");
15330                pw.println("  -c: dump in a compact machine-parseable representation.");
15331                pw.println("  -s: dump only summary of application memory usage.");
15332                pw.println("  -S: dump also SwapPss.");
15333                pw.println("  --oom: only show processes organized by oom adj.");
15334                pw.println("  --local: only collect details locally, don't call process.");
15335                pw.println("  --package: interpret process arg as package, dumping all");
15336                pw.println("             processes that have loaded that package.");
15337                pw.println("  --checkin: dump data for a checkin");
15338                pw.println("If [process] is specified it can be the name or ");
15339                pw.println("pid of a specific process to dump.");
15340                return;
15341            } else {
15342                pw.println("Unknown argument: " + opt + "; use -h for help");
15343            }
15344        }
15345
15346        long uptime = SystemClock.uptimeMillis();
15347        long realtime = SystemClock.elapsedRealtime();
15348        final long[] tmpLong = new long[1];
15349
15350        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15351        if (procs == null) {
15352            // No Java processes.  Maybe they want to print a native process.
15353            if (args != null && args.length > opti
15354                    && args[opti].charAt(0) != '-') {
15355                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15356                        = new ArrayList<ProcessCpuTracker.Stats>();
15357                updateCpuStatsNow();
15358                int findPid = -1;
15359                try {
15360                    findPid = Integer.parseInt(args[opti]);
15361                } catch (NumberFormatException e) {
15362                }
15363                synchronized (mProcessCpuTracker) {
15364                    final int N = mProcessCpuTracker.countStats();
15365                    for (int i=0; i<N; i++) {
15366                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15367                        if (st.pid == findPid || (st.baseName != null
15368                                && st.baseName.equals(args[opti]))) {
15369                            nativeProcs.add(st);
15370                        }
15371                    }
15372                }
15373                if (nativeProcs.size() > 0) {
15374                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15375                            isCompact);
15376                    Debug.MemoryInfo mi = null;
15377                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15378                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15379                        final int pid = r.pid;
15380                        if (!isCheckinRequest && dumpDetails) {
15381                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15382                        }
15383                        if (mi == null) {
15384                            mi = new Debug.MemoryInfo();
15385                        }
15386                        if (dumpDetails || (!brief && !oomOnly)) {
15387                            Debug.getMemoryInfo(pid, mi);
15388                        } else {
15389                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15390                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15391                        }
15392                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15393                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15394                        if (isCheckinRequest) {
15395                            pw.println();
15396                        }
15397                    }
15398                    return;
15399                }
15400            }
15401            pw.println("No process found for: " + args[opti]);
15402            return;
15403        }
15404
15405        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15406            dumpDetails = true;
15407        }
15408
15409        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15410
15411        String[] innerArgs = new String[args.length-opti];
15412        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15413
15414        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15415        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15416        long nativePss = 0;
15417        long nativeSwapPss = 0;
15418        long dalvikPss = 0;
15419        long dalvikSwapPss = 0;
15420        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15421                EmptyArray.LONG;
15422        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15423                EmptyArray.LONG;
15424        long otherPss = 0;
15425        long otherSwapPss = 0;
15426        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15427        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15428
15429        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15430        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15431        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15432                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15433
15434        long totalPss = 0;
15435        long totalSwapPss = 0;
15436        long cachedPss = 0;
15437        long cachedSwapPss = 0;
15438        boolean hasSwapPss = false;
15439
15440        Debug.MemoryInfo mi = null;
15441        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15442            final ProcessRecord r = procs.get(i);
15443            final IApplicationThread thread;
15444            final int pid;
15445            final int oomAdj;
15446            final boolean hasActivities;
15447            synchronized (this) {
15448                thread = r.thread;
15449                pid = r.pid;
15450                oomAdj = r.getSetAdjWithServices();
15451                hasActivities = r.activities.size() > 0;
15452            }
15453            if (thread != null) {
15454                if (!isCheckinRequest && dumpDetails) {
15455                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15456                }
15457                if (mi == null) {
15458                    mi = new Debug.MemoryInfo();
15459                }
15460                if (dumpDetails || (!brief && !oomOnly)) {
15461                    Debug.getMemoryInfo(pid, mi);
15462                    hasSwapPss = mi.hasSwappedOutPss;
15463                } else {
15464                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15465                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15466                }
15467                if (dumpDetails) {
15468                    if (localOnly) {
15469                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15470                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15471                        if (isCheckinRequest) {
15472                            pw.println();
15473                        }
15474                    } else {
15475                        try {
15476                            pw.flush();
15477                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15478                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15479                        } catch (RemoteException e) {
15480                            if (!isCheckinRequest) {
15481                                pw.println("Got RemoteException!");
15482                                pw.flush();
15483                            }
15484                        }
15485                    }
15486                }
15487
15488                final long myTotalPss = mi.getTotalPss();
15489                final long myTotalUss = mi.getTotalUss();
15490                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15491
15492                synchronized (this) {
15493                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15494                        // Record this for posterity if the process has been stable.
15495                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15496                    }
15497                }
15498
15499                if (!isCheckinRequest && mi != null) {
15500                    totalPss += myTotalPss;
15501                    totalSwapPss += myTotalSwapPss;
15502                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15503                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15504                            myTotalSwapPss, pid, hasActivities);
15505                    procMems.add(pssItem);
15506                    procMemsMap.put(pid, pssItem);
15507
15508                    nativePss += mi.nativePss;
15509                    nativeSwapPss += mi.nativeSwappedOutPss;
15510                    dalvikPss += mi.dalvikPss;
15511                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15512                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15513                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15514                        dalvikSubitemSwapPss[j] +=
15515                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15516                    }
15517                    otherPss += mi.otherPss;
15518                    otherSwapPss += mi.otherSwappedOutPss;
15519                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15520                        long mem = mi.getOtherPss(j);
15521                        miscPss[j] += mem;
15522                        otherPss -= mem;
15523                        mem = mi.getOtherSwappedOutPss(j);
15524                        miscSwapPss[j] += mem;
15525                        otherSwapPss -= mem;
15526                    }
15527
15528                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15529                        cachedPss += myTotalPss;
15530                        cachedSwapPss += myTotalSwapPss;
15531                    }
15532
15533                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15534                        if (oomIndex == (oomPss.length - 1)
15535                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15536                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15537                            oomPss[oomIndex] += myTotalPss;
15538                            oomSwapPss[oomIndex] += myTotalSwapPss;
15539                            if (oomProcs[oomIndex] == null) {
15540                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15541                            }
15542                            oomProcs[oomIndex].add(pssItem);
15543                            break;
15544                        }
15545                    }
15546                }
15547            }
15548        }
15549
15550        long nativeProcTotalPss = 0;
15551
15552        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15553            // If we are showing aggregations, also look for native processes to
15554            // include so that our aggregations are more accurate.
15555            updateCpuStatsNow();
15556            mi = null;
15557            synchronized (mProcessCpuTracker) {
15558                final int N = mProcessCpuTracker.countStats();
15559                for (int i=0; i<N; i++) {
15560                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15561                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15562                        if (mi == null) {
15563                            mi = new Debug.MemoryInfo();
15564                        }
15565                        if (!brief && !oomOnly) {
15566                            Debug.getMemoryInfo(st.pid, mi);
15567                        } else {
15568                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15569                            mi.nativePrivateDirty = (int)tmpLong[0];
15570                        }
15571
15572                        final long myTotalPss = mi.getTotalPss();
15573                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15574                        totalPss += myTotalPss;
15575                        nativeProcTotalPss += myTotalPss;
15576
15577                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15578                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15579                        procMems.add(pssItem);
15580
15581                        nativePss += mi.nativePss;
15582                        nativeSwapPss += mi.nativeSwappedOutPss;
15583                        dalvikPss += mi.dalvikPss;
15584                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15585                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15586                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15587                            dalvikSubitemSwapPss[j] +=
15588                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15589                        }
15590                        otherPss += mi.otherPss;
15591                        otherSwapPss += mi.otherSwappedOutPss;
15592                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15593                            long mem = mi.getOtherPss(j);
15594                            miscPss[j] += mem;
15595                            otherPss -= mem;
15596                            mem = mi.getOtherSwappedOutPss(j);
15597                            miscSwapPss[j] += mem;
15598                            otherSwapPss -= mem;
15599                        }
15600                        oomPss[0] += myTotalPss;
15601                        oomSwapPss[0] += myTotalSwapPss;
15602                        if (oomProcs[0] == null) {
15603                            oomProcs[0] = new ArrayList<MemItem>();
15604                        }
15605                        oomProcs[0].add(pssItem);
15606                    }
15607                }
15608            }
15609
15610            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15611
15612            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15613            final MemItem dalvikItem =
15614                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15615            if (dalvikSubitemPss.length > 0) {
15616                dalvikItem.subitems = new ArrayList<MemItem>();
15617                for (int j=0; j<dalvikSubitemPss.length; j++) {
15618                    final String name = Debug.MemoryInfo.getOtherLabel(
15619                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15620                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15621                                    dalvikSubitemSwapPss[j], j));
15622                }
15623            }
15624            catMems.add(dalvikItem);
15625            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15626            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15627                String label = Debug.MemoryInfo.getOtherLabel(j);
15628                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15629            }
15630
15631            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15632            for (int j=0; j<oomPss.length; j++) {
15633                if (oomPss[j] != 0) {
15634                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15635                            : DUMP_MEM_OOM_LABEL[j];
15636                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15637                            DUMP_MEM_OOM_ADJ[j]);
15638                    item.subitems = oomProcs[j];
15639                    oomMems.add(item);
15640                }
15641            }
15642
15643            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15644            if (!brief && !oomOnly && !isCompact) {
15645                pw.println();
15646                pw.println("Total PSS by process:");
15647                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15648                pw.println();
15649            }
15650            if (!isCompact) {
15651                pw.println("Total PSS by OOM adjustment:");
15652            }
15653            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15654            if (!brief && !oomOnly) {
15655                PrintWriter out = categoryPw != null ? categoryPw : pw;
15656                if (!isCompact) {
15657                    out.println();
15658                    out.println("Total PSS by category:");
15659                }
15660                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15661            }
15662            if (!isCompact) {
15663                pw.println();
15664            }
15665            MemInfoReader memInfo = new MemInfoReader();
15666            memInfo.readMemInfo();
15667            if (nativeProcTotalPss > 0) {
15668                synchronized (this) {
15669                    final long cachedKb = memInfo.getCachedSizeKb();
15670                    final long freeKb = memInfo.getFreeSizeKb();
15671                    final long zramKb = memInfo.getZramTotalSizeKb();
15672                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15673                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15674                            kernelKb*1024, nativeProcTotalPss*1024);
15675                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15676                            nativeProcTotalPss);
15677                }
15678            }
15679            if (!brief) {
15680                if (!isCompact) {
15681                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15682                    pw.print(" (status ");
15683                    switch (mLastMemoryLevel) {
15684                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15685                            pw.println("normal)");
15686                            break;
15687                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15688                            pw.println("moderate)");
15689                            break;
15690                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15691                            pw.println("low)");
15692                            break;
15693                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15694                            pw.println("critical)");
15695                            break;
15696                        default:
15697                            pw.print(mLastMemoryLevel);
15698                            pw.println(")");
15699                            break;
15700                    }
15701                    pw.print(" Free RAM: ");
15702                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15703                            + memInfo.getFreeSizeKb()));
15704                    pw.print(" (");
15705                    pw.print(stringifyKBSize(cachedPss));
15706                    pw.print(" cached pss + ");
15707                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15708                    pw.print(" cached kernel + ");
15709                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15710                    pw.println(" free)");
15711                } else {
15712                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15713                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15714                            + memInfo.getFreeSizeKb()); pw.print(",");
15715                    pw.println(totalPss - cachedPss);
15716                }
15717            }
15718            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15719                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15720                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15721            if (!isCompact) {
15722                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15723                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15724                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15725                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15726                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15727            } else {
15728                pw.print("lostram,"); pw.println(lostRAM);
15729            }
15730            if (!brief) {
15731                if (memInfo.getZramTotalSizeKb() != 0) {
15732                    if (!isCompact) {
15733                        pw.print("     ZRAM: ");
15734                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15735                                pw.print(" physical used for ");
15736                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15737                                        - memInfo.getSwapFreeSizeKb()));
15738                                pw.print(" in swap (");
15739                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15740                                pw.println(" total swap)");
15741                    } else {
15742                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15743                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15744                                pw.println(memInfo.getSwapFreeSizeKb());
15745                    }
15746                }
15747                final long[] ksm = getKsmInfo();
15748                if (!isCompact) {
15749                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15750                            || ksm[KSM_VOLATILE] != 0) {
15751                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15752                                pw.print(" saved from shared ");
15753                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15754                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15755                                pw.print(" unshared; ");
15756                                pw.print(stringifyKBSize(
15757                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15758                    }
15759                    pw.print("   Tuning: ");
15760                    pw.print(ActivityManager.staticGetMemoryClass());
15761                    pw.print(" (large ");
15762                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15763                    pw.print("), oom ");
15764                    pw.print(stringifySize(
15765                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15766                    pw.print(", restore limit ");
15767                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15768                    if (ActivityManager.isLowRamDeviceStatic()) {
15769                        pw.print(" (low-ram)");
15770                    }
15771                    if (ActivityManager.isHighEndGfx()) {
15772                        pw.print(" (high-end-gfx)");
15773                    }
15774                    pw.println();
15775                } else {
15776                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15777                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15778                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15779                    pw.print("tuning,");
15780                    pw.print(ActivityManager.staticGetMemoryClass());
15781                    pw.print(',');
15782                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15783                    pw.print(',');
15784                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15785                    if (ActivityManager.isLowRamDeviceStatic()) {
15786                        pw.print(",low-ram");
15787                    }
15788                    if (ActivityManager.isHighEndGfx()) {
15789                        pw.print(",high-end-gfx");
15790                    }
15791                    pw.println();
15792                }
15793            }
15794        }
15795    }
15796
15797    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15798            long memtrack, String name) {
15799        sb.append("  ");
15800        sb.append(ProcessList.makeOomAdjString(oomAdj));
15801        sb.append(' ');
15802        sb.append(ProcessList.makeProcStateString(procState));
15803        sb.append(' ');
15804        ProcessList.appendRamKb(sb, pss);
15805        sb.append(": ");
15806        sb.append(name);
15807        if (memtrack > 0) {
15808            sb.append(" (");
15809            sb.append(stringifyKBSize(memtrack));
15810            sb.append(" memtrack)");
15811        }
15812    }
15813
15814    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15815        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15816        sb.append(" (pid ");
15817        sb.append(mi.pid);
15818        sb.append(") ");
15819        sb.append(mi.adjType);
15820        sb.append('\n');
15821        if (mi.adjReason != null) {
15822            sb.append("                      ");
15823            sb.append(mi.adjReason);
15824            sb.append('\n');
15825        }
15826    }
15827
15828    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15829        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15830        for (int i=0, N=memInfos.size(); i<N; i++) {
15831            ProcessMemInfo mi = memInfos.get(i);
15832            infoMap.put(mi.pid, mi);
15833        }
15834        updateCpuStatsNow();
15835        long[] memtrackTmp = new long[1];
15836        synchronized (mProcessCpuTracker) {
15837            final int N = mProcessCpuTracker.countStats();
15838            for (int i=0; i<N; i++) {
15839                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15840                if (st.vsize > 0) {
15841                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15842                    if (pss > 0) {
15843                        if (infoMap.indexOfKey(st.pid) < 0) {
15844                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15845                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15846                            mi.pss = pss;
15847                            mi.memtrack = memtrackTmp[0];
15848                            memInfos.add(mi);
15849                        }
15850                    }
15851                }
15852            }
15853        }
15854
15855        long totalPss = 0;
15856        long totalMemtrack = 0;
15857        for (int i=0, N=memInfos.size(); i<N; i++) {
15858            ProcessMemInfo mi = memInfos.get(i);
15859            if (mi.pss == 0) {
15860                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15861                mi.memtrack = memtrackTmp[0];
15862            }
15863            totalPss += mi.pss;
15864            totalMemtrack += mi.memtrack;
15865        }
15866        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15867            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15868                if (lhs.oomAdj != rhs.oomAdj) {
15869                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15870                }
15871                if (lhs.pss != rhs.pss) {
15872                    return lhs.pss < rhs.pss ? 1 : -1;
15873                }
15874                return 0;
15875            }
15876        });
15877
15878        StringBuilder tag = new StringBuilder(128);
15879        StringBuilder stack = new StringBuilder(128);
15880        tag.append("Low on memory -- ");
15881        appendMemBucket(tag, totalPss, "total", false);
15882        appendMemBucket(stack, totalPss, "total", true);
15883
15884        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15885        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15886        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15887
15888        boolean firstLine = true;
15889        int lastOomAdj = Integer.MIN_VALUE;
15890        long extraNativeRam = 0;
15891        long extraNativeMemtrack = 0;
15892        long cachedPss = 0;
15893        for (int i=0, N=memInfos.size(); i<N; i++) {
15894            ProcessMemInfo mi = memInfos.get(i);
15895
15896            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15897                cachedPss += mi.pss;
15898            }
15899
15900            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15901                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15902                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15903                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15904                if (lastOomAdj != mi.oomAdj) {
15905                    lastOomAdj = mi.oomAdj;
15906                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15907                        tag.append(" / ");
15908                    }
15909                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15910                        if (firstLine) {
15911                            stack.append(":");
15912                            firstLine = false;
15913                        }
15914                        stack.append("\n\t at ");
15915                    } else {
15916                        stack.append("$");
15917                    }
15918                } else {
15919                    tag.append(" ");
15920                    stack.append("$");
15921                }
15922                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15923                    appendMemBucket(tag, mi.pss, mi.name, false);
15924                }
15925                appendMemBucket(stack, mi.pss, mi.name, true);
15926                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15927                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15928                    stack.append("(");
15929                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15930                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15931                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15932                            stack.append(":");
15933                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15934                        }
15935                    }
15936                    stack.append(")");
15937                }
15938            }
15939
15940            appendMemInfo(fullNativeBuilder, mi);
15941            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15942                // The short form only has native processes that are >= 512K.
15943                if (mi.pss >= 512) {
15944                    appendMemInfo(shortNativeBuilder, mi);
15945                } else {
15946                    extraNativeRam += mi.pss;
15947                    extraNativeMemtrack += mi.memtrack;
15948                }
15949            } else {
15950                // Short form has all other details, but if we have collected RAM
15951                // from smaller native processes let's dump a summary of that.
15952                if (extraNativeRam > 0) {
15953                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15954                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15955                    shortNativeBuilder.append('\n');
15956                    extraNativeRam = 0;
15957                }
15958                appendMemInfo(fullJavaBuilder, mi);
15959            }
15960        }
15961
15962        fullJavaBuilder.append("           ");
15963        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15964        fullJavaBuilder.append(": TOTAL");
15965        if (totalMemtrack > 0) {
15966            fullJavaBuilder.append(" (");
15967            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15968            fullJavaBuilder.append(" memtrack)");
15969        } else {
15970        }
15971        fullJavaBuilder.append("\n");
15972
15973        MemInfoReader memInfo = new MemInfoReader();
15974        memInfo.readMemInfo();
15975        final long[] infos = memInfo.getRawInfo();
15976
15977        StringBuilder memInfoBuilder = new StringBuilder(1024);
15978        Debug.getMemInfo(infos);
15979        memInfoBuilder.append("  MemInfo: ");
15980        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15981        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15982        memInfoBuilder.append(stringifyKBSize(
15983                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15984        memInfoBuilder.append(stringifyKBSize(
15985                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15986        memInfoBuilder.append(stringifyKBSize(
15987                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15988        memInfoBuilder.append("           ");
15989        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15990        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15991        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15992        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15993        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15994            memInfoBuilder.append("  ZRAM: ");
15995            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15996            memInfoBuilder.append(" RAM, ");
15997            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15998            memInfoBuilder.append(" swap total, ");
15999            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16000            memInfoBuilder.append(" swap free\n");
16001        }
16002        final long[] ksm = getKsmInfo();
16003        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16004                || ksm[KSM_VOLATILE] != 0) {
16005            memInfoBuilder.append("  KSM: ");
16006            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16007            memInfoBuilder.append(" saved from shared ");
16008            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16009            memInfoBuilder.append("\n       ");
16010            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16011            memInfoBuilder.append(" unshared; ");
16012            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16013            memInfoBuilder.append(" volatile\n");
16014        }
16015        memInfoBuilder.append("  Free RAM: ");
16016        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16017                + memInfo.getFreeSizeKb()));
16018        memInfoBuilder.append("\n");
16019        memInfoBuilder.append("  Used RAM: ");
16020        memInfoBuilder.append(stringifyKBSize(
16021                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16022        memInfoBuilder.append("\n");
16023        memInfoBuilder.append("  Lost RAM: ");
16024        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16025                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16026                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16027        memInfoBuilder.append("\n");
16028        Slog.i(TAG, "Low on memory:");
16029        Slog.i(TAG, shortNativeBuilder.toString());
16030        Slog.i(TAG, fullJavaBuilder.toString());
16031        Slog.i(TAG, memInfoBuilder.toString());
16032
16033        StringBuilder dropBuilder = new StringBuilder(1024);
16034        /*
16035        StringWriter oomSw = new StringWriter();
16036        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16037        StringWriter catSw = new StringWriter();
16038        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16039        String[] emptyArgs = new String[] { };
16040        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16041        oomPw.flush();
16042        String oomString = oomSw.toString();
16043        */
16044        dropBuilder.append("Low on memory:");
16045        dropBuilder.append(stack);
16046        dropBuilder.append('\n');
16047        dropBuilder.append(fullNativeBuilder);
16048        dropBuilder.append(fullJavaBuilder);
16049        dropBuilder.append('\n');
16050        dropBuilder.append(memInfoBuilder);
16051        dropBuilder.append('\n');
16052        /*
16053        dropBuilder.append(oomString);
16054        dropBuilder.append('\n');
16055        */
16056        StringWriter catSw = new StringWriter();
16057        synchronized (ActivityManagerService.this) {
16058            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16059            String[] emptyArgs = new String[] { };
16060            catPw.println();
16061            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16062            catPw.println();
16063            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16064                    false, false, null);
16065            catPw.println();
16066            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16067            catPw.flush();
16068        }
16069        dropBuilder.append(catSw.toString());
16070        addErrorToDropBox("lowmem", null, "system_server", null,
16071                null, tag.toString(), dropBuilder.toString(), null, null);
16072        //Slog.i(TAG, "Sent to dropbox:");
16073        //Slog.i(TAG, dropBuilder.toString());
16074        synchronized (ActivityManagerService.this) {
16075            long now = SystemClock.uptimeMillis();
16076            if (mLastMemUsageReportTime < now) {
16077                mLastMemUsageReportTime = now;
16078            }
16079        }
16080    }
16081
16082    /**
16083     * Searches array of arguments for the specified string
16084     * @param args array of argument strings
16085     * @param value value to search for
16086     * @return true if the value is contained in the array
16087     */
16088    private static boolean scanArgs(String[] args, String value) {
16089        if (args != null) {
16090            for (String arg : args) {
16091                if (value.equals(arg)) {
16092                    return true;
16093                }
16094            }
16095        }
16096        return false;
16097    }
16098
16099    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16100            ContentProviderRecord cpr, boolean always) {
16101        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16102
16103        if (!inLaunching || always) {
16104            synchronized (cpr) {
16105                cpr.launchingApp = null;
16106                cpr.notifyAll();
16107            }
16108            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16109            String names[] = cpr.info.authority.split(";");
16110            for (int j = 0; j < names.length; j++) {
16111                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16112            }
16113        }
16114
16115        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16116            ContentProviderConnection conn = cpr.connections.get(i);
16117            if (conn.waiting) {
16118                // If this connection is waiting for the provider, then we don't
16119                // need to mess with its process unless we are always removing
16120                // or for some reason the provider is not currently launching.
16121                if (inLaunching && !always) {
16122                    continue;
16123                }
16124            }
16125            ProcessRecord capp = conn.client;
16126            conn.dead = true;
16127            if (conn.stableCount > 0) {
16128                if (!capp.persistent && capp.thread != null
16129                        && capp.pid != 0
16130                        && capp.pid != MY_PID) {
16131                    capp.kill("depends on provider "
16132                            + cpr.name.flattenToShortString()
16133                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16134                }
16135            } else if (capp.thread != null && conn.provider.provider != null) {
16136                try {
16137                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16138                } catch (RemoteException e) {
16139                }
16140                // In the protocol here, we don't expect the client to correctly
16141                // clean up this connection, we'll just remove it.
16142                cpr.connections.remove(i);
16143                if (conn.client.conProviders.remove(conn)) {
16144                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16145                }
16146            }
16147        }
16148
16149        if (inLaunching && always) {
16150            mLaunchingProviders.remove(cpr);
16151        }
16152        return inLaunching;
16153    }
16154
16155    /**
16156     * Main code for cleaning up a process when it has gone away.  This is
16157     * called both as a result of the process dying, or directly when stopping
16158     * a process when running in single process mode.
16159     *
16160     * @return Returns true if the given process has been restarted, so the
16161     * app that was passed in must remain on the process lists.
16162     */
16163    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16164            boolean restarting, boolean allowRestart, int index) {
16165        if (index >= 0) {
16166            removeLruProcessLocked(app);
16167            ProcessList.remove(app.pid);
16168        }
16169
16170        mProcessesToGc.remove(app);
16171        mPendingPssProcesses.remove(app);
16172
16173        // Dismiss any open dialogs.
16174        if (app.crashDialog != null && !app.forceCrashReport) {
16175            app.crashDialog.dismiss();
16176            app.crashDialog = null;
16177        }
16178        if (app.anrDialog != null) {
16179            app.anrDialog.dismiss();
16180            app.anrDialog = null;
16181        }
16182        if (app.waitDialog != null) {
16183            app.waitDialog.dismiss();
16184            app.waitDialog = null;
16185        }
16186
16187        app.crashing = false;
16188        app.notResponding = false;
16189
16190        app.resetPackageList(mProcessStats);
16191        app.unlinkDeathRecipient();
16192        app.makeInactive(mProcessStats);
16193        app.waitingToKill = null;
16194        app.forcingToForeground = null;
16195        updateProcessForegroundLocked(app, false, false);
16196        app.foregroundActivities = false;
16197        app.hasShownUi = false;
16198        app.treatLikeActivity = false;
16199        app.hasAboveClient = false;
16200        app.hasClientActivities = false;
16201
16202        mServices.killServicesLocked(app, allowRestart);
16203
16204        boolean restart = false;
16205
16206        // Remove published content providers.
16207        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16208            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16209            final boolean always = app.bad || !allowRestart;
16210            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16211            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16212                // We left the provider in the launching list, need to
16213                // restart it.
16214                restart = true;
16215            }
16216
16217            cpr.provider = null;
16218            cpr.proc = null;
16219        }
16220        app.pubProviders.clear();
16221
16222        // Take care of any launching providers waiting for this process.
16223        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16224            restart = true;
16225        }
16226
16227        // Unregister from connected content providers.
16228        if (!app.conProviders.isEmpty()) {
16229            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16230                ContentProviderConnection conn = app.conProviders.get(i);
16231                conn.provider.connections.remove(conn);
16232                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16233                        conn.provider.name);
16234            }
16235            app.conProviders.clear();
16236        }
16237
16238        // At this point there may be remaining entries in mLaunchingProviders
16239        // where we were the only one waiting, so they are no longer of use.
16240        // Look for these and clean up if found.
16241        // XXX Commented out for now.  Trying to figure out a way to reproduce
16242        // the actual situation to identify what is actually going on.
16243        if (false) {
16244            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16245                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16246                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16247                    synchronized (cpr) {
16248                        cpr.launchingApp = null;
16249                        cpr.notifyAll();
16250                    }
16251                }
16252            }
16253        }
16254
16255        skipCurrentReceiverLocked(app);
16256
16257        // Unregister any receivers.
16258        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16259            removeReceiverLocked(app.receivers.valueAt(i));
16260        }
16261        app.receivers.clear();
16262
16263        // If the app is undergoing backup, tell the backup manager about it
16264        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16265            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16266                    + mBackupTarget.appInfo + " died during backup");
16267            try {
16268                IBackupManager bm = IBackupManager.Stub.asInterface(
16269                        ServiceManager.getService(Context.BACKUP_SERVICE));
16270                bm.agentDisconnected(app.info.packageName);
16271            } catch (RemoteException e) {
16272                // can't happen; backup manager is local
16273            }
16274        }
16275
16276        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16277            ProcessChangeItem item = mPendingProcessChanges.get(i);
16278            if (item.pid == app.pid) {
16279                mPendingProcessChanges.remove(i);
16280                mAvailProcessChanges.add(item);
16281            }
16282        }
16283        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16284                null).sendToTarget();
16285
16286        // If the caller is restarting this app, then leave it in its
16287        // current lists and let the caller take care of it.
16288        if (restarting) {
16289            return false;
16290        }
16291
16292        if (!app.persistent || app.isolated) {
16293            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16294                    "Removing non-persistent process during cleanup: " + app);
16295            removeProcessNameLocked(app.processName, app.uid);
16296            if (mHeavyWeightProcess == app) {
16297                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16298                        mHeavyWeightProcess.userId, 0));
16299                mHeavyWeightProcess = null;
16300            }
16301        } else if (!app.removed) {
16302            // This app is persistent, so we need to keep its record around.
16303            // If it is not already on the pending app list, add it there
16304            // and start a new process for it.
16305            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16306                mPersistentStartingProcesses.add(app);
16307                restart = true;
16308            }
16309        }
16310        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16311                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16312        mProcessesOnHold.remove(app);
16313
16314        if (app == mHomeProcess) {
16315            mHomeProcess = null;
16316        }
16317        if (app == mPreviousProcess) {
16318            mPreviousProcess = null;
16319        }
16320
16321        if (restart && !app.isolated) {
16322            // We have components that still need to be running in the
16323            // process, so re-launch it.
16324            if (index < 0) {
16325                ProcessList.remove(app.pid);
16326            }
16327            addProcessNameLocked(app);
16328            startProcessLocked(app, "restart", app.processName);
16329            return true;
16330        } else if (app.pid > 0 && app.pid != MY_PID) {
16331            // Goodbye!
16332            boolean removed;
16333            synchronized (mPidsSelfLocked) {
16334                mPidsSelfLocked.remove(app.pid);
16335                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16336            }
16337            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16338            if (app.isolated) {
16339                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16340            }
16341            app.setPid(0);
16342        }
16343        return false;
16344    }
16345
16346    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16347        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16348            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16349            if (cpr.launchingApp == app) {
16350                return true;
16351            }
16352        }
16353        return false;
16354    }
16355
16356    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16357        // Look through the content providers we are waiting to have launched,
16358        // and if any run in this process then either schedule a restart of
16359        // the process or kill the client waiting for it if this process has
16360        // gone bad.
16361        boolean restart = false;
16362        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16363            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16364            if (cpr.launchingApp == app) {
16365                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16366                    restart = true;
16367                } else {
16368                    removeDyingProviderLocked(app, cpr, true);
16369                }
16370            }
16371        }
16372        return restart;
16373    }
16374
16375    // =========================================================
16376    // SERVICES
16377    // =========================================================
16378
16379    @Override
16380    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16381            int flags) {
16382        enforceNotIsolatedCaller("getServices");
16383        synchronized (this) {
16384            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16385        }
16386    }
16387
16388    @Override
16389    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16390        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16391        synchronized (this) {
16392            return mServices.getRunningServiceControlPanelLocked(name);
16393        }
16394    }
16395
16396    @Override
16397    public ComponentName startService(IApplicationThread caller, Intent service,
16398            String resolvedType, String callingPackage, int userId)
16399            throws TransactionTooLargeException {
16400        enforceNotIsolatedCaller("startService");
16401        // Refuse possible leaked file descriptors
16402        if (service != null && service.hasFileDescriptors() == true) {
16403            throw new IllegalArgumentException("File descriptors passed in Intent");
16404        }
16405
16406        if (callingPackage == null) {
16407            throw new IllegalArgumentException("callingPackage cannot be null");
16408        }
16409
16410        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16411                "startService: " + service + " type=" + resolvedType);
16412        synchronized(this) {
16413            final int callingPid = Binder.getCallingPid();
16414            final int callingUid = Binder.getCallingUid();
16415            final long origId = Binder.clearCallingIdentity();
16416            ComponentName res = mServices.startServiceLocked(caller, service,
16417                    resolvedType, callingPid, callingUid, callingPackage, userId);
16418            Binder.restoreCallingIdentity(origId);
16419            return res;
16420        }
16421    }
16422
16423    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16424            String callingPackage, int userId)
16425            throws TransactionTooLargeException {
16426        synchronized(this) {
16427            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16428                    "startServiceInPackage: " + service + " type=" + resolvedType);
16429            final long origId = Binder.clearCallingIdentity();
16430            ComponentName res = mServices.startServiceLocked(null, service,
16431                    resolvedType, -1, uid, callingPackage, userId);
16432            Binder.restoreCallingIdentity(origId);
16433            return res;
16434        }
16435    }
16436
16437    @Override
16438    public int stopService(IApplicationThread caller, Intent service,
16439            String resolvedType, int userId) {
16440        enforceNotIsolatedCaller("stopService");
16441        // Refuse possible leaked file descriptors
16442        if (service != null && service.hasFileDescriptors() == true) {
16443            throw new IllegalArgumentException("File descriptors passed in Intent");
16444        }
16445
16446        synchronized(this) {
16447            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16448        }
16449    }
16450
16451    @Override
16452    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16453        enforceNotIsolatedCaller("peekService");
16454        // Refuse possible leaked file descriptors
16455        if (service != null && service.hasFileDescriptors() == true) {
16456            throw new IllegalArgumentException("File descriptors passed in Intent");
16457        }
16458
16459        if (callingPackage == null) {
16460            throw new IllegalArgumentException("callingPackage cannot be null");
16461        }
16462
16463        synchronized(this) {
16464            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16465        }
16466    }
16467
16468    @Override
16469    public boolean stopServiceToken(ComponentName className, IBinder token,
16470            int startId) {
16471        synchronized(this) {
16472            return mServices.stopServiceTokenLocked(className, token, startId);
16473        }
16474    }
16475
16476    @Override
16477    public void setServiceForeground(ComponentName className, IBinder token,
16478            int id, Notification notification, boolean removeNotification) {
16479        synchronized(this) {
16480            mServices.setServiceForegroundLocked(className, token, id, notification,
16481                    removeNotification);
16482        }
16483    }
16484
16485    @Override
16486    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16487            boolean requireFull, String name, String callerPackage) {
16488        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16489                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16490    }
16491
16492    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16493            String className, int flags) {
16494        boolean result = false;
16495        // For apps that don't have pre-defined UIDs, check for permission
16496        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16497            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16498                if (ActivityManager.checkUidPermission(
16499                        INTERACT_ACROSS_USERS,
16500                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16501                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16502                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16503                            + " requests FLAG_SINGLE_USER, but app does not hold "
16504                            + INTERACT_ACROSS_USERS;
16505                    Slog.w(TAG, msg);
16506                    throw new SecurityException(msg);
16507                }
16508                // Permission passed
16509                result = true;
16510            }
16511        } else if ("system".equals(componentProcessName)) {
16512            result = true;
16513        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16514            // Phone app and persistent apps are allowed to export singleuser providers.
16515            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16516                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16517        }
16518        if (DEBUG_MU) Slog.v(TAG_MU,
16519                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16520                + Integer.toHexString(flags) + ") = " + result);
16521        return result;
16522    }
16523
16524    /**
16525     * Checks to see if the caller is in the same app as the singleton
16526     * component, or the component is in a special app. It allows special apps
16527     * to export singleton components but prevents exporting singleton
16528     * components for regular apps.
16529     */
16530    boolean isValidSingletonCall(int callingUid, int componentUid) {
16531        int componentAppId = UserHandle.getAppId(componentUid);
16532        return UserHandle.isSameApp(callingUid, componentUid)
16533                || componentAppId == Process.SYSTEM_UID
16534                || componentAppId == Process.PHONE_UID
16535                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16536                        == PackageManager.PERMISSION_GRANTED;
16537    }
16538
16539    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16540            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16541            int userId) throws TransactionTooLargeException {
16542        enforceNotIsolatedCaller("bindService");
16543
16544        // Refuse possible leaked file descriptors
16545        if (service != null && service.hasFileDescriptors() == true) {
16546            throw new IllegalArgumentException("File descriptors passed in Intent");
16547        }
16548
16549        if (callingPackage == null) {
16550            throw new IllegalArgumentException("callingPackage cannot be null");
16551        }
16552
16553        synchronized(this) {
16554            return mServices.bindServiceLocked(caller, token, service,
16555                    resolvedType, connection, flags, callingPackage, userId);
16556        }
16557    }
16558
16559    public boolean unbindService(IServiceConnection connection) {
16560        synchronized (this) {
16561            return mServices.unbindServiceLocked(connection);
16562        }
16563    }
16564
16565    public void publishService(IBinder token, Intent intent, IBinder service) {
16566        // Refuse possible leaked file descriptors
16567        if (intent != null && intent.hasFileDescriptors() == true) {
16568            throw new IllegalArgumentException("File descriptors passed in Intent");
16569        }
16570
16571        synchronized(this) {
16572            if (!(token instanceof ServiceRecord)) {
16573                throw new IllegalArgumentException("Invalid service token");
16574            }
16575            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16576        }
16577    }
16578
16579    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16580        // Refuse possible leaked file descriptors
16581        if (intent != null && intent.hasFileDescriptors() == true) {
16582            throw new IllegalArgumentException("File descriptors passed in Intent");
16583        }
16584
16585        synchronized(this) {
16586            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16587        }
16588    }
16589
16590    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16591        synchronized(this) {
16592            if (!(token instanceof ServiceRecord)) {
16593                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16594                throw new IllegalArgumentException("Invalid service token");
16595            }
16596            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16597        }
16598    }
16599
16600    // =========================================================
16601    // BACKUP AND RESTORE
16602    // =========================================================
16603
16604    // Cause the target app to be launched if necessary and its backup agent
16605    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16606    // activity manager to announce its creation.
16607    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16608        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16609                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16610        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16611
16612        synchronized(this) {
16613            // !!! TODO: currently no check here that we're already bound
16614            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16615            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16616            synchronized (stats) {
16617                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16618            }
16619
16620            // Backup agent is now in use, its package can't be stopped.
16621            try {
16622                AppGlobals.getPackageManager().setPackageStoppedState(
16623                        app.packageName, false, UserHandle.getUserId(app.uid));
16624            } catch (RemoteException e) {
16625            } catch (IllegalArgumentException e) {
16626                Slog.w(TAG, "Failed trying to unstop package "
16627                        + app.packageName + ": " + e);
16628            }
16629
16630            BackupRecord r = new BackupRecord(ss, app, backupMode);
16631            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16632                    ? new ComponentName(app.packageName, app.backupAgentName)
16633                    : new ComponentName("android", "FullBackupAgent");
16634            // startProcessLocked() returns existing proc's record if it's already running
16635            ProcessRecord proc = startProcessLocked(app.processName, app,
16636                    false, 0, "backup", hostingName, false, false, false);
16637            if (proc == null) {
16638                Slog.e(TAG, "Unable to start backup agent process " + r);
16639                return false;
16640            }
16641
16642            r.app = proc;
16643            mBackupTarget = r;
16644            mBackupAppName = app.packageName;
16645
16646            // Try not to kill the process during backup
16647            updateOomAdjLocked(proc);
16648
16649            // If the process is already attached, schedule the creation of the backup agent now.
16650            // If it is not yet live, this will be done when it attaches to the framework.
16651            if (proc.thread != null) {
16652                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16653                try {
16654                    proc.thread.scheduleCreateBackupAgent(app,
16655                            compatibilityInfoForPackageLocked(app), backupMode);
16656                } catch (RemoteException e) {
16657                    // Will time out on the backup manager side
16658                }
16659            } else {
16660                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16661            }
16662            // Invariants: at this point, the target app process exists and the application
16663            // is either already running or in the process of coming up.  mBackupTarget and
16664            // mBackupAppName describe the app, so that when it binds back to the AM we
16665            // know that it's scheduled for a backup-agent operation.
16666        }
16667
16668        return true;
16669    }
16670
16671    @Override
16672    public void clearPendingBackup() {
16673        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16674        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16675
16676        synchronized (this) {
16677            mBackupTarget = null;
16678            mBackupAppName = null;
16679        }
16680    }
16681
16682    // A backup agent has just come up
16683    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16684        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16685                + " = " + agent);
16686
16687        synchronized(this) {
16688            if (!agentPackageName.equals(mBackupAppName)) {
16689                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16690                return;
16691            }
16692        }
16693
16694        long oldIdent = Binder.clearCallingIdentity();
16695        try {
16696            IBackupManager bm = IBackupManager.Stub.asInterface(
16697                    ServiceManager.getService(Context.BACKUP_SERVICE));
16698            bm.agentConnected(agentPackageName, agent);
16699        } catch (RemoteException e) {
16700            // can't happen; the backup manager service is local
16701        } catch (Exception e) {
16702            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16703            e.printStackTrace();
16704        } finally {
16705            Binder.restoreCallingIdentity(oldIdent);
16706        }
16707    }
16708
16709    // done with this agent
16710    public void unbindBackupAgent(ApplicationInfo appInfo) {
16711        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16712        if (appInfo == null) {
16713            Slog.w(TAG, "unbind backup agent for null app");
16714            return;
16715        }
16716
16717        synchronized(this) {
16718            try {
16719                if (mBackupAppName == null) {
16720                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16721                    return;
16722                }
16723
16724                if (!mBackupAppName.equals(appInfo.packageName)) {
16725                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16726                    return;
16727                }
16728
16729                // Not backing this app up any more; reset its OOM adjustment
16730                final ProcessRecord proc = mBackupTarget.app;
16731                updateOomAdjLocked(proc);
16732
16733                // If the app crashed during backup, 'thread' will be null here
16734                if (proc.thread != null) {
16735                    try {
16736                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16737                                compatibilityInfoForPackageLocked(appInfo));
16738                    } catch (Exception e) {
16739                        Slog.e(TAG, "Exception when unbinding backup agent:");
16740                        e.printStackTrace();
16741                    }
16742                }
16743            } finally {
16744                mBackupTarget = null;
16745                mBackupAppName = null;
16746            }
16747        }
16748    }
16749    // =========================================================
16750    // BROADCASTS
16751    // =========================================================
16752
16753    boolean isPendingBroadcastProcessLocked(int pid) {
16754        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16755                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16756    }
16757
16758    void skipPendingBroadcastLocked(int pid) {
16759            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16760            for (BroadcastQueue queue : mBroadcastQueues) {
16761                queue.skipPendingBroadcastLocked(pid);
16762            }
16763    }
16764
16765    // The app just attached; send any pending broadcasts that it should receive
16766    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16767        boolean didSomething = false;
16768        for (BroadcastQueue queue : mBroadcastQueues) {
16769            didSomething |= queue.sendPendingBroadcastsLocked(app);
16770        }
16771        return didSomething;
16772    }
16773
16774    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16775            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16776        enforceNotIsolatedCaller("registerReceiver");
16777        ArrayList<Intent> stickyIntents = null;
16778        ProcessRecord callerApp = null;
16779        int callingUid;
16780        int callingPid;
16781        synchronized(this) {
16782            if (caller != null) {
16783                callerApp = getRecordForAppLocked(caller);
16784                if (callerApp == null) {
16785                    throw new SecurityException(
16786                            "Unable to find app for caller " + caller
16787                            + " (pid=" + Binder.getCallingPid()
16788                            + ") when registering receiver " + receiver);
16789                }
16790                if (callerApp.info.uid != Process.SYSTEM_UID &&
16791                        !callerApp.pkgList.containsKey(callerPackage) &&
16792                        !"android".equals(callerPackage)) {
16793                    throw new SecurityException("Given caller package " + callerPackage
16794                            + " is not running in process " + callerApp);
16795                }
16796                callingUid = callerApp.info.uid;
16797                callingPid = callerApp.pid;
16798            } else {
16799                callerPackage = null;
16800                callingUid = Binder.getCallingUid();
16801                callingPid = Binder.getCallingPid();
16802            }
16803
16804            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16805                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16806
16807            Iterator<String> actions = filter.actionsIterator();
16808            if (actions == null) {
16809                ArrayList<String> noAction = new ArrayList<String>(1);
16810                noAction.add(null);
16811                actions = noAction.iterator();
16812            }
16813
16814            // Collect stickies of users
16815            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16816            while (actions.hasNext()) {
16817                String action = actions.next();
16818                for (int id : userIds) {
16819                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16820                    if (stickies != null) {
16821                        ArrayList<Intent> intents = stickies.get(action);
16822                        if (intents != null) {
16823                            if (stickyIntents == null) {
16824                                stickyIntents = new ArrayList<Intent>();
16825                            }
16826                            stickyIntents.addAll(intents);
16827                        }
16828                    }
16829                }
16830            }
16831        }
16832
16833        ArrayList<Intent> allSticky = null;
16834        if (stickyIntents != null) {
16835            final ContentResolver resolver = mContext.getContentResolver();
16836            // Look for any matching sticky broadcasts...
16837            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16838                Intent intent = stickyIntents.get(i);
16839                // If intent has scheme "content", it will need to acccess
16840                // provider that needs to lock mProviderMap in ActivityThread
16841                // and also it may need to wait application response, so we
16842                // cannot lock ActivityManagerService here.
16843                if (filter.match(resolver, intent, true, TAG) >= 0) {
16844                    if (allSticky == null) {
16845                        allSticky = new ArrayList<Intent>();
16846                    }
16847                    allSticky.add(intent);
16848                }
16849            }
16850        }
16851
16852        // The first sticky in the list is returned directly back to the client.
16853        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16854        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16855        if (receiver == null) {
16856            return sticky;
16857        }
16858
16859        synchronized (this) {
16860            if (callerApp != null && (callerApp.thread == null
16861                    || callerApp.thread.asBinder() != caller.asBinder())) {
16862                // Original caller already died
16863                return null;
16864            }
16865            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16866            if (rl == null) {
16867                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16868                        userId, receiver);
16869                if (rl.app != null) {
16870                    rl.app.receivers.add(rl);
16871                } else {
16872                    try {
16873                        receiver.asBinder().linkToDeath(rl, 0);
16874                    } catch (RemoteException e) {
16875                        return sticky;
16876                    }
16877                    rl.linkedToDeath = true;
16878                }
16879                mRegisteredReceivers.put(receiver.asBinder(), rl);
16880            } else if (rl.uid != callingUid) {
16881                throw new IllegalArgumentException(
16882                        "Receiver requested to register for uid " + callingUid
16883                        + " was previously registered for uid " + rl.uid);
16884            } else if (rl.pid != callingPid) {
16885                throw new IllegalArgumentException(
16886                        "Receiver requested to register for pid " + callingPid
16887                        + " was previously registered for pid " + rl.pid);
16888            } else if (rl.userId != userId) {
16889                throw new IllegalArgumentException(
16890                        "Receiver requested to register for user " + userId
16891                        + " was previously registered for user " + rl.userId);
16892            }
16893            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16894                    permission, callingUid, userId);
16895            rl.add(bf);
16896            if (!bf.debugCheck()) {
16897                Slog.w(TAG, "==> For Dynamic broadcast");
16898            }
16899            mReceiverResolver.addFilter(bf);
16900
16901            // Enqueue broadcasts for all existing stickies that match
16902            // this filter.
16903            if (allSticky != null) {
16904                ArrayList receivers = new ArrayList();
16905                receivers.add(bf);
16906
16907                final int stickyCount = allSticky.size();
16908                for (int i = 0; i < stickyCount; i++) {
16909                    Intent intent = allSticky.get(i);
16910                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16911                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16912                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16913                            null, 0, null, null, false, true, true, -1);
16914                    queue.enqueueParallelBroadcastLocked(r);
16915                    queue.scheduleBroadcastsLocked();
16916                }
16917            }
16918
16919            return sticky;
16920        }
16921    }
16922
16923    public void unregisterReceiver(IIntentReceiver receiver) {
16924        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16925
16926        final long origId = Binder.clearCallingIdentity();
16927        try {
16928            boolean doTrim = false;
16929
16930            synchronized(this) {
16931                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16932                if (rl != null) {
16933                    final BroadcastRecord r = rl.curBroadcast;
16934                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16935                        final boolean doNext = r.queue.finishReceiverLocked(
16936                                r, r.resultCode, r.resultData, r.resultExtras,
16937                                r.resultAbort, false);
16938                        if (doNext) {
16939                            doTrim = true;
16940                            r.queue.processNextBroadcast(false);
16941                        }
16942                    }
16943
16944                    if (rl.app != null) {
16945                        rl.app.receivers.remove(rl);
16946                    }
16947                    removeReceiverLocked(rl);
16948                    if (rl.linkedToDeath) {
16949                        rl.linkedToDeath = false;
16950                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16951                    }
16952                }
16953            }
16954
16955            // If we actually concluded any broadcasts, we might now be able
16956            // to trim the recipients' apps from our working set
16957            if (doTrim) {
16958                trimApplications();
16959                return;
16960            }
16961
16962        } finally {
16963            Binder.restoreCallingIdentity(origId);
16964        }
16965    }
16966
16967    void removeReceiverLocked(ReceiverList rl) {
16968        mRegisteredReceivers.remove(rl.receiver.asBinder());
16969        for (int i = rl.size() - 1; i >= 0; i--) {
16970            mReceiverResolver.removeFilter(rl.get(i));
16971        }
16972    }
16973
16974    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16975        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16976            ProcessRecord r = mLruProcesses.get(i);
16977            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16978                try {
16979                    r.thread.dispatchPackageBroadcast(cmd, packages);
16980                } catch (RemoteException ex) {
16981                }
16982            }
16983        }
16984    }
16985
16986    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16987            int callingUid, int[] users) {
16988        // TODO: come back and remove this assumption to triage all broadcasts
16989        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16990
16991        List<ResolveInfo> receivers = null;
16992        try {
16993            HashSet<ComponentName> singleUserReceivers = null;
16994            boolean scannedFirstReceivers = false;
16995            for (int user : users) {
16996                // Skip users that have Shell restrictions, with exception of always permitted
16997                // Shell broadcasts
16998                if (callingUid == Process.SHELL_UID
16999                        && mUserController.hasUserRestriction(
17000                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17001                        && !isPermittedShellBroadcast(intent)) {
17002                    continue;
17003                }
17004                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17005                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17006                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17007                    // If this is not the system user, we need to check for
17008                    // any receivers that should be filtered out.
17009                    for (int i=0; i<newReceivers.size(); i++) {
17010                        ResolveInfo ri = newReceivers.get(i);
17011                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17012                            newReceivers.remove(i);
17013                            i--;
17014                        }
17015                    }
17016                }
17017                if (newReceivers != null && newReceivers.size() == 0) {
17018                    newReceivers = null;
17019                }
17020                if (receivers == null) {
17021                    receivers = newReceivers;
17022                } else if (newReceivers != null) {
17023                    // We need to concatenate the additional receivers
17024                    // found with what we have do far.  This would be easy,
17025                    // but we also need to de-dup any receivers that are
17026                    // singleUser.
17027                    if (!scannedFirstReceivers) {
17028                        // Collect any single user receivers we had already retrieved.
17029                        scannedFirstReceivers = true;
17030                        for (int i=0; i<receivers.size(); i++) {
17031                            ResolveInfo ri = receivers.get(i);
17032                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17033                                ComponentName cn = new ComponentName(
17034                                        ri.activityInfo.packageName, ri.activityInfo.name);
17035                                if (singleUserReceivers == null) {
17036                                    singleUserReceivers = new HashSet<ComponentName>();
17037                                }
17038                                singleUserReceivers.add(cn);
17039                            }
17040                        }
17041                    }
17042                    // Add the new results to the existing results, tracking
17043                    // and de-dupping single user receivers.
17044                    for (int i=0; i<newReceivers.size(); i++) {
17045                        ResolveInfo ri = newReceivers.get(i);
17046                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17047                            ComponentName cn = new ComponentName(
17048                                    ri.activityInfo.packageName, ri.activityInfo.name);
17049                            if (singleUserReceivers == null) {
17050                                singleUserReceivers = new HashSet<ComponentName>();
17051                            }
17052                            if (!singleUserReceivers.contains(cn)) {
17053                                singleUserReceivers.add(cn);
17054                                receivers.add(ri);
17055                            }
17056                        } else {
17057                            receivers.add(ri);
17058                        }
17059                    }
17060                }
17061            }
17062        } catch (RemoteException ex) {
17063            // pm is in same process, this will never happen.
17064        }
17065        return receivers;
17066    }
17067
17068    private boolean isPermittedShellBroadcast(Intent intent) {
17069        // remote bugreport should always be allowed to be taken
17070        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17071    }
17072
17073    final int broadcastIntentLocked(ProcessRecord callerApp,
17074            String callerPackage, Intent intent, String resolvedType,
17075            IIntentReceiver resultTo, int resultCode, String resultData,
17076            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17077            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17078        intent = new Intent(intent);
17079
17080        // By default broadcasts do not go to stopped apps.
17081        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17082
17083        // If we have not finished booting, don't allow this to launch new processes.
17084        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17085            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17086        }
17087
17088        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17089                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17090                + " ordered=" + ordered + " userid=" + userId);
17091        if ((resultTo != null) && !ordered) {
17092            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17093        }
17094
17095        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17096                ALLOW_NON_FULL, "broadcast", callerPackage);
17097
17098        // Make sure that the user who is receiving this broadcast is running.
17099        // If not, we will just skip it. Make an exception for shutdown broadcasts
17100        // and upgrade steps.
17101
17102        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17103            if ((callingUid != Process.SYSTEM_UID
17104                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17105                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17106                Slog.w(TAG, "Skipping broadcast of " + intent
17107                        + ": user " + userId + " is stopped");
17108                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17109            }
17110        }
17111
17112        BroadcastOptions brOptions = null;
17113        if (bOptions != null) {
17114            brOptions = new BroadcastOptions(bOptions);
17115            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17116                // See if the caller is allowed to do this.  Note we are checking against
17117                // the actual real caller (not whoever provided the operation as say a
17118                // PendingIntent), because that who is actually supplied the arguments.
17119                if (checkComponentPermission(
17120                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17121                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17122                        != PackageManager.PERMISSION_GRANTED) {
17123                    String msg = "Permission Denial: " + intent.getAction()
17124                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17125                            + ", uid=" + callingUid + ")"
17126                            + " requires "
17127                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17128                    Slog.w(TAG, msg);
17129                    throw new SecurityException(msg);
17130                }
17131            }
17132        }
17133
17134        // Verify that protected broadcasts are only being sent by system code,
17135        // and that system code is only sending protected broadcasts.
17136        final String action = intent.getAction();
17137        final boolean isProtectedBroadcast;
17138        try {
17139            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17140        } catch (RemoteException e) {
17141            Slog.w(TAG, "Remote exception", e);
17142            return ActivityManager.BROADCAST_SUCCESS;
17143        }
17144
17145        final boolean isCallerSystem;
17146        switch (UserHandle.getAppId(callingUid)) {
17147            case Process.ROOT_UID:
17148            case Process.SYSTEM_UID:
17149            case Process.PHONE_UID:
17150            case Process.BLUETOOTH_UID:
17151            case Process.NFC_UID:
17152                isCallerSystem = true;
17153                break;
17154            default:
17155                isCallerSystem = (callerApp != null) && callerApp.persistent;
17156                break;
17157        }
17158
17159        if (isCallerSystem) {
17160            if (isProtectedBroadcast
17161                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17162                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17163                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17164                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17165                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17166                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17167                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17168                // Broadcast is either protected, or it's a public action that
17169                // we've relaxed, so it's fine for system internals to send.
17170            } else {
17171                // The vast majority of broadcasts sent from system internals
17172                // should be protected to avoid security holes, so yell loudly
17173                // to ensure we examine these cases.
17174                Log.wtf(TAG, "Sending non-protected broadcast " + action
17175                        + " from system", new Throwable());
17176            }
17177
17178        } else {
17179            if (isProtectedBroadcast) {
17180                String msg = "Permission Denial: not allowed to send broadcast "
17181                        + action + " from pid="
17182                        + callingPid + ", uid=" + callingUid;
17183                Slog.w(TAG, msg);
17184                throw new SecurityException(msg);
17185
17186            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17187                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17188                // Special case for compatibility: we don't want apps to send this,
17189                // but historically it has not been protected and apps may be using it
17190                // to poke their own app widget.  So, instead of making it protected,
17191                // just limit it to the caller.
17192                if (callerPackage == null) {
17193                    String msg = "Permission Denial: not allowed to send broadcast "
17194                            + action + " from unknown caller.";
17195                    Slog.w(TAG, msg);
17196                    throw new SecurityException(msg);
17197                } else if (intent.getComponent() != null) {
17198                    // They are good enough to send to an explicit component...  verify
17199                    // it is being sent to the calling app.
17200                    if (!intent.getComponent().getPackageName().equals(
17201                            callerPackage)) {
17202                        String msg = "Permission Denial: not allowed to send broadcast "
17203                                + action + " to "
17204                                + intent.getComponent().getPackageName() + " from "
17205                                + callerPackage;
17206                        Slog.w(TAG, msg);
17207                        throw new SecurityException(msg);
17208                    }
17209                } else {
17210                    // Limit broadcast to their own package.
17211                    intent.setPackage(callerPackage);
17212                }
17213            }
17214        }
17215
17216        if (action != null) {
17217            switch (action) {
17218                case Intent.ACTION_UID_REMOVED:
17219                case Intent.ACTION_PACKAGE_REMOVED:
17220                case Intent.ACTION_PACKAGE_CHANGED:
17221                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17222                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17223                case Intent.ACTION_PACKAGES_SUSPENDED:
17224                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17225                    // Handle special intents: if this broadcast is from the package
17226                    // manager about a package being removed, we need to remove all of
17227                    // its activities from the history stack.
17228                    if (checkComponentPermission(
17229                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17230                            callingPid, callingUid, -1, true)
17231                            != PackageManager.PERMISSION_GRANTED) {
17232                        String msg = "Permission Denial: " + intent.getAction()
17233                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17234                                + ", uid=" + callingUid + ")"
17235                                + " requires "
17236                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17237                        Slog.w(TAG, msg);
17238                        throw new SecurityException(msg);
17239                    }
17240                    switch (action) {
17241                        case Intent.ACTION_UID_REMOVED:
17242                            final Bundle intentExtras = intent.getExtras();
17243                            final int uid = intentExtras != null
17244                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17245                            if (uid >= 0) {
17246                                mBatteryStatsService.removeUid(uid);
17247                                mAppOpsService.uidRemoved(uid);
17248                            }
17249                            break;
17250                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17251                            // If resources are unavailable just force stop all those packages
17252                            // and flush the attribute cache as well.
17253                            String list[] =
17254                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17255                            if (list != null && list.length > 0) {
17256                                for (int i = 0; i < list.length; i++) {
17257                                    forceStopPackageLocked(list[i], -1, false, true, true,
17258                                            false, false, userId, "storage unmount");
17259                                }
17260                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17261                                sendPackageBroadcastLocked(
17262                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17263                                        userId);
17264                            }
17265                            break;
17266                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17267                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17268                            break;
17269                        case Intent.ACTION_PACKAGE_REMOVED:
17270                        case Intent.ACTION_PACKAGE_CHANGED:
17271                            Uri data = intent.getData();
17272                            String ssp;
17273                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17274                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17275                                final boolean replacing =
17276                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17277                                final boolean killProcess =
17278                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17279                                final boolean fullUninstall = removed && !replacing;
17280                                if (killProcess) {
17281                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17282                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17283                                            false, true, true, false, fullUninstall, userId,
17284                                            removed ? "pkg removed" : "pkg changed");
17285                                }
17286                                if (removed) {
17287                                    final int cmd = killProcess
17288                                            ? IApplicationThread.PACKAGE_REMOVED
17289                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17290                                    sendPackageBroadcastLocked(cmd,
17291                                            new String[] {ssp}, userId);
17292                                    if (fullUninstall) {
17293                                        mAppOpsService.packageRemoved(
17294                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17295
17296                                        // Remove all permissions granted from/to this package
17297                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17298
17299                                        removeTasksByPackageNameLocked(ssp, userId);
17300                                        mBatteryStatsService.notePackageUninstalled(ssp);
17301                                    }
17302                                } else {
17303                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17304                                            intent.getStringArrayExtra(
17305                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17306                                }
17307                            }
17308                            break;
17309                        case Intent.ACTION_PACKAGES_SUSPENDED:
17310                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17311                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17312                                    intent.getAction());
17313                            final String[] packageNames = intent.getStringArrayExtra(
17314                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17315                            final int userHandle = intent.getIntExtra(
17316                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17317
17318                            synchronized(ActivityManagerService.this) {
17319                                mRecentTasks.onPackagesSuspendedChanged(
17320                                        packageNames, suspended, userHandle);
17321                            }
17322                            break;
17323                    }
17324                    break;
17325                case Intent.ACTION_PACKAGE_REPLACED:
17326                {
17327                    final Uri data = intent.getData();
17328                    final String ssp;
17329                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17330                        final ApplicationInfo aInfo =
17331                                getPackageManagerInternalLocked().getApplicationInfo(
17332                                        ssp,
17333                                        userId);
17334                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17335                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17336                                new String[] {ssp}, userId);
17337                    }
17338                    break;
17339                }
17340                case Intent.ACTION_PACKAGE_ADDED:
17341                {
17342                    // Special case for adding a package: by default turn on compatibility mode.
17343                    Uri data = intent.getData();
17344                    String ssp;
17345                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17346                        final boolean replacing =
17347                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17348                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17349
17350                        try {
17351                            ApplicationInfo ai = AppGlobals.getPackageManager().
17352                                    getApplicationInfo(ssp, 0, 0);
17353                            mBatteryStatsService.notePackageInstalled(ssp,
17354                                    ai != null ? ai.versionCode : 0);
17355                        } catch (RemoteException e) {
17356                        }
17357                    }
17358                    break;
17359                }
17360                case Intent.ACTION_TIMEZONE_CHANGED:
17361                    // If this is the time zone changed action, queue up a message that will reset
17362                    // the timezone of all currently running processes. This message will get
17363                    // queued up before the broadcast happens.
17364                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17365                    break;
17366                case Intent.ACTION_TIME_CHANGED:
17367                    // If the user set the time, let all running processes know.
17368                    final int is24Hour =
17369                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17370                                    : 0;
17371                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17372                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17373                    synchronized (stats) {
17374                        stats.noteCurrentTimeChangedLocked();
17375                    }
17376                    break;
17377                case Intent.ACTION_CLEAR_DNS_CACHE:
17378                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17379                    break;
17380                case Proxy.PROXY_CHANGE_ACTION:
17381                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17382                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17383                    break;
17384                case android.hardware.Camera.ACTION_NEW_PICTURE:
17385                case android.hardware.Camera.ACTION_NEW_VIDEO:
17386                    // These broadcasts are no longer allowed by the system, since they can
17387                    // cause significant thrashing at a crictical point (using the camera).
17388                    // Apps should use JobScehduler to monitor for media provider changes.
17389                    Slog.w(TAG, action + " no longer allowed; dropping from "
17390                            + UserHandle.formatUid(callingUid));
17391                    // Lie; we don't want to crash the app.
17392                    return ActivityManager.BROADCAST_SUCCESS;
17393            }
17394        }
17395
17396        // Add to the sticky list if requested.
17397        if (sticky) {
17398            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17399                    callingPid, callingUid)
17400                    != PackageManager.PERMISSION_GRANTED) {
17401                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17402                        + callingPid + ", uid=" + callingUid
17403                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17404                Slog.w(TAG, msg);
17405                throw new SecurityException(msg);
17406            }
17407            if (requiredPermissions != null && requiredPermissions.length > 0) {
17408                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17409                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17410                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17411            }
17412            if (intent.getComponent() != null) {
17413                throw new SecurityException(
17414                        "Sticky broadcasts can't target a specific component");
17415            }
17416            // We use userId directly here, since the "all" target is maintained
17417            // as a separate set of sticky broadcasts.
17418            if (userId != UserHandle.USER_ALL) {
17419                // But first, if this is not a broadcast to all users, then
17420                // make sure it doesn't conflict with an existing broadcast to
17421                // all users.
17422                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17423                        UserHandle.USER_ALL);
17424                if (stickies != null) {
17425                    ArrayList<Intent> list = stickies.get(intent.getAction());
17426                    if (list != null) {
17427                        int N = list.size();
17428                        int i;
17429                        for (i=0; i<N; i++) {
17430                            if (intent.filterEquals(list.get(i))) {
17431                                throw new IllegalArgumentException(
17432                                        "Sticky broadcast " + intent + " for user "
17433                                        + userId + " conflicts with existing global broadcast");
17434                            }
17435                        }
17436                    }
17437                }
17438            }
17439            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17440            if (stickies == null) {
17441                stickies = new ArrayMap<>();
17442                mStickyBroadcasts.put(userId, stickies);
17443            }
17444            ArrayList<Intent> list = stickies.get(intent.getAction());
17445            if (list == null) {
17446                list = new ArrayList<>();
17447                stickies.put(intent.getAction(), list);
17448            }
17449            final int stickiesCount = list.size();
17450            int i;
17451            for (i = 0; i < stickiesCount; i++) {
17452                if (intent.filterEquals(list.get(i))) {
17453                    // This sticky already exists, replace it.
17454                    list.set(i, new Intent(intent));
17455                    break;
17456                }
17457            }
17458            if (i >= stickiesCount) {
17459                list.add(new Intent(intent));
17460            }
17461        }
17462
17463        int[] users;
17464        if (userId == UserHandle.USER_ALL) {
17465            // Caller wants broadcast to go to all started users.
17466            users = mUserController.getStartedUserArrayLocked();
17467        } else {
17468            // Caller wants broadcast to go to one specific user.
17469            users = new int[] {userId};
17470        }
17471
17472        // Figure out who all will receive this broadcast.
17473        List receivers = null;
17474        List<BroadcastFilter> registeredReceivers = null;
17475        // Need to resolve the intent to interested receivers...
17476        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17477                 == 0) {
17478            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17479        }
17480        if (intent.getComponent() == null) {
17481            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17482                // Query one target user at a time, excluding shell-restricted users
17483                for (int i = 0; i < users.length; i++) {
17484                    if (mUserController.hasUserRestriction(
17485                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17486                        continue;
17487                    }
17488                    List<BroadcastFilter> registeredReceiversForUser =
17489                            mReceiverResolver.queryIntent(intent,
17490                                    resolvedType, false, users[i]);
17491                    if (registeredReceivers == null) {
17492                        registeredReceivers = registeredReceiversForUser;
17493                    } else if (registeredReceiversForUser != null) {
17494                        registeredReceivers.addAll(registeredReceiversForUser);
17495                    }
17496                }
17497            } else {
17498                registeredReceivers = mReceiverResolver.queryIntent(intent,
17499                        resolvedType, false, userId);
17500            }
17501        }
17502
17503        final boolean replacePending =
17504                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17505
17506        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17507                + " replacePending=" + replacePending);
17508
17509        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17510        if (!ordered && NR > 0) {
17511            // If we are not serializing this broadcast, then send the
17512            // registered receivers separately so they don't wait for the
17513            // components to be launched.
17514            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17515            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17516                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17517                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17518                    resultExtras, ordered, sticky, false, userId);
17519            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17520            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17521            if (!replaced) {
17522                queue.enqueueParallelBroadcastLocked(r);
17523                queue.scheduleBroadcastsLocked();
17524            }
17525            registeredReceivers = null;
17526            NR = 0;
17527        }
17528
17529        // Merge into one list.
17530        int ir = 0;
17531        if (receivers != null) {
17532            // A special case for PACKAGE_ADDED: do not allow the package
17533            // being added to see this broadcast.  This prevents them from
17534            // using this as a back door to get run as soon as they are
17535            // installed.  Maybe in the future we want to have a special install
17536            // broadcast or such for apps, but we'd like to deliberately make
17537            // this decision.
17538            String skipPackages[] = null;
17539            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17540                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17541                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17542                Uri data = intent.getData();
17543                if (data != null) {
17544                    String pkgName = data.getSchemeSpecificPart();
17545                    if (pkgName != null) {
17546                        skipPackages = new String[] { pkgName };
17547                    }
17548                }
17549            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17550                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17551            }
17552            if (skipPackages != null && (skipPackages.length > 0)) {
17553                for (String skipPackage : skipPackages) {
17554                    if (skipPackage != null) {
17555                        int NT = receivers.size();
17556                        for (int it=0; it<NT; it++) {
17557                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17558                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17559                                receivers.remove(it);
17560                                it--;
17561                                NT--;
17562                            }
17563                        }
17564                    }
17565                }
17566            }
17567
17568            int NT = receivers != null ? receivers.size() : 0;
17569            int it = 0;
17570            ResolveInfo curt = null;
17571            BroadcastFilter curr = null;
17572            while (it < NT && ir < NR) {
17573                if (curt == null) {
17574                    curt = (ResolveInfo)receivers.get(it);
17575                }
17576                if (curr == null) {
17577                    curr = registeredReceivers.get(ir);
17578                }
17579                if (curr.getPriority() >= curt.priority) {
17580                    // Insert this broadcast record into the final list.
17581                    receivers.add(it, curr);
17582                    ir++;
17583                    curr = null;
17584                    it++;
17585                    NT++;
17586                } else {
17587                    // Skip to the next ResolveInfo in the final list.
17588                    it++;
17589                    curt = null;
17590                }
17591            }
17592        }
17593        while (ir < NR) {
17594            if (receivers == null) {
17595                receivers = new ArrayList();
17596            }
17597            receivers.add(registeredReceivers.get(ir));
17598            ir++;
17599        }
17600
17601        if ((receivers != null && receivers.size() > 0)
17602                || resultTo != null) {
17603            BroadcastQueue queue = broadcastQueueForIntent(intent);
17604            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17605                    callerPackage, callingPid, callingUid, resolvedType,
17606                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17607                    resultData, resultExtras, ordered, sticky, false, userId);
17608
17609            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17610                    + ": prev had " + queue.mOrderedBroadcasts.size());
17611            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17612                    "Enqueueing broadcast " + r.intent.getAction());
17613
17614            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17615            if (!replaced) {
17616                queue.enqueueOrderedBroadcastLocked(r);
17617                queue.scheduleBroadcastsLocked();
17618            }
17619        }
17620
17621        return ActivityManager.BROADCAST_SUCCESS;
17622    }
17623
17624    final Intent verifyBroadcastLocked(Intent intent) {
17625        // Refuse possible leaked file descriptors
17626        if (intent != null && intent.hasFileDescriptors() == true) {
17627            throw new IllegalArgumentException("File descriptors passed in Intent");
17628        }
17629
17630        int flags = intent.getFlags();
17631
17632        if (!mProcessesReady) {
17633            // if the caller really truly claims to know what they're doing, go
17634            // ahead and allow the broadcast without launching any receivers
17635            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17636                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17637            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17638                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17639                        + " before boot completion");
17640                throw new IllegalStateException("Cannot broadcast before boot completed");
17641            }
17642        }
17643
17644        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17645            throw new IllegalArgumentException(
17646                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17647        }
17648
17649        return intent;
17650    }
17651
17652    public final int broadcastIntent(IApplicationThread caller,
17653            Intent intent, String resolvedType, IIntentReceiver resultTo,
17654            int resultCode, String resultData, Bundle resultExtras,
17655            String[] requiredPermissions, int appOp, Bundle bOptions,
17656            boolean serialized, boolean sticky, int userId) {
17657        enforceNotIsolatedCaller("broadcastIntent");
17658        synchronized(this) {
17659            intent = verifyBroadcastLocked(intent);
17660
17661            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17662            final int callingPid = Binder.getCallingPid();
17663            final int callingUid = Binder.getCallingUid();
17664            final long origId = Binder.clearCallingIdentity();
17665            int res = broadcastIntentLocked(callerApp,
17666                    callerApp != null ? callerApp.info.packageName : null,
17667                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17668                    requiredPermissions, appOp, bOptions, serialized, sticky,
17669                    callingPid, callingUid, userId);
17670            Binder.restoreCallingIdentity(origId);
17671            return res;
17672        }
17673    }
17674
17675
17676    int broadcastIntentInPackage(String packageName, int uid,
17677            Intent intent, String resolvedType, IIntentReceiver resultTo,
17678            int resultCode, String resultData, Bundle resultExtras,
17679            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17680            int userId) {
17681        synchronized(this) {
17682            intent = verifyBroadcastLocked(intent);
17683
17684            final long origId = Binder.clearCallingIdentity();
17685            String[] requiredPermissions = requiredPermission == null ? null
17686                    : new String[] {requiredPermission};
17687            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17688                    resultTo, resultCode, resultData, resultExtras,
17689                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17690                    sticky, -1, uid, userId);
17691            Binder.restoreCallingIdentity(origId);
17692            return res;
17693        }
17694    }
17695
17696    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17697        // Refuse possible leaked file descriptors
17698        if (intent != null && intent.hasFileDescriptors() == true) {
17699            throw new IllegalArgumentException("File descriptors passed in Intent");
17700        }
17701
17702        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17703                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17704
17705        synchronized(this) {
17706            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17707                    != PackageManager.PERMISSION_GRANTED) {
17708                String msg = "Permission Denial: unbroadcastIntent() from pid="
17709                        + Binder.getCallingPid()
17710                        + ", uid=" + Binder.getCallingUid()
17711                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17712                Slog.w(TAG, msg);
17713                throw new SecurityException(msg);
17714            }
17715            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17716            if (stickies != null) {
17717                ArrayList<Intent> list = stickies.get(intent.getAction());
17718                if (list != null) {
17719                    int N = list.size();
17720                    int i;
17721                    for (i=0; i<N; i++) {
17722                        if (intent.filterEquals(list.get(i))) {
17723                            list.remove(i);
17724                            break;
17725                        }
17726                    }
17727                    if (list.size() <= 0) {
17728                        stickies.remove(intent.getAction());
17729                    }
17730                }
17731                if (stickies.size() <= 0) {
17732                    mStickyBroadcasts.remove(userId);
17733                }
17734            }
17735        }
17736    }
17737
17738    void backgroundServicesFinishedLocked(int userId) {
17739        for (BroadcastQueue queue : mBroadcastQueues) {
17740            queue.backgroundServicesFinishedLocked(userId);
17741        }
17742    }
17743
17744    public void finishReceiver(IBinder who, int resultCode, String resultData,
17745            Bundle resultExtras, boolean resultAbort, int flags) {
17746        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17747
17748        // Refuse possible leaked file descriptors
17749        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17750            throw new IllegalArgumentException("File descriptors passed in Bundle");
17751        }
17752
17753        final long origId = Binder.clearCallingIdentity();
17754        try {
17755            boolean doNext = false;
17756            BroadcastRecord r;
17757
17758            synchronized(this) {
17759                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17760                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17761                r = queue.getMatchingOrderedReceiver(who);
17762                if (r != null) {
17763                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17764                        resultData, resultExtras, resultAbort, true);
17765                }
17766            }
17767
17768            if (doNext) {
17769                r.queue.processNextBroadcast(false);
17770            }
17771            trimApplications();
17772        } finally {
17773            Binder.restoreCallingIdentity(origId);
17774        }
17775    }
17776
17777    // =========================================================
17778    // INSTRUMENTATION
17779    // =========================================================
17780
17781    public boolean startInstrumentation(ComponentName className,
17782            String profileFile, int flags, Bundle arguments,
17783            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17784            int userId, String abiOverride) {
17785        enforceNotIsolatedCaller("startInstrumentation");
17786        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17787                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17788        // Refuse possible leaked file descriptors
17789        if (arguments != null && arguments.hasFileDescriptors()) {
17790            throw new IllegalArgumentException("File descriptors passed in Bundle");
17791        }
17792
17793        synchronized(this) {
17794            InstrumentationInfo ii = null;
17795            ApplicationInfo ai = null;
17796            try {
17797                ii = mContext.getPackageManager().getInstrumentationInfo(
17798                    className, STOCK_PM_FLAGS);
17799                ai = AppGlobals.getPackageManager().getApplicationInfo(
17800                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17801            } catch (PackageManager.NameNotFoundException e) {
17802            } catch (RemoteException e) {
17803            }
17804            if (ii == null) {
17805                reportStartInstrumentationFailureLocked(watcher, className,
17806                        "Unable to find instrumentation info for: " + className);
17807                return false;
17808            }
17809            if (ai == null) {
17810                reportStartInstrumentationFailureLocked(watcher, className,
17811                        "Unable to find instrumentation target package: " + ii.targetPackage);
17812                return false;
17813            }
17814            if (!ai.hasCode()) {
17815                reportStartInstrumentationFailureLocked(watcher, className,
17816                        "Instrumentation target has no code: " + ii.targetPackage);
17817                return false;
17818            }
17819
17820            int match = mContext.getPackageManager().checkSignatures(
17821                    ii.targetPackage, ii.packageName);
17822            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17823                String msg = "Permission Denial: starting instrumentation "
17824                        + className + " from pid="
17825                        + Binder.getCallingPid()
17826                        + ", uid=" + Binder.getCallingPid()
17827                        + " not allowed because package " + ii.packageName
17828                        + " does not have a signature matching the target "
17829                        + ii.targetPackage;
17830                reportStartInstrumentationFailureLocked(watcher, className, msg);
17831                throw new SecurityException(msg);
17832            }
17833
17834            final long origId = Binder.clearCallingIdentity();
17835            // Instrumentation can kill and relaunch even persistent processes
17836            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17837                    "start instr");
17838            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17839            app.instrumentationClass = className;
17840            app.instrumentationInfo = ai;
17841            app.instrumentationProfileFile = profileFile;
17842            app.instrumentationArguments = arguments;
17843            app.instrumentationWatcher = watcher;
17844            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17845            app.instrumentationResultClass = className;
17846            Binder.restoreCallingIdentity(origId);
17847        }
17848
17849        return true;
17850    }
17851
17852    /**
17853     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17854     * error to the logs, but if somebody is watching, send the report there too.  This enables
17855     * the "am" command to report errors with more information.
17856     *
17857     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17858     * @param cn The component name of the instrumentation.
17859     * @param report The error report.
17860     */
17861    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17862            ComponentName cn, String report) {
17863        Slog.w(TAG, report);
17864        if (watcher != null) {
17865            Bundle results = new Bundle();
17866            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17867            results.putString("Error", report);
17868            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17869        }
17870    }
17871
17872    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17873        if (app.instrumentationWatcher != null) {
17874            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17875                    app.instrumentationClass, resultCode, results);
17876        }
17877
17878        // Can't call out of the system process with a lock held, so post a message.
17879        if (app.instrumentationUiAutomationConnection != null) {
17880            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17881                    app.instrumentationUiAutomationConnection).sendToTarget();
17882        }
17883
17884        app.instrumentationWatcher = null;
17885        app.instrumentationUiAutomationConnection = null;
17886        app.instrumentationClass = null;
17887        app.instrumentationInfo = null;
17888        app.instrumentationProfileFile = null;
17889        app.instrumentationArguments = null;
17890
17891        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17892                "finished inst");
17893    }
17894
17895    public void finishInstrumentation(IApplicationThread target,
17896            int resultCode, Bundle results) {
17897        int userId = UserHandle.getCallingUserId();
17898        // Refuse possible leaked file descriptors
17899        if (results != null && results.hasFileDescriptors()) {
17900            throw new IllegalArgumentException("File descriptors passed in Intent");
17901        }
17902
17903        synchronized(this) {
17904            ProcessRecord app = getRecordForAppLocked(target);
17905            if (app == null) {
17906                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17907                return;
17908            }
17909            final long origId = Binder.clearCallingIdentity();
17910            finishInstrumentationLocked(app, resultCode, results);
17911            Binder.restoreCallingIdentity(origId);
17912        }
17913    }
17914
17915    // =========================================================
17916    // CONFIGURATION
17917    // =========================================================
17918
17919    public ConfigurationInfo getDeviceConfigurationInfo() {
17920        ConfigurationInfo config = new ConfigurationInfo();
17921        synchronized (this) {
17922            config.reqTouchScreen = mConfiguration.touchscreen;
17923            config.reqKeyboardType = mConfiguration.keyboard;
17924            config.reqNavigation = mConfiguration.navigation;
17925            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17926                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17927                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17928            }
17929            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17930                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17931                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17932            }
17933            config.reqGlEsVersion = GL_ES_VERSION;
17934        }
17935        return config;
17936    }
17937
17938    ActivityStack getFocusedStack() {
17939        return mStackSupervisor.getFocusedStack();
17940    }
17941
17942    @Override
17943    public int getFocusedStackId() throws RemoteException {
17944        ActivityStack focusedStack = getFocusedStack();
17945        if (focusedStack != null) {
17946            return focusedStack.getStackId();
17947        }
17948        return -1;
17949    }
17950
17951    public Configuration getConfiguration() {
17952        Configuration ci;
17953        synchronized(this) {
17954            ci = new Configuration(mConfiguration);
17955            ci.userSetLocale = false;
17956        }
17957        return ci;
17958    }
17959
17960    @Override
17961    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17962        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17963        synchronized (this) {
17964            mSuppressResizeConfigChanges = suppress;
17965        }
17966    }
17967
17968    @Override
17969    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17970        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17971        if (fromStackId == HOME_STACK_ID) {
17972            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17973        }
17974        synchronized (this) {
17975            final long origId = Binder.clearCallingIdentity();
17976            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17977            if (stack != null) {
17978                mWindowManager.deferSurfaceLayout();
17979                try {
17980                    if (fromStackId == DOCKED_STACK_ID) {
17981
17982                        // We are moving all tasks from the docked stack to the fullscreen stack,
17983                        // which is dismissing the docked stack, so resize all other stacks to
17984                        // fullscreen here already so we don't end up with resize trashing.
17985                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17986                            if (StackId.isResizeableByDockedStack(i)) {
17987                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17988                                if (otherStack != null) {
17989                                    mStackSupervisor.resizeStackLocked(i,
17990                                            null, null, null, PRESERVE_WINDOWS,
17991                                            true /* allowResizeInDockedMode */);
17992                                }
17993                            }
17994                        }
17995                    }
17996                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17997                    final int size = tasks.size();
17998                    if (onTop) {
17999                        for (int i = 0; i < size; i++) {
18000                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18001                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
18002                                    "moveTasksToFullscreenStack", ANIMATE);
18003                        }
18004                    } else {
18005                        for (int i = size - 1; i >= 0; i--) {
18006                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18007                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
18008                        }
18009                    }
18010                } finally {
18011                    mWindowManager.continueSurfaceLayout();
18012                }
18013
18014            }
18015            Binder.restoreCallingIdentity(origId);
18016        }
18017    }
18018
18019    @Override
18020    public void updatePersistentConfiguration(Configuration values) {
18021        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18022                "updateConfiguration()");
18023        enforceWriteSettingsPermission("updateConfiguration()");
18024        if (values == null) {
18025            throw new NullPointerException("Configuration must not be null");
18026        }
18027
18028        int userId = UserHandle.getCallingUserId();
18029
18030        synchronized(this) {
18031            final long origId = Binder.clearCallingIdentity();
18032            updateConfigurationLocked(values, null, false, true, userId);
18033            Binder.restoreCallingIdentity(origId);
18034        }
18035    }
18036
18037    private void updateFontScaleIfNeeded() {
18038        final int currentUserId;
18039        synchronized(this) {
18040            currentUserId = mUserController.getCurrentUserIdLocked();
18041        }
18042        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18043                FONT_SCALE, 1.0f, currentUserId);
18044        if (mConfiguration.fontScale != scaleFactor) {
18045            final Configuration configuration = mWindowManager.computeNewConfiguration();
18046            configuration.fontScale = scaleFactor;
18047            updatePersistentConfiguration(configuration);
18048        }
18049    }
18050
18051    private void enforceWriteSettingsPermission(String func) {
18052        int uid = Binder.getCallingUid();
18053        if (uid == Process.ROOT_UID) {
18054            return;
18055        }
18056
18057        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18058                Settings.getPackageNameForUid(mContext, uid), false)) {
18059            return;
18060        }
18061
18062        String msg = "Permission Denial: " + func + " from pid="
18063                + Binder.getCallingPid()
18064                + ", uid=" + uid
18065                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18066        Slog.w(TAG, msg);
18067        throw new SecurityException(msg);
18068    }
18069
18070    public void updateConfiguration(Configuration values) {
18071        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18072                "updateConfiguration()");
18073
18074        synchronized(this) {
18075            if (values == null && mWindowManager != null) {
18076                // sentinel: fetch the current configuration from the window manager
18077                values = mWindowManager.computeNewConfiguration();
18078            }
18079
18080            if (mWindowManager != null) {
18081                mProcessList.applyDisplaySize(mWindowManager);
18082            }
18083
18084            final long origId = Binder.clearCallingIdentity();
18085            if (values != null) {
18086                Settings.System.clearConfiguration(values);
18087            }
18088            updateConfigurationLocked(values, null, false);
18089            Binder.restoreCallingIdentity(origId);
18090        }
18091    }
18092
18093    void updateUserConfigurationLocked() {
18094        Configuration configuration = new Configuration(mConfiguration);
18095        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18096                mUserController.getCurrentUserIdLocked());
18097        updateConfigurationLocked(configuration, null, false);
18098    }
18099
18100    boolean updateConfigurationLocked(Configuration values,
18101            ActivityRecord starting, boolean initLocale) {
18102        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18103        return updateConfigurationLocked(values, starting, initLocale, false,
18104                UserHandle.USER_NULL);
18105    }
18106
18107    // To cache the list of supported system locales
18108    private String[] mSupportedSystemLocales = null;
18109
18110    /**
18111     * Do either or both things: (1) change the current configuration, and (2)
18112     * make sure the given activity is running with the (now) current
18113     * configuration.  Returns true if the activity has been left running, or
18114     * false if <var>starting</var> is being destroyed to match the new
18115     * configuration.
18116     *
18117     * @param userId is only used when persistent parameter is set to true to persist configuration
18118     *               for that particular user
18119     */
18120    private boolean updateConfigurationLocked(Configuration values,
18121            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18122        int changes = 0;
18123
18124        if (mWindowManager != null) {
18125            mWindowManager.deferSurfaceLayout();
18126        }
18127        if (values != null) {
18128            Configuration newConfig = new Configuration(mConfiguration);
18129            changes = newConfig.updateFrom(values);
18130            if (changes != 0) {
18131                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18132                        "Updating configuration to: " + values);
18133
18134                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18135
18136                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18137                    final Locale locale;
18138                    if (values.getLocales().size() == 1) {
18139                        // This is an optimization to avoid the JNI call when the result of
18140                        // getFirstMatch() does not depend on the supported locales.
18141                        locale = values.getLocales().get(0);
18142                    } else {
18143                        if (mSupportedSystemLocales == null) {
18144                            mSupportedSystemLocales =
18145                                    Resources.getSystem().getAssets().getLocales();
18146                        }
18147                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18148                    }
18149                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18150                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18151                            locale));
18152                }
18153
18154                mConfigurationSeq++;
18155                if (mConfigurationSeq <= 0) {
18156                    mConfigurationSeq = 1;
18157                }
18158                newConfig.seq = mConfigurationSeq;
18159                mConfiguration = newConfig;
18160                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18161                mUsageStatsService.reportConfigurationChange(newConfig,
18162                        mUserController.getCurrentUserIdLocked());
18163                //mUsageStatsService.noteStartConfig(newConfig);
18164
18165                final Configuration configCopy = new Configuration(mConfiguration);
18166
18167                // TODO: If our config changes, should we auto dismiss any currently
18168                // showing dialogs?
18169                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18170
18171                AttributeCache ac = AttributeCache.instance();
18172                if (ac != null) {
18173                    ac.updateConfiguration(configCopy);
18174                }
18175
18176                // Make sure all resources in our process are updated
18177                // right now, so that anyone who is going to retrieve
18178                // resource values after we return will be sure to get
18179                // the new ones.  This is especially important during
18180                // boot, where the first config change needs to guarantee
18181                // all resources have that config before following boot
18182                // code is executed.
18183                mSystemThread.applyConfigurationToResources(configCopy);
18184
18185                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18186                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18187                    msg.obj = new Configuration(configCopy);
18188                    msg.arg1 = userId;
18189                    mHandler.sendMessage(msg);
18190                }
18191
18192                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18193                if (isDensityChange) {
18194                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18195                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18196                }
18197
18198                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18199                    ProcessRecord app = mLruProcesses.get(i);
18200                    try {
18201                        if (app.thread != null) {
18202                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18203                                    + app.processName + " new config " + mConfiguration);
18204                            app.thread.scheduleConfigurationChanged(configCopy);
18205                        }
18206                    } catch (Exception e) {
18207                    }
18208                }
18209                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18210                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18211                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18212                        | Intent.FLAG_RECEIVER_FOREGROUND);
18213                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18214                        null, AppOpsManager.OP_NONE, null, false, false,
18215                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18216                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18217                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18218                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18219                    if (!mProcessesReady) {
18220                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18221                    }
18222                    broadcastIntentLocked(null, null, intent,
18223                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18224                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18225                }
18226            }
18227            // Update the configuration with WM first and check if any of the stacks need to be
18228            // resized due to the configuration change. If so, resize the stacks now and do any
18229            // relaunches if necessary. This way we don't need to relaunch again below in
18230            // ensureActivityConfigurationLocked().
18231            if (mWindowManager != null) {
18232                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18233                if (resizedStacks != null) {
18234                    for (int stackId : resizedStacks) {
18235                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18236                        mStackSupervisor.resizeStackLocked(
18237                                stackId, newBounds, null, null, false, false);
18238                    }
18239                }
18240            }
18241        }
18242
18243        boolean kept = true;
18244        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18245        // mainStack is null during startup.
18246        if (mainStack != null) {
18247            if (changes != 0 && starting == null) {
18248                // If the configuration changed, and the caller is not already
18249                // in the process of starting an activity, then find the top
18250                // activity to check if its configuration needs to change.
18251                starting = mainStack.topRunningActivityLocked();
18252            }
18253
18254            if (starting != null) {
18255                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18256                // And we need to make sure at this point that all other activities
18257                // are made visible with the correct configuration.
18258                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18259                        !PRESERVE_WINDOWS);
18260            }
18261        }
18262        if (mWindowManager != null) {
18263            mWindowManager.continueSurfaceLayout();
18264        }
18265        return kept;
18266    }
18267
18268    /**
18269     * Decide based on the configuration whether we should shouw the ANR,
18270     * crash, etc dialogs.  The idea is that if there is no affordnace to
18271     * press the on-screen buttons, we shouldn't show the dialog.
18272     *
18273     * A thought: SystemUI might also want to get told about this, the Power
18274     * dialog / global actions also might want different behaviors.
18275     */
18276    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18277        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18278                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18279                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18280        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18281                                    == Configuration.UI_MODE_TYPE_CAR);
18282        return inputMethodExists && uiIsNotCarType && !inVrMode;
18283    }
18284
18285    @Override
18286    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18287        synchronized (this) {
18288            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18289            if (srec != null) {
18290                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18291            }
18292        }
18293        return false;
18294    }
18295
18296    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18297            Intent resultData) {
18298
18299        synchronized (this) {
18300            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18301            if (r != null) {
18302                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18303            }
18304            return false;
18305        }
18306    }
18307
18308    public int getLaunchedFromUid(IBinder activityToken) {
18309        ActivityRecord srec;
18310        synchronized (this) {
18311            srec = ActivityRecord.forTokenLocked(activityToken);
18312        }
18313        if (srec == null) {
18314            return -1;
18315        }
18316        return srec.launchedFromUid;
18317    }
18318
18319    public String getLaunchedFromPackage(IBinder activityToken) {
18320        ActivityRecord srec;
18321        synchronized (this) {
18322            srec = ActivityRecord.forTokenLocked(activityToken);
18323        }
18324        if (srec == null) {
18325            return null;
18326        }
18327        return srec.launchedFromPackage;
18328    }
18329
18330    // =========================================================
18331    // LIFETIME MANAGEMENT
18332    // =========================================================
18333
18334    // Returns which broadcast queue the app is the current [or imminent] receiver
18335    // on, or 'null' if the app is not an active broadcast recipient.
18336    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18337        BroadcastRecord r = app.curReceiver;
18338        if (r != null) {
18339            return r.queue;
18340        }
18341
18342        // It's not the current receiver, but it might be starting up to become one
18343        synchronized (this) {
18344            for (BroadcastQueue queue : mBroadcastQueues) {
18345                r = queue.mPendingBroadcast;
18346                if (r != null && r.curApp == app) {
18347                    // found it; report which queue it's in
18348                    return queue;
18349                }
18350            }
18351        }
18352
18353        return null;
18354    }
18355
18356    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18357            int targetUid, ComponentName targetComponent, String targetProcess) {
18358        if (!mTrackingAssociations) {
18359            return null;
18360        }
18361        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18362                = mAssociations.get(targetUid);
18363        if (components == null) {
18364            components = new ArrayMap<>();
18365            mAssociations.put(targetUid, components);
18366        }
18367        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18368        if (sourceUids == null) {
18369            sourceUids = new SparseArray<>();
18370            components.put(targetComponent, sourceUids);
18371        }
18372        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18373        if (sourceProcesses == null) {
18374            sourceProcesses = new ArrayMap<>();
18375            sourceUids.put(sourceUid, sourceProcesses);
18376        }
18377        Association ass = sourceProcesses.get(sourceProcess);
18378        if (ass == null) {
18379            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18380                    targetProcess);
18381            sourceProcesses.put(sourceProcess, ass);
18382        }
18383        ass.mCount++;
18384        ass.mNesting++;
18385        if (ass.mNesting == 1) {
18386            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18387            ass.mLastState = sourceState;
18388        }
18389        return ass;
18390    }
18391
18392    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18393            ComponentName targetComponent) {
18394        if (!mTrackingAssociations) {
18395            return;
18396        }
18397        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18398                = mAssociations.get(targetUid);
18399        if (components == null) {
18400            return;
18401        }
18402        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18403        if (sourceUids == null) {
18404            return;
18405        }
18406        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18407        if (sourceProcesses == null) {
18408            return;
18409        }
18410        Association ass = sourceProcesses.get(sourceProcess);
18411        if (ass == null || ass.mNesting <= 0) {
18412            return;
18413        }
18414        ass.mNesting--;
18415        if (ass.mNesting == 0) {
18416            long uptime = SystemClock.uptimeMillis();
18417            ass.mTime += uptime - ass.mStartTime;
18418            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18419                    += uptime - ass.mLastStateUptime;
18420            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18421        }
18422    }
18423
18424    private void noteUidProcessState(final int uid, final int state) {
18425        mBatteryStatsService.noteUidProcessState(uid, state);
18426        if (mTrackingAssociations) {
18427            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18428                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18429                        = mAssociations.valueAt(i1);
18430                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18431                    SparseArray<ArrayMap<String, Association>> sourceUids
18432                            = targetComponents.valueAt(i2);
18433                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18434                    if (sourceProcesses != null) {
18435                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18436                            Association ass = sourceProcesses.valueAt(i4);
18437                            if (ass.mNesting >= 1) {
18438                                // currently associated
18439                                long uptime = SystemClock.uptimeMillis();
18440                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18441                                        += uptime - ass.mLastStateUptime;
18442                                ass.mLastState = state;
18443                                ass.mLastStateUptime = uptime;
18444                            }
18445                        }
18446                    }
18447                }
18448            }
18449        }
18450    }
18451
18452    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18453            boolean doingAll, long now) {
18454        if (mAdjSeq == app.adjSeq) {
18455            // This adjustment has already been computed.
18456            return app.curRawAdj;
18457        }
18458
18459        if (app.thread == null) {
18460            app.adjSeq = mAdjSeq;
18461            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18462            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18463            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18464        }
18465
18466        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18467        app.adjSource = null;
18468        app.adjTarget = null;
18469        app.empty = false;
18470        app.cached = false;
18471
18472        final int activitiesSize = app.activities.size();
18473
18474        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18475            // The max adjustment doesn't allow this app to be anything
18476            // below foreground, so it is not worth doing work for it.
18477            app.adjType = "fixed";
18478            app.adjSeq = mAdjSeq;
18479            app.curRawAdj = app.maxAdj;
18480            app.foregroundActivities = false;
18481            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18482            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18483            // System processes can do UI, and when they do we want to have
18484            // them trim their memory after the user leaves the UI.  To
18485            // facilitate this, here we need to determine whether or not it
18486            // is currently showing UI.
18487            app.systemNoUi = true;
18488            if (app == TOP_APP) {
18489                app.systemNoUi = false;
18490            } else if (activitiesSize > 0) {
18491                for (int j = 0; j < activitiesSize; j++) {
18492                    final ActivityRecord r = app.activities.get(j);
18493                    if (r.visible) {
18494                        app.systemNoUi = false;
18495                    }
18496                }
18497            }
18498            if (!app.systemNoUi) {
18499                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18500            }
18501            return (app.curAdj=app.maxAdj);
18502        }
18503
18504        app.systemNoUi = false;
18505
18506        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18507
18508        // Determine the importance of the process, starting with most
18509        // important to least, and assign an appropriate OOM adjustment.
18510        int adj;
18511        int schedGroup;
18512        int procState;
18513        boolean foregroundActivities = false;
18514        BroadcastQueue queue;
18515        if (app == TOP_APP) {
18516            // The last app on the list is the foreground app.
18517            adj = ProcessList.FOREGROUND_APP_ADJ;
18518            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18519            app.adjType = "top-activity";
18520            foregroundActivities = true;
18521            procState = PROCESS_STATE_CUR_TOP;
18522        } else if (app.instrumentationClass != null) {
18523            // Don't want to kill running instrumentation.
18524            adj = ProcessList.FOREGROUND_APP_ADJ;
18525            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18526            app.adjType = "instrumentation";
18527            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18528        } else if ((queue = isReceivingBroadcast(app)) != null) {
18529            // An app that is currently receiving a broadcast also
18530            // counts as being in the foreground for OOM killer purposes.
18531            // It's placed in a sched group based on the nature of the
18532            // broadcast as reflected by which queue it's active in.
18533            adj = ProcessList.FOREGROUND_APP_ADJ;
18534            schedGroup = (queue == mFgBroadcastQueue)
18535                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18536            app.adjType = "broadcast";
18537            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18538        } else if (app.executingServices.size() > 0) {
18539            // An app that is currently executing a service callback also
18540            // counts as being in the foreground.
18541            adj = ProcessList.FOREGROUND_APP_ADJ;
18542            schedGroup = app.execServicesFg ?
18543                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18544            app.adjType = "exec-service";
18545            procState = ActivityManager.PROCESS_STATE_SERVICE;
18546            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18547        } else {
18548            // As far as we know the process is empty.  We may change our mind later.
18549            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18550            // At this point we don't actually know the adjustment.  Use the cached adj
18551            // value that the caller wants us to.
18552            adj = cachedAdj;
18553            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18554            app.cached = true;
18555            app.empty = true;
18556            app.adjType = "cch-empty";
18557        }
18558
18559        // Examine all activities if not already foreground.
18560        if (!foregroundActivities && activitiesSize > 0) {
18561            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18562            for (int j = 0; j < activitiesSize; j++) {
18563                final ActivityRecord r = app.activities.get(j);
18564                if (r.app != app) {
18565                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18566                            + " instead of expected " + app);
18567                    if (r.app == null || (r.app.uid == app.uid)) {
18568                        // Only fix things up when they look sane
18569                        r.app = app;
18570                    } else {
18571                        continue;
18572                    }
18573                }
18574                if (r.visible) {
18575                    // App has a visible activity; only upgrade adjustment.
18576                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18577                        adj = ProcessList.VISIBLE_APP_ADJ;
18578                        app.adjType = "visible";
18579                    }
18580                    if (procState > PROCESS_STATE_CUR_TOP) {
18581                        procState = PROCESS_STATE_CUR_TOP;
18582                    }
18583                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18584                    app.cached = false;
18585                    app.empty = false;
18586                    foregroundActivities = true;
18587                    if (r.task != null && minLayer > 0) {
18588                        final int layer = r.task.mLayerRank;
18589                        if (layer >= 0 && minLayer > layer) {
18590                            minLayer = layer;
18591                        }
18592                    }
18593                    break;
18594                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18595                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18596                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18597                        app.adjType = "pausing";
18598                    }
18599                    if (procState > PROCESS_STATE_CUR_TOP) {
18600                        procState = PROCESS_STATE_CUR_TOP;
18601                    }
18602                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18603                    app.cached = false;
18604                    app.empty = false;
18605                    foregroundActivities = true;
18606                } else if (r.state == ActivityState.STOPPING) {
18607                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18608                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18609                        app.adjType = "stopping";
18610                    }
18611                    // For the process state, we will at this point consider the
18612                    // process to be cached.  It will be cached either as an activity
18613                    // or empty depending on whether the activity is finishing.  We do
18614                    // this so that we can treat the process as cached for purposes of
18615                    // memory trimming (determing current memory level, trim command to
18616                    // send to process) since there can be an arbitrary number of stopping
18617                    // processes and they should soon all go into the cached state.
18618                    if (!r.finishing) {
18619                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18620                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18621                        }
18622                    }
18623                    app.cached = false;
18624                    app.empty = false;
18625                    foregroundActivities = true;
18626                } else {
18627                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18628                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18629                        app.adjType = "cch-act";
18630                    }
18631                }
18632            }
18633            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18634                adj += minLayer;
18635            }
18636        }
18637
18638        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18639                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18640            if (app.foregroundServices) {
18641                // The user is aware of this app, so make it visible.
18642                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18643                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18644                app.cached = false;
18645                app.adjType = "fg-service";
18646                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18647            } else if (app.forcingToForeground != null) {
18648                // The user is aware of this app, so make it visible.
18649                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18650                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18651                app.cached = false;
18652                app.adjType = "force-fg";
18653                app.adjSource = app.forcingToForeground;
18654                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18655            }
18656        }
18657
18658        if (app == mHeavyWeightProcess) {
18659            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18660                // We don't want to kill the current heavy-weight process.
18661                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18662                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18663                app.cached = false;
18664                app.adjType = "heavy";
18665            }
18666            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18667                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18668            }
18669        }
18670
18671        if (app == mHomeProcess) {
18672            if (adj > ProcessList.HOME_APP_ADJ) {
18673                // This process is hosting what we currently consider to be the
18674                // home app, so we don't want to let it go into the background.
18675                adj = ProcessList.HOME_APP_ADJ;
18676                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18677                app.cached = false;
18678                app.adjType = "home";
18679            }
18680            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18681                procState = ActivityManager.PROCESS_STATE_HOME;
18682            }
18683        }
18684
18685        if (app == mPreviousProcess && app.activities.size() > 0) {
18686            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18687                // This was the previous process that showed UI to the user.
18688                // We want to try to keep it around more aggressively, to give
18689                // a good experience around switching between two apps.
18690                adj = ProcessList.PREVIOUS_APP_ADJ;
18691                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18692                app.cached = false;
18693                app.adjType = "previous";
18694            }
18695            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18696                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18697            }
18698        }
18699
18700        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18701                + " reason=" + app.adjType);
18702
18703        // By default, we use the computed adjustment.  It may be changed if
18704        // there are applications dependent on our services or providers, but
18705        // this gives us a baseline and makes sure we don't get into an
18706        // infinite recursion.
18707        app.adjSeq = mAdjSeq;
18708        app.curRawAdj = adj;
18709        app.hasStartedServices = false;
18710
18711        if (mBackupTarget != null && app == mBackupTarget.app) {
18712            // If possible we want to avoid killing apps while they're being backed up
18713            if (adj > ProcessList.BACKUP_APP_ADJ) {
18714                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18715                adj = ProcessList.BACKUP_APP_ADJ;
18716                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18717                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18718                }
18719                app.adjType = "backup";
18720                app.cached = false;
18721            }
18722            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18723                procState = ActivityManager.PROCESS_STATE_BACKUP;
18724            }
18725        }
18726
18727        boolean mayBeTop = false;
18728
18729        for (int is = app.services.size()-1;
18730                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18731                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18732                        || procState > ActivityManager.PROCESS_STATE_TOP);
18733                is--) {
18734            ServiceRecord s = app.services.valueAt(is);
18735            if (s.startRequested) {
18736                app.hasStartedServices = true;
18737                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18738                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18739                }
18740                if (app.hasShownUi && app != mHomeProcess) {
18741                    // If this process has shown some UI, let it immediately
18742                    // go to the LRU list because it may be pretty heavy with
18743                    // UI stuff.  We'll tag it with a label just to help
18744                    // debug and understand what is going on.
18745                    if (adj > ProcessList.SERVICE_ADJ) {
18746                        app.adjType = "cch-started-ui-services";
18747                    }
18748                } else {
18749                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18750                        // This service has seen some activity within
18751                        // recent memory, so we will keep its process ahead
18752                        // of the background processes.
18753                        if (adj > ProcessList.SERVICE_ADJ) {
18754                            adj = ProcessList.SERVICE_ADJ;
18755                            app.adjType = "started-services";
18756                            app.cached = false;
18757                        }
18758                    }
18759                    // If we have let the service slide into the background
18760                    // state, still have some text describing what it is doing
18761                    // even though the service no longer has an impact.
18762                    if (adj > ProcessList.SERVICE_ADJ) {
18763                        app.adjType = "cch-started-services";
18764                    }
18765                }
18766            }
18767            for (int conni = s.connections.size()-1;
18768                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18769                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18770                            || procState > ActivityManager.PROCESS_STATE_TOP);
18771                    conni--) {
18772                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18773                for (int i = 0;
18774                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18775                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18776                                || procState > ActivityManager.PROCESS_STATE_TOP);
18777                        i++) {
18778                    // XXX should compute this based on the max of
18779                    // all connected clients.
18780                    ConnectionRecord cr = clist.get(i);
18781                    if (cr.binding.client == app) {
18782                        // Binding to ourself is not interesting.
18783                        continue;
18784                    }
18785                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18786                        ProcessRecord client = cr.binding.client;
18787                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18788                                TOP_APP, doingAll, now);
18789                        int clientProcState = client.curProcState;
18790                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18791                            // If the other app is cached for any reason, for purposes here
18792                            // we are going to consider it empty.  The specific cached state
18793                            // doesn't propagate except under certain conditions.
18794                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18795                        }
18796                        String adjType = null;
18797                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18798                            // Not doing bind OOM management, so treat
18799                            // this guy more like a started service.
18800                            if (app.hasShownUi && app != mHomeProcess) {
18801                                // If this process has shown some UI, let it immediately
18802                                // go to the LRU list because it may be pretty heavy with
18803                                // UI stuff.  We'll tag it with a label just to help
18804                                // debug and understand what is going on.
18805                                if (adj > clientAdj) {
18806                                    adjType = "cch-bound-ui-services";
18807                                }
18808                                app.cached = false;
18809                                clientAdj = adj;
18810                                clientProcState = procState;
18811                            } else {
18812                                if (now >= (s.lastActivity
18813                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18814                                    // This service has not seen activity within
18815                                    // recent memory, so allow it to drop to the
18816                                    // LRU list if there is no other reason to keep
18817                                    // it around.  We'll also tag it with a label just
18818                                    // to help debug and undertand what is going on.
18819                                    if (adj > clientAdj) {
18820                                        adjType = "cch-bound-services";
18821                                    }
18822                                    clientAdj = adj;
18823                                }
18824                            }
18825                        }
18826                        if (adj > clientAdj) {
18827                            // If this process has recently shown UI, and
18828                            // the process that is binding to it is less
18829                            // important than being visible, then we don't
18830                            // care about the binding as much as we care
18831                            // about letting this process get into the LRU
18832                            // list to be killed and restarted if needed for
18833                            // memory.
18834                            if (app.hasShownUi && app != mHomeProcess
18835                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18836                                adjType = "cch-bound-ui-services";
18837                            } else {
18838                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18839                                        |Context.BIND_IMPORTANT)) != 0) {
18840                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18841                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18842                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18843                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18844                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18845                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18846                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18847                                    adj = clientAdj;
18848                                } else {
18849                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18850                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18851                                    }
18852                                }
18853                                if (!client.cached) {
18854                                    app.cached = false;
18855                                }
18856                                adjType = "service";
18857                            }
18858                        }
18859                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18860                            // This will treat important bound services identically to
18861                            // the top app, which may behave differently than generic
18862                            // foreground work.
18863                            if (client.curSchedGroup > schedGroup) {
18864                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18865                                    schedGroup = client.curSchedGroup;
18866                                } else {
18867                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18868                                }
18869                            }
18870                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18871                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18872                                    // Special handling of clients who are in the top state.
18873                                    // We *may* want to consider this process to be in the
18874                                    // top state as well, but only if there is not another
18875                                    // reason for it to be running.  Being on the top is a
18876                                    // special state, meaning you are specifically running
18877                                    // for the current top app.  If the process is already
18878                                    // running in the background for some other reason, it
18879                                    // is more important to continue considering it to be
18880                                    // in the background state.
18881                                    mayBeTop = true;
18882                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18883                                } else {
18884                                    // Special handling for above-top states (persistent
18885                                    // processes).  These should not bring the current process
18886                                    // into the top state, since they are not on top.  Instead
18887                                    // give them the best state after that.
18888                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18889                                        clientProcState =
18890                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18891                                    } else if (mWakefulness
18892                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18893                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18894                                                    != 0) {
18895                                        clientProcState =
18896                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18897                                    } else {
18898                                        clientProcState =
18899                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18900                                    }
18901                                }
18902                            }
18903                        } else {
18904                            if (clientProcState <
18905                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18906                                clientProcState =
18907                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18908                            }
18909                        }
18910                        if (procState > clientProcState) {
18911                            procState = clientProcState;
18912                        }
18913                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18914                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18915                            app.pendingUiClean = true;
18916                        }
18917                        if (adjType != null) {
18918                            app.adjType = adjType;
18919                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18920                                    .REASON_SERVICE_IN_USE;
18921                            app.adjSource = cr.binding.client;
18922                            app.adjSourceProcState = clientProcState;
18923                            app.adjTarget = s.name;
18924                        }
18925                    }
18926                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18927                        app.treatLikeActivity = true;
18928                    }
18929                    final ActivityRecord a = cr.activity;
18930                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18931                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18932                            (a.visible || a.state == ActivityState.RESUMED ||
18933                             a.state == ActivityState.PAUSING)) {
18934                            adj = ProcessList.FOREGROUND_APP_ADJ;
18935                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18936                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18937                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18938                                } else {
18939                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18940                                }
18941                            }
18942                            app.cached = false;
18943                            app.adjType = "service";
18944                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18945                                    .REASON_SERVICE_IN_USE;
18946                            app.adjSource = a;
18947                            app.adjSourceProcState = procState;
18948                            app.adjTarget = s.name;
18949                        }
18950                    }
18951                }
18952            }
18953        }
18954
18955        for (int provi = app.pubProviders.size()-1;
18956                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18957                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18958                        || procState > ActivityManager.PROCESS_STATE_TOP);
18959                provi--) {
18960            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18961            for (int i = cpr.connections.size()-1;
18962                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18963                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18964                            || procState > ActivityManager.PROCESS_STATE_TOP);
18965                    i--) {
18966                ContentProviderConnection conn = cpr.connections.get(i);
18967                ProcessRecord client = conn.client;
18968                if (client == app) {
18969                    // Being our own client is not interesting.
18970                    continue;
18971                }
18972                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18973                int clientProcState = client.curProcState;
18974                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18975                    // If the other app is cached for any reason, for purposes here
18976                    // we are going to consider it empty.
18977                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18978                }
18979                if (adj > clientAdj) {
18980                    if (app.hasShownUi && app != mHomeProcess
18981                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18982                        app.adjType = "cch-ui-provider";
18983                    } else {
18984                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18985                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18986                        app.adjType = "provider";
18987                    }
18988                    app.cached &= client.cached;
18989                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18990                            .REASON_PROVIDER_IN_USE;
18991                    app.adjSource = client;
18992                    app.adjSourceProcState = clientProcState;
18993                    app.adjTarget = cpr.name;
18994                }
18995                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18996                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18997                        // Special handling of clients who are in the top state.
18998                        // We *may* want to consider this process to be in the
18999                        // top state as well, but only if there is not another
19000                        // reason for it to be running.  Being on the top is a
19001                        // special state, meaning you are specifically running
19002                        // for the current top app.  If the process is already
19003                        // running in the background for some other reason, it
19004                        // is more important to continue considering it to be
19005                        // in the background state.
19006                        mayBeTop = true;
19007                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19008                    } else {
19009                        // Special handling for above-top states (persistent
19010                        // processes).  These should not bring the current process
19011                        // into the top state, since they are not on top.  Instead
19012                        // give them the best state after that.
19013                        clientProcState =
19014                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19015                    }
19016                }
19017                if (procState > clientProcState) {
19018                    procState = clientProcState;
19019                }
19020                if (client.curSchedGroup > schedGroup) {
19021                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19022                }
19023            }
19024            // If the provider has external (non-framework) process
19025            // dependencies, ensure that its adjustment is at least
19026            // FOREGROUND_APP_ADJ.
19027            if (cpr.hasExternalProcessHandles()) {
19028                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19029                    adj = ProcessList.FOREGROUND_APP_ADJ;
19030                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19031                    app.cached = false;
19032                    app.adjType = "provider";
19033                    app.adjTarget = cpr.name;
19034                }
19035                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19036                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19037                }
19038            }
19039        }
19040
19041        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19042            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19043                adj = ProcessList.PREVIOUS_APP_ADJ;
19044                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19045                app.cached = false;
19046                app.adjType = "provider";
19047            }
19048            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19049                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19050            }
19051        }
19052
19053        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19054            // A client of one of our services or providers is in the top state.  We
19055            // *may* want to be in the top state, but not if we are already running in
19056            // the background for some other reason.  For the decision here, we are going
19057            // to pick out a few specific states that we want to remain in when a client
19058            // is top (states that tend to be longer-term) and otherwise allow it to go
19059            // to the top state.
19060            switch (procState) {
19061                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19062                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19063                case ActivityManager.PROCESS_STATE_SERVICE:
19064                    // These all are longer-term states, so pull them up to the top
19065                    // of the background states, but not all the way to the top state.
19066                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19067                    break;
19068                default:
19069                    // Otherwise, top is a better choice, so take it.
19070                    procState = ActivityManager.PROCESS_STATE_TOP;
19071                    break;
19072            }
19073        }
19074
19075        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19076            if (app.hasClientActivities) {
19077                // This is a cached process, but with client activities.  Mark it so.
19078                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19079                app.adjType = "cch-client-act";
19080            } else if (app.treatLikeActivity) {
19081                // This is a cached process, but somebody wants us to treat it like it has
19082                // an activity, okay!
19083                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19084                app.adjType = "cch-as-act";
19085            }
19086        }
19087
19088        if (adj == ProcessList.SERVICE_ADJ) {
19089            if (doingAll) {
19090                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19091                mNewNumServiceProcs++;
19092                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19093                if (!app.serviceb) {
19094                    // This service isn't far enough down on the LRU list to
19095                    // normally be a B service, but if we are low on RAM and it
19096                    // is large we want to force it down since we would prefer to
19097                    // keep launcher over it.
19098                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19099                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19100                        app.serviceHighRam = true;
19101                        app.serviceb = true;
19102                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19103                    } else {
19104                        mNewNumAServiceProcs++;
19105                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19106                    }
19107                } else {
19108                    app.serviceHighRam = false;
19109                }
19110            }
19111            if (app.serviceb) {
19112                adj = ProcessList.SERVICE_B_ADJ;
19113            }
19114        }
19115
19116        app.curRawAdj = adj;
19117
19118        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19119        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19120        if (adj > app.maxAdj) {
19121            adj = app.maxAdj;
19122            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19123                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19124            }
19125        }
19126
19127        // Do final modification to adj.  Everything we do between here and applying
19128        // the final setAdj must be done in this function, because we will also use
19129        // it when computing the final cached adj later.  Note that we don't need to
19130        // worry about this for max adj above, since max adj will always be used to
19131        // keep it out of the cached vaues.
19132        app.curAdj = app.modifyRawOomAdj(adj);
19133        app.curSchedGroup = schedGroup;
19134        app.curProcState = procState;
19135        app.foregroundActivities = foregroundActivities;
19136
19137        return app.curRawAdj;
19138    }
19139
19140    /**
19141     * Record new PSS sample for a process.
19142     */
19143    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19144            long now) {
19145        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19146                swapPss * 1024);
19147        proc.lastPssTime = now;
19148        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19149        if (DEBUG_PSS) Slog.d(TAG_PSS,
19150                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19151                + " state=" + ProcessList.makeProcStateString(procState));
19152        if (proc.initialIdlePss == 0) {
19153            proc.initialIdlePss = pss;
19154        }
19155        proc.lastPss = pss;
19156        proc.lastSwapPss = swapPss;
19157        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19158            proc.lastCachedPss = pss;
19159            proc.lastCachedSwapPss = swapPss;
19160        }
19161
19162        final SparseArray<Pair<Long, String>> watchUids
19163                = mMemWatchProcesses.getMap().get(proc.processName);
19164        Long check = null;
19165        if (watchUids != null) {
19166            Pair<Long, String> val = watchUids.get(proc.uid);
19167            if (val == null) {
19168                val = watchUids.get(0);
19169            }
19170            if (val != null) {
19171                check = val.first;
19172            }
19173        }
19174        if (check != null) {
19175            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19176                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19177                if (!isDebuggable) {
19178                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19179                        isDebuggable = true;
19180                    }
19181                }
19182                if (isDebuggable) {
19183                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19184                    final ProcessRecord myProc = proc;
19185                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19186                    mMemWatchDumpProcName = proc.processName;
19187                    mMemWatchDumpFile = heapdumpFile.toString();
19188                    mMemWatchDumpPid = proc.pid;
19189                    mMemWatchDumpUid = proc.uid;
19190                    BackgroundThread.getHandler().post(new Runnable() {
19191                        @Override
19192                        public void run() {
19193                            revokeUriPermission(ActivityThread.currentActivityThread()
19194                                            .getApplicationThread(),
19195                                    DumpHeapActivity.JAVA_URI,
19196                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19197                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19198                                    UserHandle.myUserId());
19199                            ParcelFileDescriptor fd = null;
19200                            try {
19201                                heapdumpFile.delete();
19202                                fd = ParcelFileDescriptor.open(heapdumpFile,
19203                                        ParcelFileDescriptor.MODE_CREATE |
19204                                                ParcelFileDescriptor.MODE_TRUNCATE |
19205                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19206                                                ParcelFileDescriptor.MODE_APPEND);
19207                                IApplicationThread thread = myProc.thread;
19208                                if (thread != null) {
19209                                    try {
19210                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19211                                                "Requesting dump heap from "
19212                                                + myProc + " to " + heapdumpFile);
19213                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19214                                    } catch (RemoteException e) {
19215                                    }
19216                                }
19217                            } catch (FileNotFoundException e) {
19218                                e.printStackTrace();
19219                            } finally {
19220                                if (fd != null) {
19221                                    try {
19222                                        fd.close();
19223                                    } catch (IOException e) {
19224                                    }
19225                                }
19226                            }
19227                        }
19228                    });
19229                } else {
19230                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19231                            + ", but debugging not enabled");
19232                }
19233            }
19234        }
19235    }
19236
19237    /**
19238     * Schedule PSS collection of a process.
19239     */
19240    void requestPssLocked(ProcessRecord proc, int procState) {
19241        if (mPendingPssProcesses.contains(proc)) {
19242            return;
19243        }
19244        if (mPendingPssProcesses.size() == 0) {
19245            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19246        }
19247        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19248        proc.pssProcState = procState;
19249        mPendingPssProcesses.add(proc);
19250    }
19251
19252    /**
19253     * Schedule PSS collection of all processes.
19254     */
19255    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19256        if (!always) {
19257            if (now < (mLastFullPssTime +
19258                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19259                return;
19260            }
19261        }
19262        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19263        mLastFullPssTime = now;
19264        mFullPssPending = true;
19265        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19266        mPendingPssProcesses.clear();
19267        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19268            ProcessRecord app = mLruProcesses.get(i);
19269            if (app.thread == null
19270                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19271                continue;
19272            }
19273            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19274                app.pssProcState = app.setProcState;
19275                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19276                        mTestPssMode, isSleeping(), now);
19277                mPendingPssProcesses.add(app);
19278            }
19279        }
19280        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19281    }
19282
19283    public void setTestPssMode(boolean enabled) {
19284        synchronized (this) {
19285            mTestPssMode = enabled;
19286            if (enabled) {
19287                // Whenever we enable the mode, we want to take a snapshot all of current
19288                // process mem use.
19289                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19290            }
19291        }
19292    }
19293
19294    /**
19295     * Ask a given process to GC right now.
19296     */
19297    final void performAppGcLocked(ProcessRecord app) {
19298        try {
19299            app.lastRequestedGc = SystemClock.uptimeMillis();
19300            if (app.thread != null) {
19301                if (app.reportLowMemory) {
19302                    app.reportLowMemory = false;
19303                    app.thread.scheduleLowMemory();
19304                } else {
19305                    app.thread.processInBackground();
19306                }
19307            }
19308        } catch (Exception e) {
19309            // whatever.
19310        }
19311    }
19312
19313    /**
19314     * Returns true if things are idle enough to perform GCs.
19315     */
19316    private final boolean canGcNowLocked() {
19317        boolean processingBroadcasts = false;
19318        for (BroadcastQueue q : mBroadcastQueues) {
19319            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19320                processingBroadcasts = true;
19321            }
19322        }
19323        return !processingBroadcasts
19324                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19325    }
19326
19327    /**
19328     * Perform GCs on all processes that are waiting for it, but only
19329     * if things are idle.
19330     */
19331    final void performAppGcsLocked() {
19332        final int N = mProcessesToGc.size();
19333        if (N <= 0) {
19334            return;
19335        }
19336        if (canGcNowLocked()) {
19337            while (mProcessesToGc.size() > 0) {
19338                ProcessRecord proc = mProcessesToGc.remove(0);
19339                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19340                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19341                            <= SystemClock.uptimeMillis()) {
19342                        // To avoid spamming the system, we will GC processes one
19343                        // at a time, waiting a few seconds between each.
19344                        performAppGcLocked(proc);
19345                        scheduleAppGcsLocked();
19346                        return;
19347                    } else {
19348                        // It hasn't been long enough since we last GCed this
19349                        // process...  put it in the list to wait for its time.
19350                        addProcessToGcListLocked(proc);
19351                        break;
19352                    }
19353                }
19354            }
19355
19356            scheduleAppGcsLocked();
19357        }
19358    }
19359
19360    /**
19361     * If all looks good, perform GCs on all processes waiting for them.
19362     */
19363    final void performAppGcsIfAppropriateLocked() {
19364        if (canGcNowLocked()) {
19365            performAppGcsLocked();
19366            return;
19367        }
19368        // Still not idle, wait some more.
19369        scheduleAppGcsLocked();
19370    }
19371
19372    /**
19373     * Schedule the execution of all pending app GCs.
19374     */
19375    final void scheduleAppGcsLocked() {
19376        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19377
19378        if (mProcessesToGc.size() > 0) {
19379            // Schedule a GC for the time to the next process.
19380            ProcessRecord proc = mProcessesToGc.get(0);
19381            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19382
19383            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19384            long now = SystemClock.uptimeMillis();
19385            if (when < (now+GC_TIMEOUT)) {
19386                when = now + GC_TIMEOUT;
19387            }
19388            mHandler.sendMessageAtTime(msg, when);
19389        }
19390    }
19391
19392    /**
19393     * Add a process to the array of processes waiting to be GCed.  Keeps the
19394     * list in sorted order by the last GC time.  The process can't already be
19395     * on the list.
19396     */
19397    final void addProcessToGcListLocked(ProcessRecord proc) {
19398        boolean added = false;
19399        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19400            if (mProcessesToGc.get(i).lastRequestedGc <
19401                    proc.lastRequestedGc) {
19402                added = true;
19403                mProcessesToGc.add(i+1, proc);
19404                break;
19405            }
19406        }
19407        if (!added) {
19408            mProcessesToGc.add(0, proc);
19409        }
19410    }
19411
19412    /**
19413     * Set up to ask a process to GC itself.  This will either do it
19414     * immediately, or put it on the list of processes to gc the next
19415     * time things are idle.
19416     */
19417    final void scheduleAppGcLocked(ProcessRecord app) {
19418        long now = SystemClock.uptimeMillis();
19419        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19420            return;
19421        }
19422        if (!mProcessesToGc.contains(app)) {
19423            addProcessToGcListLocked(app);
19424            scheduleAppGcsLocked();
19425        }
19426    }
19427
19428    final void checkExcessivePowerUsageLocked(boolean doKills) {
19429        updateCpuStatsNow();
19430
19431        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19432        boolean doWakeKills = doKills;
19433        boolean doCpuKills = doKills;
19434        if (mLastPowerCheckRealtime == 0) {
19435            doWakeKills = false;
19436        }
19437        if (mLastPowerCheckUptime == 0) {
19438            doCpuKills = false;
19439        }
19440        if (stats.isScreenOn()) {
19441            doWakeKills = false;
19442        }
19443        final long curRealtime = SystemClock.elapsedRealtime();
19444        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19445        final long curUptime = SystemClock.uptimeMillis();
19446        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19447        mLastPowerCheckRealtime = curRealtime;
19448        mLastPowerCheckUptime = curUptime;
19449        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19450            doWakeKills = false;
19451        }
19452        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19453            doCpuKills = false;
19454        }
19455        int i = mLruProcesses.size();
19456        while (i > 0) {
19457            i--;
19458            ProcessRecord app = mLruProcesses.get(i);
19459            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19460                long wtime;
19461                synchronized (stats) {
19462                    wtime = stats.getProcessWakeTime(app.info.uid,
19463                            app.pid, curRealtime);
19464                }
19465                long wtimeUsed = wtime - app.lastWakeTime;
19466                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19467                if (DEBUG_POWER) {
19468                    StringBuilder sb = new StringBuilder(128);
19469                    sb.append("Wake for ");
19470                    app.toShortString(sb);
19471                    sb.append(": over ");
19472                    TimeUtils.formatDuration(realtimeSince, sb);
19473                    sb.append(" used ");
19474                    TimeUtils.formatDuration(wtimeUsed, sb);
19475                    sb.append(" (");
19476                    sb.append((wtimeUsed*100)/realtimeSince);
19477                    sb.append("%)");
19478                    Slog.i(TAG_POWER, sb.toString());
19479                    sb.setLength(0);
19480                    sb.append("CPU for ");
19481                    app.toShortString(sb);
19482                    sb.append(": over ");
19483                    TimeUtils.formatDuration(uptimeSince, sb);
19484                    sb.append(" used ");
19485                    TimeUtils.formatDuration(cputimeUsed, sb);
19486                    sb.append(" (");
19487                    sb.append((cputimeUsed*100)/uptimeSince);
19488                    sb.append("%)");
19489                    Slog.i(TAG_POWER, sb.toString());
19490                }
19491                // If a process has held a wake lock for more
19492                // than 50% of the time during this period,
19493                // that sounds bad.  Kill!
19494                if (doWakeKills && realtimeSince > 0
19495                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19496                    synchronized (stats) {
19497                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19498                                realtimeSince, wtimeUsed);
19499                    }
19500                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19501                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19502                } else if (doCpuKills && uptimeSince > 0
19503                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19504                    synchronized (stats) {
19505                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19506                                uptimeSince, cputimeUsed);
19507                    }
19508                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19509                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19510                } else {
19511                    app.lastWakeTime = wtime;
19512                    app.lastCpuTime = app.curCpuTime;
19513                }
19514            }
19515        }
19516    }
19517
19518    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19519            long nowElapsed) {
19520        boolean success = true;
19521
19522        if (app.curRawAdj != app.setRawAdj) {
19523            app.setRawAdj = app.curRawAdj;
19524        }
19525
19526        int changes = 0;
19527
19528        if (app.curAdj != app.setAdj) {
19529            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19530            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19531                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19532                    + app.adjType);
19533            app.setAdj = app.curAdj;
19534        }
19535
19536        if (app.setSchedGroup != app.curSchedGroup) {
19537            app.setSchedGroup = app.curSchedGroup;
19538            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19539                    "Setting sched group of " + app.processName
19540                    + " to " + app.curSchedGroup);
19541            if (app.waitingToKill != null && app.curReceiver == null
19542                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19543                app.kill(app.waitingToKill, true);
19544                success = false;
19545            } else {
19546                int processGroup;
19547                switch (app.curSchedGroup) {
19548                    case ProcessList.SCHED_GROUP_BACKGROUND:
19549                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19550                        break;
19551                    case ProcessList.SCHED_GROUP_TOP_APP:
19552                        processGroup = Process.THREAD_GROUP_TOP_APP;
19553                        break;
19554                    default:
19555                        processGroup = Process.THREAD_GROUP_DEFAULT;
19556                        break;
19557                }
19558                if (true) {
19559                    long oldId = Binder.clearCallingIdentity();
19560                    try {
19561                        Process.setProcessGroup(app.pid, processGroup);
19562                    } catch (Exception e) {
19563                        Slog.w(TAG, "Failed setting process group of " + app.pid
19564                                + " to " + app.curSchedGroup);
19565                        e.printStackTrace();
19566                    } finally {
19567                        Binder.restoreCallingIdentity(oldId);
19568                    }
19569                } else {
19570                    if (app.thread != null) {
19571                        try {
19572                            app.thread.setSchedulingGroup(processGroup);
19573                        } catch (RemoteException e) {
19574                        }
19575                    }
19576                }
19577            }
19578        }
19579        if (app.repForegroundActivities != app.foregroundActivities) {
19580            app.repForegroundActivities = app.foregroundActivities;
19581            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19582        }
19583        if (app.repProcState != app.curProcState) {
19584            app.repProcState = app.curProcState;
19585            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19586            if (app.thread != null) {
19587                try {
19588                    if (false) {
19589                        //RuntimeException h = new RuntimeException("here");
19590                        Slog.i(TAG, "Sending new process state " + app.repProcState
19591                                + " to " + app /*, h*/);
19592                    }
19593                    app.thread.setProcessState(app.repProcState);
19594                } catch (RemoteException e) {
19595                }
19596            }
19597        }
19598        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19599                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19600            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19601                // Experimental code to more aggressively collect pss while
19602                // running test...  the problem is that this tends to collect
19603                // the data right when a process is transitioning between process
19604                // states, which well tend to give noisy data.
19605                long start = SystemClock.uptimeMillis();
19606                long pss = Debug.getPss(app.pid, mTmpLong, null);
19607                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19608                mPendingPssProcesses.remove(app);
19609                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19610                        + " to " + app.curProcState + ": "
19611                        + (SystemClock.uptimeMillis()-start) + "ms");
19612            }
19613            app.lastStateTime = now;
19614            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19615                    mTestPssMode, isSleeping(), now);
19616            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19617                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19618                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19619                    + (app.nextPssTime-now) + ": " + app);
19620        } else {
19621            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19622                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19623                    mTestPssMode)))) {
19624                requestPssLocked(app, app.setProcState);
19625                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19626                        mTestPssMode, isSleeping(), now);
19627            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19628                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19629        }
19630        if (app.setProcState != app.curProcState) {
19631            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19632                    "Proc state change of " + app.processName
19633                            + " to " + app.curProcState);
19634            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19635            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19636            if (setImportant && !curImportant) {
19637                // This app is no longer something we consider important enough to allow to
19638                // use arbitrary amounts of battery power.  Note
19639                // its current wake lock time to later know to kill it if
19640                // it is not behaving well.
19641                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19642                synchronized (stats) {
19643                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19644                            app.pid, nowElapsed);
19645                }
19646                app.lastCpuTime = app.curCpuTime;
19647
19648            }
19649            // Inform UsageStats of important process state change
19650            // Must be called before updating setProcState
19651            maybeUpdateUsageStatsLocked(app, nowElapsed);
19652
19653            app.setProcState = app.curProcState;
19654            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19655                app.notCachedSinceIdle = false;
19656            }
19657            if (!doingAll) {
19658                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19659            } else {
19660                app.procStateChanged = true;
19661            }
19662        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19663                > USAGE_STATS_INTERACTION_INTERVAL) {
19664            // For apps that sit around for a long time in the interactive state, we need
19665            // to report this at least once a day so they don't go idle.
19666            maybeUpdateUsageStatsLocked(app, nowElapsed);
19667        }
19668
19669        if (changes != 0) {
19670            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19671                    "Changes in " + app + ": " + changes);
19672            int i = mPendingProcessChanges.size()-1;
19673            ProcessChangeItem item = null;
19674            while (i >= 0) {
19675                item = mPendingProcessChanges.get(i);
19676                if (item.pid == app.pid) {
19677                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19678                            "Re-using existing item: " + item);
19679                    break;
19680                }
19681                i--;
19682            }
19683            if (i < 0) {
19684                // No existing item in pending changes; need a new one.
19685                final int NA = mAvailProcessChanges.size();
19686                if (NA > 0) {
19687                    item = mAvailProcessChanges.remove(NA-1);
19688                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19689                            "Retrieving available item: " + item);
19690                } else {
19691                    item = new ProcessChangeItem();
19692                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19693                            "Allocating new item: " + item);
19694                }
19695                item.changes = 0;
19696                item.pid = app.pid;
19697                item.uid = app.info.uid;
19698                if (mPendingProcessChanges.size() == 0) {
19699                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19700                            "*** Enqueueing dispatch processes changed!");
19701                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19702                }
19703                mPendingProcessChanges.add(item);
19704            }
19705            item.changes |= changes;
19706            item.processState = app.repProcState;
19707            item.foregroundActivities = app.repForegroundActivities;
19708            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19709                    "Item " + Integer.toHexString(System.identityHashCode(item))
19710                    + " " + app.toShortString() + ": changes=" + item.changes
19711                    + " procState=" + item.processState
19712                    + " foreground=" + item.foregroundActivities
19713                    + " type=" + app.adjType + " source=" + app.adjSource
19714                    + " target=" + app.adjTarget);
19715        }
19716
19717        return success;
19718    }
19719
19720    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19721        final UidRecord.ChangeItem pendingChange;
19722        if (uidRec == null || uidRec.pendingChange == null) {
19723            if (mPendingUidChanges.size() == 0) {
19724                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19725                        "*** Enqueueing dispatch uid changed!");
19726                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19727            }
19728            final int NA = mAvailUidChanges.size();
19729            if (NA > 0) {
19730                pendingChange = mAvailUidChanges.remove(NA-1);
19731                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19732                        "Retrieving available item: " + pendingChange);
19733            } else {
19734                pendingChange = new UidRecord.ChangeItem();
19735                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19736                        "Allocating new item: " + pendingChange);
19737            }
19738            if (uidRec != null) {
19739                uidRec.pendingChange = pendingChange;
19740                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19741                    // If this uid is going away, and we haven't yet reported it is gone,
19742                    // then do so now.
19743                    change = UidRecord.CHANGE_GONE_IDLE;
19744                }
19745            } else if (uid < 0) {
19746                throw new IllegalArgumentException("No UidRecord or uid");
19747            }
19748            pendingChange.uidRecord = uidRec;
19749            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19750            mPendingUidChanges.add(pendingChange);
19751        } else {
19752            pendingChange = uidRec.pendingChange;
19753            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19754                change = UidRecord.CHANGE_GONE_IDLE;
19755            }
19756        }
19757        pendingChange.change = change;
19758        pendingChange.processState = uidRec != null
19759                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19760    }
19761
19762    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19763            String authority) {
19764        if (app == null) return;
19765        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19766            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19767            if (userState == null) return;
19768            final long now = SystemClock.elapsedRealtime();
19769            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19770            if (lastReported == null || lastReported < now - 60 * 1000L) {
19771                mUsageStatsService.reportContentProviderUsage(
19772                        authority, providerPkgName, app.userId);
19773                userState.mProviderLastReportedFg.put(authority, now);
19774            }
19775        }
19776    }
19777
19778    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19779        if (DEBUG_USAGE_STATS) {
19780            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19781                    + "] state changes: old = " + app.setProcState + ", new = "
19782                    + app.curProcState);
19783        }
19784        if (mUsageStatsService == null) {
19785            return;
19786        }
19787        boolean isInteraction;
19788        // To avoid some abuse patterns, we are going to be careful about what we consider
19789        // to be an app interaction.  Being the top activity doesn't count while the display
19790        // is sleeping, nor do short foreground services.
19791        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19792            isInteraction = true;
19793            app.fgInteractionTime = 0;
19794        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19795            if (app.fgInteractionTime == 0) {
19796                app.fgInteractionTime = nowElapsed;
19797                isInteraction = false;
19798            } else {
19799                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19800            }
19801        } else {
19802            isInteraction = app.curProcState
19803                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19804            app.fgInteractionTime = 0;
19805        }
19806        if (isInteraction && (!app.reportedInteraction
19807                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19808            app.interactionEventTime = nowElapsed;
19809            String[] packages = app.getPackageList();
19810            if (packages != null) {
19811                for (int i = 0; i < packages.length; i++) {
19812                    mUsageStatsService.reportEvent(packages[i], app.userId,
19813                            UsageEvents.Event.SYSTEM_INTERACTION);
19814                }
19815            }
19816        }
19817        app.reportedInteraction = isInteraction;
19818        if (!isInteraction) {
19819            app.interactionEventTime = 0;
19820        }
19821    }
19822
19823    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19824        if (proc.thread != null) {
19825            if (proc.baseProcessTracker != null) {
19826                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19827            }
19828        }
19829    }
19830
19831    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19832            ProcessRecord TOP_APP, boolean doingAll, long now) {
19833        if (app.thread == null) {
19834            return false;
19835        }
19836
19837        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19838
19839        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19840    }
19841
19842    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19843            boolean oomAdj) {
19844        if (isForeground != proc.foregroundServices) {
19845            proc.foregroundServices = isForeground;
19846            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19847                    proc.info.uid);
19848            if (isForeground) {
19849                if (curProcs == null) {
19850                    curProcs = new ArrayList<ProcessRecord>();
19851                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19852                }
19853                if (!curProcs.contains(proc)) {
19854                    curProcs.add(proc);
19855                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19856                            proc.info.packageName, proc.info.uid);
19857                }
19858            } else {
19859                if (curProcs != null) {
19860                    if (curProcs.remove(proc)) {
19861                        mBatteryStatsService.noteEvent(
19862                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19863                                proc.info.packageName, proc.info.uid);
19864                        if (curProcs.size() <= 0) {
19865                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19866                        }
19867                    }
19868                }
19869            }
19870            if (oomAdj) {
19871                updateOomAdjLocked();
19872            }
19873        }
19874    }
19875
19876    private final ActivityRecord resumedAppLocked() {
19877        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19878        String pkg;
19879        int uid;
19880        if (act != null) {
19881            pkg = act.packageName;
19882            uid = act.info.applicationInfo.uid;
19883        } else {
19884            pkg = null;
19885            uid = -1;
19886        }
19887        // Has the UID or resumed package name changed?
19888        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19889                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19890            if (mCurResumedPackage != null) {
19891                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19892                        mCurResumedPackage, mCurResumedUid);
19893            }
19894            mCurResumedPackage = pkg;
19895            mCurResumedUid = uid;
19896            if (mCurResumedPackage != null) {
19897                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19898                        mCurResumedPackage, mCurResumedUid);
19899            }
19900        }
19901        return act;
19902    }
19903
19904    final boolean updateOomAdjLocked(ProcessRecord app) {
19905        final ActivityRecord TOP_ACT = resumedAppLocked();
19906        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19907        final boolean wasCached = app.cached;
19908
19909        mAdjSeq++;
19910
19911        // This is the desired cached adjusment we want to tell it to use.
19912        // If our app is currently cached, we know it, and that is it.  Otherwise,
19913        // we don't know it yet, and it needs to now be cached we will then
19914        // need to do a complete oom adj.
19915        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19916                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19917        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19918                SystemClock.uptimeMillis());
19919        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19920            // Changed to/from cached state, so apps after it in the LRU
19921            // list may also be changed.
19922            updateOomAdjLocked();
19923        }
19924        return success;
19925    }
19926
19927    final void updateOomAdjLocked() {
19928        final ActivityRecord TOP_ACT = resumedAppLocked();
19929        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19930        final long now = SystemClock.uptimeMillis();
19931        final long nowElapsed = SystemClock.elapsedRealtime();
19932        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19933        final int N = mLruProcesses.size();
19934
19935        if (false) {
19936            RuntimeException e = new RuntimeException();
19937            e.fillInStackTrace();
19938            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19939        }
19940
19941        // Reset state in all uid records.
19942        for (int i=mActiveUids.size()-1; i>=0; i--) {
19943            final UidRecord uidRec = mActiveUids.valueAt(i);
19944            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19945                    "Starting update of " + uidRec);
19946            uidRec.reset();
19947        }
19948
19949        mStackSupervisor.rankTaskLayersIfNeeded();
19950
19951        mAdjSeq++;
19952        mNewNumServiceProcs = 0;
19953        mNewNumAServiceProcs = 0;
19954
19955        final int emptyProcessLimit;
19956        final int cachedProcessLimit;
19957        if (mProcessLimit <= 0) {
19958            emptyProcessLimit = cachedProcessLimit = 0;
19959        } else if (mProcessLimit == 1) {
19960            emptyProcessLimit = 1;
19961            cachedProcessLimit = 0;
19962        } else {
19963            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19964            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19965        }
19966
19967        // Let's determine how many processes we have running vs.
19968        // how many slots we have for background processes; we may want
19969        // to put multiple processes in a slot of there are enough of
19970        // them.
19971        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19972                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19973        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19974        if (numEmptyProcs > cachedProcessLimit) {
19975            // If there are more empty processes than our limit on cached
19976            // processes, then use the cached process limit for the factor.
19977            // This ensures that the really old empty processes get pushed
19978            // down to the bottom, so if we are running low on memory we will
19979            // have a better chance at keeping around more cached processes
19980            // instead of a gazillion empty processes.
19981            numEmptyProcs = cachedProcessLimit;
19982        }
19983        int emptyFactor = numEmptyProcs/numSlots;
19984        if (emptyFactor < 1) emptyFactor = 1;
19985        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19986        if (cachedFactor < 1) cachedFactor = 1;
19987        int stepCached = 0;
19988        int stepEmpty = 0;
19989        int numCached = 0;
19990        int numEmpty = 0;
19991        int numTrimming = 0;
19992
19993        mNumNonCachedProcs = 0;
19994        mNumCachedHiddenProcs = 0;
19995
19996        // First update the OOM adjustment for each of the
19997        // application processes based on their current state.
19998        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19999        int nextCachedAdj = curCachedAdj+1;
20000        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20001        int nextEmptyAdj = curEmptyAdj+2;
20002        for (int i=N-1; i>=0; i--) {
20003            ProcessRecord app = mLruProcesses.get(i);
20004            if (!app.killedByAm && app.thread != null) {
20005                app.procStateChanged = false;
20006                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20007
20008                // If we haven't yet assigned the final cached adj
20009                // to the process, do that now.
20010                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20011                    switch (app.curProcState) {
20012                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20013                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20014                            // This process is a cached process holding activities...
20015                            // assign it the next cached value for that type, and then
20016                            // step that cached level.
20017                            app.curRawAdj = curCachedAdj;
20018                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20019                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20020                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20021                                    + ")");
20022                            if (curCachedAdj != nextCachedAdj) {
20023                                stepCached++;
20024                                if (stepCached >= cachedFactor) {
20025                                    stepCached = 0;
20026                                    curCachedAdj = nextCachedAdj;
20027                                    nextCachedAdj += 2;
20028                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20029                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20030                                    }
20031                                }
20032                            }
20033                            break;
20034                        default:
20035                            // For everything else, assign next empty cached process
20036                            // level and bump that up.  Note that this means that
20037                            // long-running services that have dropped down to the
20038                            // cached level will be treated as empty (since their process
20039                            // state is still as a service), which is what we want.
20040                            app.curRawAdj = curEmptyAdj;
20041                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20042                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20043                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20044                                    + ")");
20045                            if (curEmptyAdj != nextEmptyAdj) {
20046                                stepEmpty++;
20047                                if (stepEmpty >= emptyFactor) {
20048                                    stepEmpty = 0;
20049                                    curEmptyAdj = nextEmptyAdj;
20050                                    nextEmptyAdj += 2;
20051                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20052                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20053                                    }
20054                                }
20055                            }
20056                            break;
20057                    }
20058                }
20059
20060                applyOomAdjLocked(app, true, now, nowElapsed);
20061
20062                // Count the number of process types.
20063                switch (app.curProcState) {
20064                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20065                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20066                        mNumCachedHiddenProcs++;
20067                        numCached++;
20068                        if (numCached > cachedProcessLimit) {
20069                            app.kill("cached #" + numCached, true);
20070                        }
20071                        break;
20072                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20073                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20074                                && app.lastActivityTime < oldTime) {
20075                            app.kill("empty for "
20076                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20077                                    / 1000) + "s", true);
20078                        } else {
20079                            numEmpty++;
20080                            if (numEmpty > emptyProcessLimit) {
20081                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20082                            }
20083                        }
20084                        break;
20085                    default:
20086                        mNumNonCachedProcs++;
20087                        break;
20088                }
20089
20090                if (app.isolated && app.services.size() <= 0) {
20091                    // If this is an isolated process, and there are no
20092                    // services running in it, then the process is no longer
20093                    // needed.  We agressively kill these because we can by
20094                    // definition not re-use the same process again, and it is
20095                    // good to avoid having whatever code was running in them
20096                    // left sitting around after no longer needed.
20097                    app.kill("isolated not needed", true);
20098                } else {
20099                    // Keeping this process, update its uid.
20100                    final UidRecord uidRec = app.uidRecord;
20101                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20102                        uidRec.curProcState = app.curProcState;
20103                    }
20104                }
20105
20106                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20107                        && !app.killedByAm) {
20108                    numTrimming++;
20109                }
20110            }
20111        }
20112
20113        mNumServiceProcs = mNewNumServiceProcs;
20114
20115        // Now determine the memory trimming level of background processes.
20116        // Unfortunately we need to start at the back of the list to do this
20117        // properly.  We only do this if the number of background apps we
20118        // are managing to keep around is less than half the maximum we desire;
20119        // if we are keeping a good number around, we'll let them use whatever
20120        // memory they want.
20121        final int numCachedAndEmpty = numCached + numEmpty;
20122        int memFactor;
20123        if (numCached <= ProcessList.TRIM_CACHED_APPS
20124                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20125            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20126                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20127            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20128                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20129            } else {
20130                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20131            }
20132        } else {
20133            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20134        }
20135        // We always allow the memory level to go up (better).  We only allow it to go
20136        // down if we are in a state where that is allowed, *and* the total number of processes
20137        // has gone down since last time.
20138        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20139                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20140                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20141        if (memFactor > mLastMemoryLevel) {
20142            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20143                memFactor = mLastMemoryLevel;
20144                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20145            }
20146        }
20147        mLastMemoryLevel = memFactor;
20148        mLastNumProcesses = mLruProcesses.size();
20149        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20150        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20151        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20152            if (mLowRamStartTime == 0) {
20153                mLowRamStartTime = now;
20154            }
20155            int step = 0;
20156            int fgTrimLevel;
20157            switch (memFactor) {
20158                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20159                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20160                    break;
20161                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20162                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20163                    break;
20164                default:
20165                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20166                    break;
20167            }
20168            int factor = numTrimming/3;
20169            int minFactor = 2;
20170            if (mHomeProcess != null) minFactor++;
20171            if (mPreviousProcess != null) minFactor++;
20172            if (factor < minFactor) factor = minFactor;
20173            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20174            for (int i=N-1; i>=0; i--) {
20175                ProcessRecord app = mLruProcesses.get(i);
20176                if (allChanged || app.procStateChanged) {
20177                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20178                    app.procStateChanged = false;
20179                }
20180                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20181                        && !app.killedByAm) {
20182                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20183                        try {
20184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20185                                    "Trimming memory of " + app.processName + " to " + curLevel);
20186                            app.thread.scheduleTrimMemory(curLevel);
20187                        } catch (RemoteException e) {
20188                        }
20189                        if (false) {
20190                            // For now we won't do this; our memory trimming seems
20191                            // to be good enough at this point that destroying
20192                            // activities causes more harm than good.
20193                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20194                                    && app != mHomeProcess && app != mPreviousProcess) {
20195                                // Need to do this on its own message because the stack may not
20196                                // be in a consistent state at this point.
20197                                // For these apps we will also finish their activities
20198                                // to help them free memory.
20199                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20200                            }
20201                        }
20202                    }
20203                    app.trimMemoryLevel = curLevel;
20204                    step++;
20205                    if (step >= factor) {
20206                        step = 0;
20207                        switch (curLevel) {
20208                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20209                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20210                                break;
20211                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20212                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20213                                break;
20214                        }
20215                    }
20216                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20217                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20218                            && app.thread != null) {
20219                        try {
20220                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20221                                    "Trimming memory of heavy-weight " + app.processName
20222                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20223                            app.thread.scheduleTrimMemory(
20224                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20225                        } catch (RemoteException e) {
20226                        }
20227                    }
20228                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20229                } else {
20230                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20231                            || app.systemNoUi) && app.pendingUiClean) {
20232                        // If this application is now in the background and it
20233                        // had done UI, then give it the special trim level to
20234                        // have it free UI resources.
20235                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20236                        if (app.trimMemoryLevel < level && app.thread != null) {
20237                            try {
20238                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20239                                        "Trimming memory of bg-ui " + app.processName
20240                                        + " to " + level);
20241                                app.thread.scheduleTrimMemory(level);
20242                            } catch (RemoteException e) {
20243                            }
20244                        }
20245                        app.pendingUiClean = false;
20246                    }
20247                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20248                        try {
20249                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20250                                    "Trimming memory of fg " + app.processName
20251                                    + " to " + fgTrimLevel);
20252                            app.thread.scheduleTrimMemory(fgTrimLevel);
20253                        } catch (RemoteException e) {
20254                        }
20255                    }
20256                    app.trimMemoryLevel = fgTrimLevel;
20257                }
20258            }
20259        } else {
20260            if (mLowRamStartTime != 0) {
20261                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20262                mLowRamStartTime = 0;
20263            }
20264            for (int i=N-1; i>=0; i--) {
20265                ProcessRecord app = mLruProcesses.get(i);
20266                if (allChanged || app.procStateChanged) {
20267                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20268                    app.procStateChanged = false;
20269                }
20270                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20271                        || app.systemNoUi) && app.pendingUiClean) {
20272                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20273                            && app.thread != null) {
20274                        try {
20275                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20276                                    "Trimming memory of ui hidden " + app.processName
20277                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20278                            app.thread.scheduleTrimMemory(
20279                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20280                        } catch (RemoteException e) {
20281                        }
20282                    }
20283                    app.pendingUiClean = false;
20284                }
20285                app.trimMemoryLevel = 0;
20286            }
20287        }
20288
20289        if (mAlwaysFinishActivities) {
20290            // Need to do this on its own message because the stack may not
20291            // be in a consistent state at this point.
20292            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20293        }
20294
20295        if (allChanged) {
20296            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20297        }
20298
20299        // Update from any uid changes.
20300        for (int i=mActiveUids.size()-1; i>=0; i--) {
20301            final UidRecord uidRec = mActiveUids.valueAt(i);
20302            int uidChange = UidRecord.CHANGE_PROCSTATE;
20303            if (uidRec.setProcState != uidRec.curProcState) {
20304                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20305                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20306                        + " to " + uidRec.curProcState);
20307                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20308                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20309                        uidRec.lastBackgroundTime = nowElapsed;
20310                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20311                            // Note: the background settle time is in elapsed realtime, while
20312                            // the handler time base is uptime.  All this means is that we may
20313                            // stop background uids later than we had intended, but that only
20314                            // happens because the device was sleeping so we are okay anyway.
20315                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20316                        }
20317                    }
20318                } else {
20319                    if (uidRec.idle) {
20320                        uidChange = UidRecord.CHANGE_ACTIVE;
20321                        uidRec.idle = false;
20322                    }
20323                    uidRec.lastBackgroundTime = 0;
20324                }
20325                uidRec.setProcState = uidRec.curProcState;
20326                enqueueUidChangeLocked(uidRec, -1, uidChange);
20327                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20328            }
20329        }
20330
20331        if (mProcessStats.shouldWriteNowLocked(now)) {
20332            mHandler.post(new Runnable() {
20333                @Override public void run() {
20334                    synchronized (ActivityManagerService.this) {
20335                        mProcessStats.writeStateAsyncLocked();
20336                    }
20337                }
20338            });
20339        }
20340
20341        if (DEBUG_OOM_ADJ) {
20342            final long duration = SystemClock.uptimeMillis() - now;
20343            if (false) {
20344                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20345                        new RuntimeException("here").fillInStackTrace());
20346            } else {
20347                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20348            }
20349        }
20350    }
20351
20352    final void idleUids() {
20353        synchronized (this) {
20354            final long nowElapsed = SystemClock.elapsedRealtime();
20355            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20356            long nextTime = 0;
20357            for (int i=mActiveUids.size()-1; i>=0; i--) {
20358                final UidRecord uidRec = mActiveUids.valueAt(i);
20359                final long bgTime = uidRec.lastBackgroundTime;
20360                if (bgTime > 0 && !uidRec.idle) {
20361                    if (bgTime <= maxBgTime) {
20362                        uidRec.idle = true;
20363                        doStopUidLocked(uidRec.uid, uidRec);
20364                    } else {
20365                        if (nextTime == 0 || nextTime > bgTime) {
20366                            nextTime = bgTime;
20367                        }
20368                    }
20369                }
20370            }
20371            if (nextTime > 0) {
20372                mHandler.removeMessages(IDLE_UIDS_MSG);
20373                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20374                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20375            }
20376        }
20377    }
20378
20379    final void runInBackgroundDisabled(int uid) {
20380        synchronized (this) {
20381            UidRecord uidRec = mActiveUids.get(uid);
20382            if (uidRec != null) {
20383                // This uid is actually running...  should it be considered background now?
20384                if (uidRec.idle) {
20385                    doStopUidLocked(uidRec.uid, uidRec);
20386                }
20387            } else {
20388                // This uid isn't actually running...  still send a report about it being "stopped".
20389                doStopUidLocked(uid, null);
20390            }
20391        }
20392    }
20393
20394    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20395        mServices.stopInBackgroundLocked(uid);
20396        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20397    }
20398
20399    final void trimApplications() {
20400        synchronized (this) {
20401            int i;
20402
20403            // First remove any unused application processes whose package
20404            // has been removed.
20405            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20406                final ProcessRecord app = mRemovedProcesses.get(i);
20407                if (app.activities.size() == 0
20408                        && app.curReceiver == null && app.services.size() == 0) {
20409                    Slog.i(
20410                        TAG, "Exiting empty application process "
20411                        + app.processName + " ("
20412                        + (app.thread != null ? app.thread.asBinder() : null)
20413                        + ")\n");
20414                    if (app.pid > 0 && app.pid != MY_PID) {
20415                        app.kill("empty", false);
20416                    } else {
20417                        try {
20418                            app.thread.scheduleExit();
20419                        } catch (Exception e) {
20420                            // Ignore exceptions.
20421                        }
20422                    }
20423                    cleanUpApplicationRecordLocked(app, false, true, -1);
20424                    mRemovedProcesses.remove(i);
20425
20426                    if (app.persistent) {
20427                        addAppLocked(app.info, false, null /* ABI override */);
20428                    }
20429                }
20430            }
20431
20432            // Now update the oom adj for all processes.
20433            updateOomAdjLocked();
20434        }
20435    }
20436
20437    /** This method sends the specified signal to each of the persistent apps */
20438    public void signalPersistentProcesses(int sig) throws RemoteException {
20439        if (sig != Process.SIGNAL_USR1) {
20440            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20441        }
20442
20443        synchronized (this) {
20444            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20445                    != PackageManager.PERMISSION_GRANTED) {
20446                throw new SecurityException("Requires permission "
20447                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20448            }
20449
20450            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20451                ProcessRecord r = mLruProcesses.get(i);
20452                if (r.thread != null && r.persistent) {
20453                    Process.sendSignal(r.pid, sig);
20454                }
20455            }
20456        }
20457    }
20458
20459    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20460        if (proc == null || proc == mProfileProc) {
20461            proc = mProfileProc;
20462            profileType = mProfileType;
20463            clearProfilerLocked();
20464        }
20465        if (proc == null) {
20466            return;
20467        }
20468        try {
20469            proc.thread.profilerControl(false, null, profileType);
20470        } catch (RemoteException e) {
20471            throw new IllegalStateException("Process disappeared");
20472        }
20473    }
20474
20475    private void clearProfilerLocked() {
20476        if (mProfileFd != null) {
20477            try {
20478                mProfileFd.close();
20479            } catch (IOException e) {
20480            }
20481        }
20482        mProfileApp = null;
20483        mProfileProc = null;
20484        mProfileFile = null;
20485        mProfileType = 0;
20486        mAutoStopProfiler = false;
20487        mSamplingInterval = 0;
20488    }
20489
20490    public boolean profileControl(String process, int userId, boolean start,
20491            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20492
20493        try {
20494            synchronized (this) {
20495                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20496                // its own permission.
20497                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20498                        != PackageManager.PERMISSION_GRANTED) {
20499                    throw new SecurityException("Requires permission "
20500                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20501                }
20502
20503                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20504                    throw new IllegalArgumentException("null profile info or fd");
20505                }
20506
20507                ProcessRecord proc = null;
20508                if (process != null) {
20509                    proc = findProcessLocked(process, userId, "profileControl");
20510                }
20511
20512                if (start && (proc == null || proc.thread == null)) {
20513                    throw new IllegalArgumentException("Unknown process: " + process);
20514                }
20515
20516                if (start) {
20517                    stopProfilerLocked(null, 0);
20518                    setProfileApp(proc.info, proc.processName, profilerInfo);
20519                    mProfileProc = proc;
20520                    mProfileType = profileType;
20521                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20522                    try {
20523                        fd = fd.dup();
20524                    } catch (IOException e) {
20525                        fd = null;
20526                    }
20527                    profilerInfo.profileFd = fd;
20528                    proc.thread.profilerControl(start, profilerInfo, profileType);
20529                    fd = null;
20530                    mProfileFd = null;
20531                } else {
20532                    stopProfilerLocked(proc, profileType);
20533                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20534                        try {
20535                            profilerInfo.profileFd.close();
20536                        } catch (IOException e) {
20537                        }
20538                    }
20539                }
20540
20541                return true;
20542            }
20543        } catch (RemoteException e) {
20544            throw new IllegalStateException("Process disappeared");
20545        } finally {
20546            if (profilerInfo != null && profilerInfo.profileFd != null) {
20547                try {
20548                    profilerInfo.profileFd.close();
20549                } catch (IOException e) {
20550                }
20551            }
20552        }
20553    }
20554
20555    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20556        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20557                userId, true, ALLOW_FULL_ONLY, callName, null);
20558        ProcessRecord proc = null;
20559        try {
20560            int pid = Integer.parseInt(process);
20561            synchronized (mPidsSelfLocked) {
20562                proc = mPidsSelfLocked.get(pid);
20563            }
20564        } catch (NumberFormatException e) {
20565        }
20566
20567        if (proc == null) {
20568            ArrayMap<String, SparseArray<ProcessRecord>> all
20569                    = mProcessNames.getMap();
20570            SparseArray<ProcessRecord> procs = all.get(process);
20571            if (procs != null && procs.size() > 0) {
20572                proc = procs.valueAt(0);
20573                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20574                    for (int i=1; i<procs.size(); i++) {
20575                        ProcessRecord thisProc = procs.valueAt(i);
20576                        if (thisProc.userId == userId) {
20577                            proc = thisProc;
20578                            break;
20579                        }
20580                    }
20581                }
20582            }
20583        }
20584
20585        return proc;
20586    }
20587
20588    public boolean dumpHeap(String process, int userId, boolean managed,
20589            String path, ParcelFileDescriptor fd) throws RemoteException {
20590
20591        try {
20592            synchronized (this) {
20593                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20594                // its own permission (same as profileControl).
20595                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20596                        != PackageManager.PERMISSION_GRANTED) {
20597                    throw new SecurityException("Requires permission "
20598                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20599                }
20600
20601                if (fd == null) {
20602                    throw new IllegalArgumentException("null fd");
20603                }
20604
20605                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20606                if (proc == null || proc.thread == null) {
20607                    throw new IllegalArgumentException("Unknown process: " + process);
20608                }
20609
20610                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20611                if (!isDebuggable) {
20612                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20613                        throw new SecurityException("Process not debuggable: " + proc);
20614                    }
20615                }
20616
20617                proc.thread.dumpHeap(managed, path, fd);
20618                fd = null;
20619                return true;
20620            }
20621        } catch (RemoteException e) {
20622            throw new IllegalStateException("Process disappeared");
20623        } finally {
20624            if (fd != null) {
20625                try {
20626                    fd.close();
20627                } catch (IOException e) {
20628                }
20629            }
20630        }
20631    }
20632
20633    @Override
20634    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20635            String reportPackage) {
20636        if (processName != null) {
20637            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20638                    "setDumpHeapDebugLimit()");
20639        } else {
20640            synchronized (mPidsSelfLocked) {
20641                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20642                if (proc == null) {
20643                    throw new SecurityException("No process found for calling pid "
20644                            + Binder.getCallingPid());
20645                }
20646                if (!Build.IS_DEBUGGABLE
20647                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20648                    throw new SecurityException("Not running a debuggable build");
20649                }
20650                processName = proc.processName;
20651                uid = proc.uid;
20652                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20653                    throw new SecurityException("Package " + reportPackage + " is not running in "
20654                            + proc);
20655                }
20656            }
20657        }
20658        synchronized (this) {
20659            if (maxMemSize > 0) {
20660                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20661            } else {
20662                if (uid != 0) {
20663                    mMemWatchProcesses.remove(processName, uid);
20664                } else {
20665                    mMemWatchProcesses.getMap().remove(processName);
20666                }
20667            }
20668        }
20669    }
20670
20671    @Override
20672    public void dumpHeapFinished(String path) {
20673        synchronized (this) {
20674            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20675                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20676                        + " does not match last pid " + mMemWatchDumpPid);
20677                return;
20678            }
20679            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20680                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20681                        + " does not match last path " + mMemWatchDumpFile);
20682                return;
20683            }
20684            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20685            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20686        }
20687    }
20688
20689    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20690    public void monitor() {
20691        synchronized (this) { }
20692    }
20693
20694    void onCoreSettingsChange(Bundle settings) {
20695        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20696            ProcessRecord processRecord = mLruProcesses.get(i);
20697            try {
20698                if (processRecord.thread != null) {
20699                    processRecord.thread.setCoreSettings(settings);
20700                }
20701            } catch (RemoteException re) {
20702                /* ignore */
20703            }
20704        }
20705    }
20706
20707    // Multi-user methods
20708
20709    /**
20710     * Start user, if its not already running, but don't bring it to foreground.
20711     */
20712    @Override
20713    public boolean startUserInBackground(final int userId) {
20714        return mUserController.startUser(userId, /* foreground */ false);
20715    }
20716
20717    @Override
20718    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20719        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20720    }
20721
20722    @Override
20723    public boolean switchUser(final int targetUserId) {
20724        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20725        UserInfo currentUserInfo;
20726        UserInfo targetUserInfo;
20727        synchronized (this) {
20728            int currentUserId = mUserController.getCurrentUserIdLocked();
20729            currentUserInfo = mUserController.getUserInfo(currentUserId);
20730            targetUserInfo = mUserController.getUserInfo(targetUserId);
20731            if (targetUserInfo == null) {
20732                Slog.w(TAG, "No user info for user #" + targetUserId);
20733                return false;
20734            }
20735            if (!targetUserInfo.supportsSwitchTo()) {
20736                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20737                return false;
20738            }
20739            if (targetUserInfo.isManagedProfile()) {
20740                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20741                return false;
20742            }
20743            mUserController.setTargetUserIdLocked(targetUserId);
20744        }
20745        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20746        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20747        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20748        return true;
20749    }
20750
20751    void scheduleStartProfilesLocked() {
20752        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20753            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20754                    DateUtils.SECOND_IN_MILLIS);
20755        }
20756    }
20757
20758    @Override
20759    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20760        return mUserController.stopUser(userId, force, callback);
20761    }
20762
20763    @Override
20764    public UserInfo getCurrentUser() {
20765        return mUserController.getCurrentUser();
20766    }
20767
20768    @Override
20769    public boolean isUserRunning(int userId, int flags) {
20770        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20771                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20772            String msg = "Permission Denial: isUserRunning() from pid="
20773                    + Binder.getCallingPid()
20774                    + ", uid=" + Binder.getCallingUid()
20775                    + " requires " + INTERACT_ACROSS_USERS;
20776            Slog.w(TAG, msg);
20777            throw new SecurityException(msg);
20778        }
20779        synchronized (this) {
20780            return mUserController.isUserRunningLocked(userId, flags);
20781        }
20782    }
20783
20784    @Override
20785    public int[] getRunningUserIds() {
20786        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20787                != PackageManager.PERMISSION_GRANTED) {
20788            String msg = "Permission Denial: isUserRunning() from pid="
20789                    + Binder.getCallingPid()
20790                    + ", uid=" + Binder.getCallingUid()
20791                    + " requires " + INTERACT_ACROSS_USERS;
20792            Slog.w(TAG, msg);
20793            throw new SecurityException(msg);
20794        }
20795        synchronized (this) {
20796            return mUserController.getStartedUserArrayLocked();
20797        }
20798    }
20799
20800    @Override
20801    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20802        mUserController.registerUserSwitchObserver(observer);
20803    }
20804
20805    @Override
20806    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20807        mUserController.unregisterUserSwitchObserver(observer);
20808    }
20809
20810    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20811        if (info == null) return null;
20812        ApplicationInfo newInfo = new ApplicationInfo(info);
20813        newInfo.initForUser(userId);
20814        return newInfo;
20815    }
20816
20817    public boolean isUserStopped(int userId) {
20818        synchronized (this) {
20819            return mUserController.getStartedUserStateLocked(userId) == null;
20820        }
20821    }
20822
20823    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20824        if (aInfo == null
20825                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20826            return aInfo;
20827        }
20828
20829        ActivityInfo info = new ActivityInfo(aInfo);
20830        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20831        return info;
20832    }
20833
20834    private boolean processSanityChecksLocked(ProcessRecord process) {
20835        if (process == null || process.thread == null) {
20836            return false;
20837        }
20838
20839        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20840        if (!isDebuggable) {
20841            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20842                return false;
20843            }
20844        }
20845
20846        return true;
20847    }
20848
20849    public boolean startBinderTracking() throws RemoteException {
20850        synchronized (this) {
20851            mBinderTransactionTrackingEnabled = true;
20852            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20853            // permission (same as profileControl).
20854            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20855                    != PackageManager.PERMISSION_GRANTED) {
20856                throw new SecurityException("Requires permission "
20857                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20858            }
20859
20860            for (int i = 0; i < mLruProcesses.size(); i++) {
20861                ProcessRecord process = mLruProcesses.get(i);
20862                if (!processSanityChecksLocked(process)) {
20863                    continue;
20864                }
20865                try {
20866                    process.thread.startBinderTracking();
20867                } catch (RemoteException e) {
20868                    Log.v(TAG, "Process disappared");
20869                }
20870            }
20871            return true;
20872        }
20873    }
20874
20875    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20876        try {
20877            synchronized (this) {
20878                mBinderTransactionTrackingEnabled = false;
20879                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20880                // permission (same as profileControl).
20881                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20882                        != PackageManager.PERMISSION_GRANTED) {
20883                    throw new SecurityException("Requires permission "
20884                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20885                }
20886
20887                if (fd == null) {
20888                    throw new IllegalArgumentException("null fd");
20889                }
20890
20891                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20892                pw.println("Binder transaction traces for all processes.\n");
20893                for (ProcessRecord process : mLruProcesses) {
20894                    if (!processSanityChecksLocked(process)) {
20895                        continue;
20896                    }
20897
20898                    pw.println("Traces for process: " + process.processName);
20899                    pw.flush();
20900                    try {
20901                        TransferPipe tp = new TransferPipe();
20902                        try {
20903                            process.thread.stopBinderTrackingAndDump(
20904                                    tp.getWriteFd().getFileDescriptor());
20905                            tp.go(fd.getFileDescriptor());
20906                        } finally {
20907                            tp.kill();
20908                        }
20909                    } catch (IOException e) {
20910                        pw.println("Failure while dumping IPC traces from " + process +
20911                                ".  Exception: " + e);
20912                        pw.flush();
20913                    } catch (RemoteException e) {
20914                        pw.println("Got a RemoteException while dumping IPC traces from " +
20915                                process + ".  Exception: " + e);
20916                        pw.flush();
20917                    }
20918                }
20919                fd = null;
20920                return true;
20921            }
20922        } finally {
20923            if (fd != null) {
20924                try {
20925                    fd.close();
20926                } catch (IOException e) {
20927                }
20928            }
20929        }
20930    }
20931
20932    private final class LocalService extends ActivityManagerInternal {
20933        @Override
20934        public void onWakefulnessChanged(int wakefulness) {
20935            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20936        }
20937
20938        @Override
20939        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20940                String processName, String abiOverride, int uid, Runnable crashHandler) {
20941            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20942                    processName, abiOverride, uid, crashHandler);
20943        }
20944
20945        @Override
20946        public SleepToken acquireSleepToken(String tag) {
20947            Preconditions.checkNotNull(tag);
20948
20949            synchronized (ActivityManagerService.this) {
20950                SleepTokenImpl token = new SleepTokenImpl(tag);
20951                mSleepTokens.add(token);
20952                updateSleepIfNeededLocked();
20953                applyVrModeIfNeededLocked(mFocusedActivity, false);
20954                return token;
20955            }
20956        }
20957
20958        @Override
20959        public ComponentName getHomeActivityForUser(int userId) {
20960            synchronized (ActivityManagerService.this) {
20961                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20962                return homeActivity == null ? null : homeActivity.realActivity;
20963            }
20964        }
20965
20966        @Override
20967        public void onUserRemoved(int userId) {
20968            synchronized (ActivityManagerService.this) {
20969                ActivityManagerService.this.onUserStoppedLocked(userId);
20970            }
20971        }
20972
20973        @Override
20974        public void onLocalVoiceInteractionStarted(IBinder activity,
20975                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20976            synchronized (ActivityManagerService.this) {
20977                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20978                        voiceSession, voiceInteractor);
20979            }
20980        }
20981
20982        @Override
20983        public void notifyStartingWindowDrawn() {
20984            synchronized (ActivityManagerService.this) {
20985                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20986            }
20987        }
20988
20989        @Override
20990        public void notifyAppTransitionStarting(int reason) {
20991            synchronized (ActivityManagerService.this) {
20992                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20993            }
20994        }
20995
20996        @Override
20997        public void notifyAppTransitionFinished() {
20998            synchronized (ActivityManagerService.this) {
20999                mStackSupervisor.notifyAppTransitionDone();
21000            }
21001        }
21002
21003        @Override
21004        public void notifyAppTransitionCancelled() {
21005            synchronized (ActivityManagerService.this) {
21006                mStackSupervisor.notifyAppTransitionDone();
21007            }
21008        }
21009
21010        @Override
21011        public List<IBinder> getTopVisibleActivities() {
21012            synchronized (ActivityManagerService.this) {
21013                return mStackSupervisor.getTopVisibleActivities();
21014            }
21015        }
21016    }
21017
21018    private final class SleepTokenImpl extends SleepToken {
21019        private final String mTag;
21020        private final long mAcquireTime;
21021
21022        public SleepTokenImpl(String tag) {
21023            mTag = tag;
21024            mAcquireTime = SystemClock.uptimeMillis();
21025        }
21026
21027        @Override
21028        public void release() {
21029            synchronized (ActivityManagerService.this) {
21030                if (mSleepTokens.remove(this)) {
21031                    updateSleepIfNeededLocked();
21032                }
21033            }
21034        }
21035
21036        @Override
21037        public String toString() {
21038            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21039        }
21040    }
21041
21042    /**
21043     * An implementation of IAppTask, that allows an app to manage its own tasks via
21044     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21045     * only the process that calls getAppTasks() can call the AppTask methods.
21046     */
21047    class AppTaskImpl extends IAppTask.Stub {
21048        private int mTaskId;
21049        private int mCallingUid;
21050
21051        public AppTaskImpl(int taskId, int callingUid) {
21052            mTaskId = taskId;
21053            mCallingUid = callingUid;
21054        }
21055
21056        private void checkCaller() {
21057            if (mCallingUid != Binder.getCallingUid()) {
21058                throw new SecurityException("Caller " + mCallingUid
21059                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21060            }
21061        }
21062
21063        @Override
21064        public void finishAndRemoveTask() {
21065            checkCaller();
21066
21067            synchronized (ActivityManagerService.this) {
21068                long origId = Binder.clearCallingIdentity();
21069                try {
21070                    // We remove the task from recents to preserve backwards
21071                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21072                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21073                    }
21074                } finally {
21075                    Binder.restoreCallingIdentity(origId);
21076                }
21077            }
21078        }
21079
21080        @Override
21081        public ActivityManager.RecentTaskInfo getTaskInfo() {
21082            checkCaller();
21083
21084            synchronized (ActivityManagerService.this) {
21085                long origId = Binder.clearCallingIdentity();
21086                try {
21087                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21088                    if (tr == null) {
21089                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21090                    }
21091                    return createRecentTaskInfoFromTaskRecord(tr);
21092                } finally {
21093                    Binder.restoreCallingIdentity(origId);
21094                }
21095            }
21096        }
21097
21098        @Override
21099        public void moveToFront() {
21100            checkCaller();
21101            // Will bring task to front if it already has a root activity.
21102            final long origId = Binder.clearCallingIdentity();
21103            try {
21104                synchronized (this) {
21105                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21106                }
21107            } finally {
21108                Binder.restoreCallingIdentity(origId);
21109            }
21110        }
21111
21112        @Override
21113        public int startActivity(IBinder whoThread, String callingPackage,
21114                Intent intent, String resolvedType, Bundle bOptions) {
21115            checkCaller();
21116
21117            int callingUser = UserHandle.getCallingUserId();
21118            TaskRecord tr;
21119            IApplicationThread appThread;
21120            synchronized (ActivityManagerService.this) {
21121                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21122                if (tr == null) {
21123                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21124                }
21125                appThread = ApplicationThreadNative.asInterface(whoThread);
21126                if (appThread == null) {
21127                    throw new IllegalArgumentException("Bad app thread " + appThread);
21128                }
21129            }
21130            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21131                    resolvedType, null, null, null, null, 0, 0, null, null,
21132                    null, bOptions, false, callingUser, null, tr);
21133        }
21134
21135        @Override
21136        public void setExcludeFromRecents(boolean exclude) {
21137            checkCaller();
21138
21139            synchronized (ActivityManagerService.this) {
21140                long origId = Binder.clearCallingIdentity();
21141                try {
21142                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21143                    if (tr == null) {
21144                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21145                    }
21146                    Intent intent = tr.getBaseIntent();
21147                    if (exclude) {
21148                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21149                    } else {
21150                        intent.setFlags(intent.getFlags()
21151                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21152                    }
21153                } finally {
21154                    Binder.restoreCallingIdentity(origId);
21155                }
21156            }
21157        }
21158    }
21159
21160    /**
21161     * Kill processes for the user with id userId and that depend on the package named packageName
21162     */
21163    @Override
21164    public void killPackageDependents(String packageName, int userId) {
21165        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21166        if (packageName == null) {
21167            throw new NullPointerException(
21168                    "Cannot kill the dependents of a package without its name.");
21169        }
21170
21171        long callingId = Binder.clearCallingIdentity();
21172        IPackageManager pm = AppGlobals.getPackageManager();
21173        int pkgUid = -1;
21174        try {
21175            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21176        } catch (RemoteException e) {
21177        }
21178        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21179            throw new IllegalArgumentException(
21180                    "Cannot kill dependents of non-existing package " + packageName);
21181        }
21182        try {
21183            synchronized(this) {
21184                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21185                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21186                        "dep: " + packageName);
21187            }
21188        } finally {
21189            Binder.restoreCallingIdentity(callingId);
21190        }
21191    }
21192}
21193