ActivityManagerService.java revision 2fd3f122bfb3557f3324a480e09c8777eaf53b6f
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.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
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.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.vr.VrManagerInternal;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
63
64import android.Manifest;
65import android.app.Activity;
66import android.app.ActivityManager;
67import android.app.ActivityManager.RunningTaskInfo;
68import android.app.ActivityManager.StackId;
69import android.app.ActivityManager.StackInfo;
70import android.app.ActivityManager.TaskThumbnailInfo;
71import android.app.ActivityManagerInternal;
72import android.app.ActivityManagerInternal.SleepToken;
73import android.app.ActivityManagerNative;
74import android.app.ActivityOptions;
75import android.app.ActivityThread;
76import android.app.AlertDialog;
77import android.app.AppGlobals;
78import android.app.AppOpsManager;
79import android.app.ApplicationErrorReport;
80import android.app.ApplicationThreadNative;
81import android.app.BroadcastOptions;
82import android.app.Dialog;
83import android.app.IActivityContainer;
84import android.app.IActivityContainerCallback;
85import android.app.IActivityController;
86import android.app.IAppTask;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.ITaskStackListener;
94import android.app.IUiAutomationConnection;
95import android.app.IUidObserver;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.ProfilerInfo;
102import android.app.admin.DevicePolicyManager;
103import android.app.assist.AssistContent;
104import android.app.assist.AssistStructure;
105import android.app.backup.IBackupManager;
106import android.app.usage.UsageEvents;
107import android.app.usage.UsageStatsManagerInternal;
108import android.appwidget.AppWidgetManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PackageManagerInternal;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.PathPermission;
136import android.content.pm.PermissionInfo;
137import android.content.pm.ProviderInfo;
138import android.content.pm.ResolveInfo;
139import android.content.pm.ServiceInfo;
140import android.content.pm.UserInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.content.res.Resources;
144import android.graphics.Bitmap;
145import android.graphics.Point;
146import android.graphics.Rect;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.BatteryStats;
151import android.os.Binder;
152import android.os.Build;
153import android.os.Bundle;
154import android.os.Debug;
155import android.os.DropBoxManager;
156import android.os.Environment;
157import android.os.FactoryTest;
158import android.os.FileObserver;
159import android.os.FileUtils;
160import android.os.Handler;
161import android.os.IBinder;
162import android.os.IPermissionController;
163import android.os.IProcessInfoService;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.PersistableBundle;
169import android.os.PowerManager;
170import android.os.PowerManagerInternal;
171import android.os.Process;
172import android.os.RemoteCallbackList;
173import android.os.RemoteException;
174import android.os.ResultReceiver;
175import android.os.ServiceManager;
176import android.os.StrictMode;
177import android.os.SystemClock;
178import android.os.SystemProperties;
179import android.os.Trace;
180import android.os.TransactionTooLargeException;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.os.WorkSource;
185import android.os.storage.IMountService;
186import android.os.storage.MountServiceInternal;
187import android.os.storage.StorageManager;
188import android.provider.Settings;
189import android.service.voice.IVoiceInteractionSession;
190import android.service.voice.VoiceInteractionSession;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.ArrayMap;
194import android.util.ArraySet;
195import android.util.AtomicFile;
196import android.util.DebugUtils;
197import android.util.EventLog;
198import android.util.LocaleList;
199import android.util.Log;
200import android.util.Pair;
201import android.util.PrintWriterPrinter;
202import android.util.Slog;
203import android.util.SparseArray;
204import android.util.TimeUtils;
205import android.util.Xml;
206import android.view.Display;
207import android.view.Gravity;
208import android.view.LayoutInflater;
209import android.view.View;
210import android.view.WindowManager;
211
212import java.io.BufferedInputStream;
213import java.io.BufferedOutputStream;
214import java.io.DataInputStream;
215import java.io.DataOutputStream;
216import java.io.File;
217import java.io.FileDescriptor;
218import java.io.FileInputStream;
219import java.io.FileNotFoundException;
220import java.io.FileOutputStream;
221import java.io.IOException;
222import java.io.InputStreamReader;
223import java.io.PrintWriter;
224import java.io.StringWriter;
225import java.lang.ref.WeakReference;
226import java.nio.charset.StandardCharsets;
227import java.util.ArrayList;
228import java.util.Arrays;
229import java.util.Collections;
230import java.util.Comparator;
231import java.util.HashMap;
232import java.util.HashSet;
233import java.util.Iterator;
234import java.util.List;
235import java.util.Locale;
236import java.util.Map;
237import java.util.Set;
238import java.util.concurrent.atomic.AtomicBoolean;
239import java.util.concurrent.atomic.AtomicLong;
240
241import dalvik.system.VMRuntime;
242
243import libcore.io.IoUtils;
244import libcore.util.EmptyArray;
245
246import static android.Manifest.permission.INTERACT_ACROSS_USERS;
247import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
248import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
249import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
250import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
251import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
252import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
253import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
254import static android.app.ActivityManager.StackId.HOME_STACK_ID;
255import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
256import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
257import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
258import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
259import static android.content.pm.PackageManager.GET_PROVIDERS;
260import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
261import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
262import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
263import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
264import static android.content.pm.PackageManager.PERMISSION_GRANTED;
265import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
266import static android.provider.Settings.Global.DEBUG_APP;
267import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
268import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
269import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
270import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
271import static com.android.internal.util.XmlUtils.readBooleanAttribute;
272import static com.android.internal.util.XmlUtils.readIntAttribute;
273import static com.android.internal.util.XmlUtils.readLongAttribute;
274import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
275import static com.android.internal.util.XmlUtils.writeIntAttribute;
276import static com.android.internal.util.XmlUtils.writeLongAttribute;
277import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
278import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
279import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
280import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
281import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
282import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
283import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
309import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
310import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
311import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
312import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
313import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
314import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
333import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
334import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
335import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
336import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
337import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
338import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
339import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
340import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
341import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
342import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
343import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
344import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
345import static org.xmlpull.v1.XmlPullParser.START_TAG;
346
347public final class ActivityManagerService extends ActivityManagerNative
348        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
349
350    // File that stores last updated system version and called preboot receivers
351    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
352
353    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
354    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
355    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
356    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
357    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
358    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
359    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
360    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
361    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
362    private static final String TAG_LRU = TAG + POSTFIX_LRU;
363    private static final String TAG_MU = TAG + POSTFIX_MU;
364    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
365    private static final String TAG_POWER = TAG + POSTFIX_POWER;
366    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
367    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
368    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
369    private static final String TAG_PSS = TAG + POSTFIX_PSS;
370    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
371    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
372    private static final String TAG_STACK = TAG + POSTFIX_STACK;
373    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
374    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
375    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
376    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
377    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
378
379    /** Control over CPU and battery monitoring */
380    // write battery stats every 30 minutes.
381    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
382    static final boolean MONITOR_CPU_USAGE = true;
383    // don't sample cpu less than every 5 seconds.
384    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
385    // wait possibly forever for next cpu sample.
386    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
387    static final boolean MONITOR_THREAD_CPU_USAGE = false;
388
389    // The flags that are set for all calls we make to the package manager.
390    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
391
392    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
393
394    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
395
396    // Amount of time after a call to stopAppSwitches() during which we will
397    // prevent further untrusted switches from happening.
398    static final long APP_SWITCH_DELAY_TIME = 5*1000;
399
400    // How long we wait for a launched process to attach to the activity manager
401    // before we decide it's never going to come up for real.
402    static final int PROC_START_TIMEOUT = 10*1000;
403    // How long we wait for an attached process to publish its content providers
404    // before we decide it must be hung.
405    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
406
407    // How long we will retain processes hosting content providers in the "last activity"
408    // state before allowing them to drop down to the regular cached LRU list.  This is
409    // to avoid thrashing of provider processes under low memory situations.
410    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
411
412    // How long we wait for a launched process to attach to the activity manager
413    // before we decide it's never going to come up for real, when the process was
414    // started with a wrapper for instrumentation (such as Valgrind) because it
415    // could take much longer than usual.
416    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
417
418    // How long to wait after going idle before forcing apps to GC.
419    static final int GC_TIMEOUT = 5*1000;
420
421    // The minimum amount of time between successive GC requests for a process.
422    static final int GC_MIN_INTERVAL = 60*1000;
423
424    // The minimum amount of time between successive PSS requests for a process.
425    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
426
427    // The minimum amount of time between successive PSS requests for a process
428    // when the request is due to the memory state being lowered.
429    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
430
431    // The rate at which we check for apps using excessive power -- 15 mins.
432    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
433
434    // The minimum sample duration we will allow before deciding we have
435    // enough data on wake locks to start killing things.
436    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
437
438    // The minimum sample duration we will allow before deciding we have
439    // enough data on CPU usage to start killing things.
440    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
441
442    // How long we allow a receiver to run before giving up on it.
443    static final int BROADCAST_FG_TIMEOUT = 10*1000;
444    static final int BROADCAST_BG_TIMEOUT = 60*1000;
445
446    // How long we wait until we timeout on key dispatching.
447    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
448
449    // How long we wait until we timeout on key dispatching during instrumentation.
450    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
451
452    // This is the amount of time an app needs to be running a foreground service before
453    // we will consider it to be doing interaction for usage stats.
454    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
455
456    // Maximum amount of time we will allow to elapse before re-reporting usage stats
457    // interaction with foreground processes.
458    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
459
460    // This is the amount of time we allow an app to settle after it goes into the background,
461    // before we start restricting what it can do.
462    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
463
464    // How long to wait in getAssistContextExtras for the activity and foreground services
465    // to respond with the result.
466    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
467
468    // How long top wait when going through the modern assist (which doesn't need to block
469    // on getting this result before starting to launch its UI).
470    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
471
472    // Maximum number of persisted Uri grants a package is allowed
473    static final int MAX_PERSISTED_URI_GRANTS = 128;
474
475    static final int MY_PID = Process.myPid();
476
477    static final String[] EMPTY_STRING_ARRAY = new String[0];
478
479    // How many bytes to write into the dropbox log before truncating
480    static final int DROPBOX_MAX_SIZE = 256 * 1024;
481
482    // Access modes for handleIncomingUser.
483    static final int ALLOW_NON_FULL = 0;
484    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
485    static final int ALLOW_FULL_ONLY = 2;
486
487    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
488
489    // Delay in notifying task stack change listeners (in millis)
490    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
491
492    // Necessary ApplicationInfo flags to mark an app as persistent
493    private static final int PERSISTENT_MASK =
494            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
495
496
497    // Delay to disable app launch boost
498    static final int APP_BOOST_MESSAGE_DELAY = 3000;
499    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
500    static final int APP_BOOST_TIMEOUT = 2500;
501
502    // Used to indicate that a task is removed it should also be removed from recents.
503    private static final boolean REMOVE_FROM_RECENTS = true;
504    // Used to indicate that an app transition should be animated.
505    static final boolean ANIMATE = true;
506
507    // Determines whether to take full screen screenshots
508    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
509
510    private static native int nativeMigrateToBoost();
511    private static native int nativeMigrateFromBoost();
512    private boolean mIsBoosted = false;
513    private long mBoostStartTime = 0;
514
515    /** All system services */
516    SystemServiceManager mSystemServiceManager;
517
518    private Installer mInstaller;
519
520    /** Run all ActivityStacks through this */
521    final ActivityStackSupervisor mStackSupervisor;
522
523    final ActivityStarter mActivityStarter;
524
525    /** Task stack change listeners. */
526    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
527            new RemoteCallbackList<ITaskStackListener>();
528
529    public IntentFirewall mIntentFirewall;
530
531    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
532    // default actuion automatically.  Important for devices without direct input
533    // devices.
534    private boolean mShowDialogs = true;
535
536    BroadcastQueue mFgBroadcastQueue;
537    BroadcastQueue mBgBroadcastQueue;
538    // Convenient for easy iteration over the queues. Foreground is first
539    // so that dispatch of foreground broadcasts gets precedence.
540    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
541
542    BroadcastQueue broadcastQueueForIntent(Intent intent) {
543        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
544        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
545                "Broadcast intent " + intent + " on "
546                + (isFg ? "foreground" : "background") + " queue");
547        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
548    }
549
550    /**
551     * Activity we have told the window manager to have key focus.
552     */
553    ActivityRecord mFocusedActivity = null;
554
555    /**
556     * User id of the last activity mFocusedActivity was set to.
557     */
558    private int mLastFocusedUserId;
559
560    /**
561     * If non-null, we are tracking the time the user spends in the currently focused app.
562     */
563    private AppTimeTracker mCurAppTimeTracker;
564
565    /**
566     * List of intents that were used to start the most recent tasks.
567     */
568    private final RecentTasks mRecentTasks;
569
570    /**
571     * For addAppTask: cached of the last activity component that was added.
572     */
573    ComponentName mLastAddedTaskComponent;
574
575    /**
576     * For addAppTask: cached of the last activity uid that was added.
577     */
578    int mLastAddedTaskUid;
579
580    /**
581     * For addAppTask: cached of the last ActivityInfo that was added.
582     */
583    ActivityInfo mLastAddedTaskActivity;
584
585    /**
586     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
587     */
588    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
589
590    /**
591     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
592     */
593    String mDeviceOwnerName;
594
595    final UserController mUserController;
596
597    public class PendingAssistExtras extends Binder implements Runnable {
598        public final ActivityRecord activity;
599        public final Bundle extras;
600        public final Intent intent;
601        public final String hint;
602        public final IResultReceiver receiver;
603        public final int userHandle;
604        public boolean haveResult = false;
605        public Bundle result = null;
606        public AssistStructure structure = null;
607        public AssistContent content = null;
608        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
609                String _hint, IResultReceiver _receiver, int _userHandle) {
610            activity = _activity;
611            extras = _extras;
612            intent = _intent;
613            hint = _hint;
614            receiver = _receiver;
615            userHandle = _userHandle;
616        }
617        @Override
618        public void run() {
619            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
620            synchronized (this) {
621                haveResult = true;
622                notifyAll();
623            }
624            pendingAssistExtrasTimedOut(this);
625        }
626    }
627
628    final ArrayList<PendingAssistExtras> mPendingAssistExtras
629            = new ArrayList<PendingAssistExtras>();
630
631    /**
632     * Process management.
633     */
634    final ProcessList mProcessList = new ProcessList();
635
636    /**
637     * All of the applications we currently have running organized by name.
638     * The keys are strings of the application package name (as
639     * returned by the package manager), and the keys are ApplicationRecord
640     * objects.
641     */
642    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
643
644    /**
645     * Tracking long-term execution of processes to look for abuse and other
646     * bad app behavior.
647     */
648    final ProcessStatsService mProcessStats;
649
650    /**
651     * The currently running isolated processes.
652     */
653    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
654
655    /**
656     * Counter for assigning isolated process uids, to avoid frequently reusing the
657     * same ones.
658     */
659    int mNextIsolatedProcessUid = 0;
660
661    /**
662     * The currently running heavy-weight process, if any.
663     */
664    ProcessRecord mHeavyWeightProcess = null;
665
666    /**
667     * The last time that various processes have crashed.
668     */
669    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
670
671    /**
672     * Information about a process that is currently marked as bad.
673     */
674    static final class BadProcessInfo {
675        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
676            this.time = time;
677            this.shortMsg = shortMsg;
678            this.longMsg = longMsg;
679            this.stack = stack;
680        }
681
682        final long time;
683        final String shortMsg;
684        final String longMsg;
685        final String stack;
686    }
687
688    /**
689     * Set of applications that we consider to be bad, and will reject
690     * incoming broadcasts from (which the user has no control over).
691     * Processes are added to this set when they have crashed twice within
692     * a minimum amount of time; they are removed from it when they are
693     * later restarted (hopefully due to some user action).  The value is the
694     * time it was added to the list.
695     */
696    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
697
698    /**
699     * All of the processes we currently have running organized by pid.
700     * The keys are the pid running the application.
701     *
702     * <p>NOTE: This object is protected by its own lock, NOT the global
703     * activity manager lock!
704     */
705    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
706
707    /**
708     * All of the processes that have been forced to be foreground.  The key
709     * is the pid of the caller who requested it (we hold a death
710     * link on it).
711     */
712    abstract class ForegroundToken implements IBinder.DeathRecipient {
713        int pid;
714        IBinder token;
715    }
716    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
717
718    /**
719     * List of records for processes that someone had tried to start before the
720     * system was ready.  We don't start them at that point, but ensure they
721     * are started by the time booting is complete.
722     */
723    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
724
725    /**
726     * List of persistent applications that are in the process
727     * of being started.
728     */
729    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
730
731    /**
732     * Processes that are being forcibly torn down.
733     */
734    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
735
736    /**
737     * List of running applications, sorted by recent usage.
738     * The first entry in the list is the least recently used.
739     */
740    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
741
742    /**
743     * Where in mLruProcesses that the processes hosting activities start.
744     */
745    int mLruProcessActivityStart = 0;
746
747    /**
748     * Where in mLruProcesses that the processes hosting services start.
749     * This is after (lower index) than mLruProcessesActivityStart.
750     */
751    int mLruProcessServiceStart = 0;
752
753    /**
754     * List of processes that should gc as soon as things are idle.
755     */
756    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
757
758    /**
759     * Processes we want to collect PSS data from.
760     */
761    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
762
763    private boolean mBinderTransactionTrackingEnabled = false;
764
765    /**
766     * Last time we requested PSS data of all processes.
767     */
768    long mLastFullPssTime = SystemClock.uptimeMillis();
769
770    /**
771     * If set, the next time we collect PSS data we should do a full collection
772     * with data from native processes and the kernel.
773     */
774    boolean mFullPssPending = false;
775
776    /**
777     * This is the process holding what we currently consider to be
778     * the "home" activity.
779     */
780    ProcessRecord mHomeProcess;
781
782    /**
783     * This is the process holding the activity the user last visited that
784     * is in a different process from the one they are currently in.
785     */
786    ProcessRecord mPreviousProcess;
787
788    /**
789     * The time at which the previous process was last visible.
790     */
791    long mPreviousProcessVisibleTime;
792
793    /**
794     * Track all uids that have actively running processes.
795     */
796    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
797
798    /**
799     * This is for verifying the UID report flow.
800     */
801    static final boolean VALIDATE_UID_STATES = true;
802    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
803
804    /**
805     * Packages that the user has asked to have run in screen size
806     * compatibility mode instead of filling the screen.
807     */
808    final CompatModePackages mCompatModePackages;
809
810    /**
811     * Set of IntentSenderRecord objects that are currently active.
812     */
813    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
814            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
815
816    /**
817     * Fingerprints (hashCode()) of stack traces that we've
818     * already logged DropBox entries for.  Guarded by itself.  If
819     * something (rogue user app) forces this over
820     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
821     */
822    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
823    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
824
825    /**
826     * Strict Mode background batched logging state.
827     *
828     * The string buffer is guarded by itself, and its lock is also
829     * used to determine if another batched write is already
830     * in-flight.
831     */
832    private final StringBuilder mStrictModeBuffer = new StringBuilder();
833
834    /**
835     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
836     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
837     */
838    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
839
840    /**
841     * Resolver for broadcast intents to registered receivers.
842     * Holds BroadcastFilter (subclass of IntentFilter).
843     */
844    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
845            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
846        @Override
847        protected boolean allowFilterResult(
848                BroadcastFilter filter, List<BroadcastFilter> dest) {
849            IBinder target = filter.receiverList.receiver.asBinder();
850            for (int i = dest.size() - 1; i >= 0; i--) {
851                if (dest.get(i).receiverList.receiver.asBinder() == target) {
852                    return false;
853                }
854            }
855            return true;
856        }
857
858        @Override
859        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
860            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
861                    || userId == filter.owningUserId) {
862                return super.newResult(filter, match, userId);
863            }
864            return null;
865        }
866
867        @Override
868        protected BroadcastFilter[] newArray(int size) {
869            return new BroadcastFilter[size];
870        }
871
872        @Override
873        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
874            return packageName.equals(filter.packageName);
875        }
876    };
877
878    /**
879     * State of all active sticky broadcasts per user.  Keys are the action of the
880     * sticky Intent, values are an ArrayList of all broadcasted intents with
881     * that action (which should usually be one).  The SparseArray is keyed
882     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
883     * for stickies that are sent to all users.
884     */
885    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
886            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
887
888    final ActiveServices mServices;
889
890    final static class Association {
891        final int mSourceUid;
892        final String mSourceProcess;
893        final int mTargetUid;
894        final ComponentName mTargetComponent;
895        final String mTargetProcess;
896
897        int mCount;
898        long mTime;
899
900        int mNesting;
901        long mStartTime;
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    /**
1017     * Thread-local storage used to carry caller permissions over through
1018     * indirect content-provider access.
1019     */
1020    private class Identity {
1021        public final IBinder token;
1022        public final int pid;
1023        public final int uid;
1024
1025        Identity(IBinder _token, int _pid, int _uid) {
1026            token = _token;
1027            pid = _pid;
1028            uid = _uid;
1029        }
1030    }
1031
1032    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1033
1034    /**
1035     * All information we have collected about the runtime performance of
1036     * any user id that can impact battery performance.
1037     */
1038    final BatteryStatsService mBatteryStatsService;
1039
1040    /**
1041     * Information about component usage
1042     */
1043    UsageStatsManagerInternal mUsageStatsService;
1044
1045    /**
1046     * Access to DeviceIdleController service.
1047     */
1048    DeviceIdleController.LocalService mLocalDeviceIdleController;
1049
1050    /**
1051     * Information about and control over application operations
1052     */
1053    final AppOpsService mAppOpsService;
1054
1055    /**
1056     * Save recent tasks information across reboots.
1057     */
1058    final TaskPersister mTaskPersister;
1059
1060    /**
1061     * Current configuration information.  HistoryRecord objects are given
1062     * a reference to this object to indicate which configuration they are
1063     * currently running in, so this object must be kept immutable.
1064     */
1065    Configuration mConfiguration = new Configuration();
1066
1067    /**
1068     * Current sequencing integer of the configuration, for skipping old
1069     * configurations.
1070     */
1071    int mConfigurationSeq = 0;
1072
1073    boolean mSuppressResizeConfigChanges = false;
1074
1075    /**
1076     * Hardware-reported OpenGLES version.
1077     */
1078    final int GL_ES_VERSION;
1079
1080    /**
1081     * List of initialization arguments to pass to all processes when binding applications to them.
1082     * For example, references to the commonly used services.
1083     */
1084    HashMap<String, IBinder> mAppBindArgs;
1085
1086    /**
1087     * Temporary to avoid allocations.  Protected by main lock.
1088     */
1089    final StringBuilder mStringBuilder = new StringBuilder(256);
1090
1091    /**
1092     * Used to control how we initialize the service.
1093     */
1094    ComponentName mTopComponent;
1095    String mTopAction = Intent.ACTION_MAIN;
1096    String mTopData;
1097    boolean mProcessesReady = false;
1098    boolean mSystemReady = false;
1099    boolean mBooting = false;
1100    boolean mCallFinishBooting = false;
1101    boolean mBootAnimationComplete = false;
1102    boolean mWaitingUpdate = false;
1103    boolean mDidUpdate = false;
1104    boolean mOnBattery = false;
1105    boolean mLaunchWarningShown = false;
1106
1107    Context mContext;
1108
1109    int mFactoryTest;
1110
1111    boolean mCheckedForSetup;
1112
1113    /**
1114     * The time at which we will allow normal application switches again,
1115     * after a call to {@link #stopAppSwitches()}.
1116     */
1117    long mAppSwitchesAllowedTime;
1118
1119    /**
1120     * This is set to true after the first switch after mAppSwitchesAllowedTime
1121     * is set; any switches after that will clear the time.
1122     */
1123    boolean mDidAppSwitch;
1124
1125    /**
1126     * Last time (in realtime) at which we checked for power usage.
1127     */
1128    long mLastPowerCheckRealtime;
1129
1130    /**
1131     * Last time (in uptime) at which we checked for power usage.
1132     */
1133    long mLastPowerCheckUptime;
1134
1135    /**
1136     * Set while we are wanting to sleep, to prevent any
1137     * activities from being started/resumed.
1138     */
1139    private boolean mSleeping = false;
1140
1141    /**
1142     * The process state used for processes that are running the top activities.
1143     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1144     */
1145    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1146
1147    /**
1148     * Set while we are running a voice interaction.  This overrides
1149     * sleeping while it is active.
1150     */
1151    private IVoiceInteractionSession mRunningVoice;
1152
1153    /**
1154     * For some direct access we need to power manager.
1155     */
1156    PowerManagerInternal mLocalPowerManager;
1157
1158    /**
1159     * We want to hold a wake lock while running a voice interaction session, since
1160     * this may happen with the screen off and we need to keep the CPU running to
1161     * be able to continue to interact with the user.
1162     */
1163    PowerManager.WakeLock mVoiceWakeLock;
1164
1165    /**
1166     * State of external calls telling us if the device is awake or asleep.
1167     */
1168    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1169
1170    /**
1171     * A list of tokens that cause the top activity to be put to sleep.
1172     * They are used by components that may hide and block interaction with underlying
1173     * activities.
1174     */
1175    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1176
1177    static final int LOCK_SCREEN_HIDDEN = 0;
1178    static final int LOCK_SCREEN_LEAVING = 1;
1179    static final int LOCK_SCREEN_SHOWN = 2;
1180    /**
1181     * State of external call telling us if the lock screen is shown.
1182     */
1183    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1184
1185    /**
1186     * Set if we are shutting down the system, similar to sleeping.
1187     */
1188    boolean mShuttingDown = false;
1189
1190    /**
1191     * Current sequence id for oom_adj computation traversal.
1192     */
1193    int mAdjSeq = 0;
1194
1195    /**
1196     * Current sequence id for process LRU updating.
1197     */
1198    int mLruSeq = 0;
1199
1200    /**
1201     * Keep track of the non-cached/empty process we last found, to help
1202     * determine how to distribute cached/empty processes next time.
1203     */
1204    int mNumNonCachedProcs = 0;
1205
1206    /**
1207     * Keep track of the number of cached hidden procs, to balance oom adj
1208     * distribution between those and empty procs.
1209     */
1210    int mNumCachedHiddenProcs = 0;
1211
1212    /**
1213     * Keep track of the number of service processes we last found, to
1214     * determine on the next iteration which should be B services.
1215     */
1216    int mNumServiceProcs = 0;
1217    int mNewNumAServiceProcs = 0;
1218    int mNewNumServiceProcs = 0;
1219
1220    /**
1221     * Allow the current computed overall memory level of the system to go down?
1222     * This is set to false when we are killing processes for reasons other than
1223     * memory management, so that the now smaller process list will not be taken as
1224     * an indication that memory is tighter.
1225     */
1226    boolean mAllowLowerMemLevel = false;
1227
1228    /**
1229     * The last computed memory level, for holding when we are in a state that
1230     * processes are going away for other reasons.
1231     */
1232    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1233
1234    /**
1235     * The last total number of process we have, to determine if changes actually look
1236     * like a shrinking number of process due to lower RAM.
1237     */
1238    int mLastNumProcesses;
1239
1240    /**
1241     * The uptime of the last time we performed idle maintenance.
1242     */
1243    long mLastIdleTime = SystemClock.uptimeMillis();
1244
1245    /**
1246     * Total time spent with RAM that has been added in the past since the last idle time.
1247     */
1248    long mLowRamTimeSinceLastIdle = 0;
1249
1250    /**
1251     * If RAM is currently low, when that horrible situation started.
1252     */
1253    long mLowRamStartTime = 0;
1254
1255    /**
1256     * For reporting to battery stats the current top application.
1257     */
1258    private String mCurResumedPackage = null;
1259    private int mCurResumedUid = -1;
1260
1261    /**
1262     * For reporting to battery stats the apps currently running foreground
1263     * service.  The ProcessMap is package/uid tuples; each of these contain
1264     * an array of the currently foreground processes.
1265     */
1266    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1267            = new ProcessMap<ArrayList<ProcessRecord>>();
1268
1269    /**
1270     * This is set if we had to do a delayed dexopt of an app before launching
1271     * it, to increase the ANR timeouts in that case.
1272     */
1273    boolean mDidDexOpt;
1274
1275    /**
1276     * Set if the systemServer made a call to enterSafeMode.
1277     */
1278    boolean mSafeMode;
1279
1280    /**
1281     * If true, we are running under a test environment so will sample PSS from processes
1282     * much more rapidly to try to collect better data when the tests are rapidly
1283     * running through apps.
1284     */
1285    boolean mTestPssMode = false;
1286
1287    String mDebugApp = null;
1288    boolean mWaitForDebugger = false;
1289    boolean mDebugTransient = false;
1290    String mOrigDebugApp = null;
1291    boolean mOrigWaitForDebugger = false;
1292    boolean mAlwaysFinishActivities = false;
1293    boolean mForceResizableActivities;
1294    boolean mSupportsFreeformWindowManagement;
1295    boolean mSupportsPictureInPicture;
1296    Rect mDefaultPinnedStackBounds;
1297    IActivityController mController = null;
1298    String mProfileApp = null;
1299    ProcessRecord mProfileProc = null;
1300    String mProfileFile;
1301    ParcelFileDescriptor mProfileFd;
1302    int mSamplingInterval = 0;
1303    boolean mAutoStopProfiler = false;
1304    int mProfileType = 0;
1305    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1306    String mMemWatchDumpProcName;
1307    String mMemWatchDumpFile;
1308    int mMemWatchDumpPid;
1309    int mMemWatchDumpUid;
1310    String mTrackAllocationApp = null;
1311
1312    final long[] mTmpLong = new long[2];
1313
1314    static final class ProcessChangeItem {
1315        static final int CHANGE_ACTIVITIES = 1<<0;
1316        static final int CHANGE_PROCESS_STATE = 1<<1;
1317        int changes;
1318        int uid;
1319        int pid;
1320        int processState;
1321        boolean foregroundActivities;
1322    }
1323
1324    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1325    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1326
1327    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1328    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1329
1330    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1331    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1332
1333    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1334    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1335
1336    ArraySet<String> mAppsNotReportingCrashes;
1337
1338    /**
1339     * Runtime CPU use collection thread.  This object's lock is used to
1340     * perform synchronization with the thread (notifying it to run).
1341     */
1342    final Thread mProcessCpuThread;
1343
1344    /**
1345     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1346     * Must acquire this object's lock when accessing it.
1347     * NOTE: this lock will be held while doing long operations (trawling
1348     * through all processes in /proc), so it should never be acquired by
1349     * any critical paths such as when holding the main activity manager lock.
1350     */
1351    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1352            MONITOR_THREAD_CPU_USAGE);
1353    final AtomicLong mLastCpuTime = new AtomicLong(0);
1354    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1355
1356    long mLastWriteTime = 0;
1357
1358    /**
1359     * Used to retain an update lock when the foreground activity is in
1360     * immersive mode.
1361     */
1362    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1363
1364    /**
1365     * Set to true after the system has finished booting.
1366     */
1367    boolean mBooted = false;
1368
1369    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1370    int mProcessLimitOverride = -1;
1371
1372    WindowManagerService mWindowManager;
1373
1374    final ActivityThread mSystemThread;
1375
1376    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1377        final ProcessRecord mApp;
1378        final int mPid;
1379        final IApplicationThread mAppThread;
1380
1381        AppDeathRecipient(ProcessRecord app, int pid,
1382                IApplicationThread thread) {
1383            if (DEBUG_ALL) Slog.v(
1384                TAG, "New death recipient " + this
1385                + " for thread " + thread.asBinder());
1386            mApp = app;
1387            mPid = pid;
1388            mAppThread = thread;
1389        }
1390
1391        @Override
1392        public void binderDied() {
1393            if (DEBUG_ALL) Slog.v(
1394                TAG, "Death received in " + this
1395                + " for thread " + mAppThread.asBinder());
1396            synchronized(ActivityManagerService.this) {
1397                appDiedLocked(mApp, mPid, mAppThread, true);
1398            }
1399        }
1400    }
1401
1402    static final int SHOW_ERROR_UI_MSG = 1;
1403    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1404    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1405    static final int UPDATE_CONFIGURATION_MSG = 4;
1406    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1407    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1408    static final int SERVICE_TIMEOUT_MSG = 12;
1409    static final int UPDATE_TIME_ZONE = 13;
1410    static final int SHOW_UID_ERROR_UI_MSG = 14;
1411    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1412    static final int PROC_START_TIMEOUT_MSG = 20;
1413    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1414    static final int KILL_APPLICATION_MSG = 22;
1415    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1416    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1417    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1418    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1419    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1420    static final int CLEAR_DNS_CACHE_MSG = 28;
1421    static final int UPDATE_HTTP_PROXY_MSG = 29;
1422    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1423    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1424    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1425    static final int REPORT_MEM_USAGE_MSG = 33;
1426    static final int REPORT_USER_SWITCH_MSG = 34;
1427    static final int CONTINUE_USER_SWITCH_MSG = 35;
1428    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1429    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1430    static final int PERSIST_URI_GRANTS_MSG = 38;
1431    static final int REQUEST_ALL_PSS_MSG = 39;
1432    static final int START_PROFILES_MSG = 40;
1433    static final int UPDATE_TIME = 41;
1434    static final int SYSTEM_USER_START_MSG = 42;
1435    static final int SYSTEM_USER_CURRENT_MSG = 43;
1436    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1437    static final int FINISH_BOOTING_MSG = 45;
1438    static final int START_USER_SWITCH_UI_MSG = 46;
1439    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1440    static final int DISMISS_DIALOG_UI_MSG = 48;
1441    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1442    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1443    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1444    static final int DELETE_DUMPHEAP_MSG = 52;
1445    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1446    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1447    static final int REPORT_TIME_TRACKER_MSG = 55;
1448    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1449    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1450    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1451    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1452    static final int IDLE_UIDS_MSG = 60;
1453    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1454    static final int LOG_STACK_STATE = 62;
1455    static final int VR_MODE_CHANGE_MSG = 63;
1456    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1457
1458    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1459    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1460    static final int FIRST_COMPAT_MODE_MSG = 300;
1461    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1462
1463    CompatModeDialog mCompatModeDialog;
1464    long mLastMemUsageReportTime = 0;
1465
1466    /**
1467     * Flag whether the current user is a "monkey", i.e. whether
1468     * the UI is driven by a UI automation tool.
1469     */
1470    private boolean mUserIsMonkey;
1471
1472    /** Flag whether the device has a Recents UI */
1473    boolean mHasRecents;
1474
1475    /** The dimensions of the thumbnails in the Recents UI. */
1476    int mThumbnailWidth;
1477    int mThumbnailHeight;
1478
1479    final ServiceThread mHandlerThread;
1480    final MainHandler mHandler;
1481    final UiHandler mUiHandler;
1482
1483    PackageManagerInternal mPackageManagerInt;
1484
1485    final class UiHandler extends Handler {
1486        public UiHandler() {
1487            super(com.android.server.UiThread.get().getLooper(), null, true);
1488        }
1489
1490        @Override
1491        public void handleMessage(Message msg) {
1492            switch (msg.what) {
1493            case SHOW_ERROR_UI_MSG: {
1494                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1495                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1496                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1497                synchronized (ActivityManagerService.this) {
1498                    ProcessRecord proc = (ProcessRecord)data.get("app");
1499                    AppErrorResult res = (AppErrorResult) data.get("result");
1500                    if (proc != null && proc.crashDialog != null) {
1501                        Slog.e(TAG, "App already has crash dialog: " + proc);
1502                        if (res != null) {
1503                            res.set(0);
1504                        }
1505                        return;
1506                    }
1507                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1508                            >= Process.FIRST_APPLICATION_UID
1509                            && proc.pid != MY_PID);
1510                    for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1511                        isBackground &= (proc.userId != userId);
1512                    }
1513                    if (isBackground && !showBackground) {
1514                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1515                        if (res != null) {
1516                            res.set(0);
1517                        }
1518                        return;
1519                    }
1520                    final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1521                            mAppsNotReportingCrashes.contains(proc.info.packageName);
1522                    if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1523                        Dialog d = new AppErrorDialog(mContext,
1524                                ActivityManagerService.this, res, proc);
1525                        d.show();
1526                        proc.crashDialog = d;
1527                    } else {
1528                        // The device is asleep, so just pretend that the user
1529                        // saw a crash dialog and hit "force quit".
1530                        if (res != null) {
1531                            res.set(0);
1532                        }
1533                    }
1534                }
1535
1536                ensureBootCompleted();
1537            } break;
1538            case SHOW_NOT_RESPONDING_UI_MSG: {
1539                synchronized (ActivityManagerService.this) {
1540                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1541                    ProcessRecord proc = (ProcessRecord)data.get("app");
1542                    if (proc != null && proc.anrDialog != null) {
1543                        Slog.e(TAG, "App already has anr dialog: " + proc);
1544                        return;
1545                    }
1546
1547                    Intent intent = new Intent("android.intent.action.ANR");
1548                    if (!mProcessesReady) {
1549                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1550                                | Intent.FLAG_RECEIVER_FOREGROUND);
1551                    }
1552                    broadcastIntentLocked(null, null, intent,
1553                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1554                            null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1555
1556                    if (mShowDialogs) {
1557                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1558                                mContext, proc, (ActivityRecord)data.get("activity"),
1559                                msg.arg1 != 0);
1560                        d.show();
1561                        proc.anrDialog = d;
1562                    } else {
1563                        // Just kill the app if there is no dialog to be shown.
1564                        killAppAtUsersRequest(proc, null);
1565                    }
1566                }
1567
1568                ensureBootCompleted();
1569            } break;
1570            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1571                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1572                synchronized (ActivityManagerService.this) {
1573                    ProcessRecord proc = (ProcessRecord) data.get("app");
1574                    if (proc == null) {
1575                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1576                        break;
1577                    }
1578                    if (proc.crashDialog != null) {
1579                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1580                        return;
1581                    }
1582                    AppErrorResult res = (AppErrorResult) data.get("result");
1583                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1584                        Dialog d = new StrictModeViolationDialog(mContext,
1585                                ActivityManagerService.this, res, proc);
1586                        d.show();
1587                        proc.crashDialog = d;
1588                    } else {
1589                        // The device is asleep, so just pretend that the user
1590                        // saw a crash dialog and hit "force quit".
1591                        res.set(0);
1592                    }
1593                }
1594                ensureBootCompleted();
1595            } break;
1596            case SHOW_FACTORY_ERROR_UI_MSG: {
1597                Dialog d = new FactoryErrorDialog(
1598                    mContext, msg.getData().getCharSequence("msg"));
1599                d.show();
1600                ensureBootCompleted();
1601            } break;
1602            case WAIT_FOR_DEBUGGER_UI_MSG: {
1603                synchronized (ActivityManagerService.this) {
1604                    ProcessRecord app = (ProcessRecord)msg.obj;
1605                    if (msg.arg1 != 0) {
1606                        if (!app.waitedForDebugger) {
1607                            Dialog d = new AppWaitingForDebuggerDialog(
1608                                    ActivityManagerService.this,
1609                                    mContext, app);
1610                            app.waitDialog = d;
1611                            app.waitedForDebugger = true;
1612                            d.show();
1613                        }
1614                    } else {
1615                        if (app.waitDialog != null) {
1616                            app.waitDialog.dismiss();
1617                            app.waitDialog = null;
1618                        }
1619                    }
1620                }
1621            } break;
1622            case SHOW_UID_ERROR_UI_MSG: {
1623                if (mShowDialogs) {
1624                    AlertDialog d = new BaseErrorDialog(mContext);
1625                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1626                    d.setCancelable(false);
1627                    d.setTitle(mContext.getText(R.string.android_system_label));
1628                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1629                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1630                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1631                    d.show();
1632                }
1633            } break;
1634            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1635                if (mShowDialogs) {
1636                    AlertDialog d = new BaseErrorDialog(mContext);
1637                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1638                    d.setCancelable(false);
1639                    d.setTitle(mContext.getText(R.string.android_system_label));
1640                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1641                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1642                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1643                    d.show();
1644                }
1645            } break;
1646            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1647                synchronized (ActivityManagerService.this) {
1648                    ActivityRecord ar = (ActivityRecord) msg.obj;
1649                    if (mCompatModeDialog != null) {
1650                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1651                                ar.info.applicationInfo.packageName)) {
1652                            return;
1653                        }
1654                        mCompatModeDialog.dismiss();
1655                        mCompatModeDialog = null;
1656                    }
1657                    if (ar != null && false) {
1658                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1659                                ar.packageName)) {
1660                            int mode = mCompatModePackages.computeCompatModeLocked(
1661                                    ar.info.applicationInfo);
1662                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1663                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1664                                mCompatModeDialog = new CompatModeDialog(
1665                                        ActivityManagerService.this, mContext,
1666                                        ar.info.applicationInfo);
1667                                mCompatModeDialog.show();
1668                            }
1669                        }
1670                    }
1671                }
1672                break;
1673            }
1674            case START_USER_SWITCH_UI_MSG: {
1675                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1676                break;
1677            }
1678            case DISMISS_DIALOG_UI_MSG: {
1679                final Dialog d = (Dialog) msg.obj;
1680                d.dismiss();
1681                break;
1682            }
1683            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1684                dispatchProcessesChanged();
1685                break;
1686            }
1687            case DISPATCH_PROCESS_DIED_UI_MSG: {
1688                final int pid = msg.arg1;
1689                final int uid = msg.arg2;
1690                dispatchProcessDied(pid, uid);
1691                break;
1692            }
1693            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1694                dispatchUidsChanged();
1695            } break;
1696            }
1697        }
1698    }
1699
1700    final class MainHandler extends Handler {
1701        public MainHandler(Looper looper) {
1702            super(looper, null, true);
1703        }
1704
1705        @Override
1706        public void handleMessage(Message msg) {
1707            switch (msg.what) {
1708            case UPDATE_CONFIGURATION_MSG: {
1709                final ContentResolver resolver = mContext.getContentResolver();
1710                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1711                        msg.arg1);
1712            } break;
1713            case GC_BACKGROUND_PROCESSES_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    performAppGcsIfAppropriateLocked();
1716                }
1717            } break;
1718            case SERVICE_TIMEOUT_MSG: {
1719                if (mDidDexOpt) {
1720                    mDidDexOpt = false;
1721                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1722                    nmsg.obj = msg.obj;
1723                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1724                    return;
1725                }
1726                mServices.serviceTimeout((ProcessRecord)msg.obj);
1727            } break;
1728            case UPDATE_TIME_ZONE: {
1729                synchronized (ActivityManagerService.this) {
1730                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1731                        ProcessRecord r = mLruProcesses.get(i);
1732                        if (r.thread != null) {
1733                            try {
1734                                r.thread.updateTimeZone();
1735                            } catch (RemoteException ex) {
1736                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1737                            }
1738                        }
1739                    }
1740                }
1741            } break;
1742            case CLEAR_DNS_CACHE_MSG: {
1743                synchronized (ActivityManagerService.this) {
1744                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1745                        ProcessRecord r = mLruProcesses.get(i);
1746                        if (r.thread != null) {
1747                            try {
1748                                r.thread.clearDnsCache();
1749                            } catch (RemoteException ex) {
1750                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1751                            }
1752                        }
1753                    }
1754                }
1755            } break;
1756            case UPDATE_HTTP_PROXY_MSG: {
1757                ProxyInfo proxy = (ProxyInfo)msg.obj;
1758                String host = "";
1759                String port = "";
1760                String exclList = "";
1761                Uri pacFileUrl = Uri.EMPTY;
1762                if (proxy != null) {
1763                    host = proxy.getHost();
1764                    port = Integer.toString(proxy.getPort());
1765                    exclList = proxy.getExclusionListAsString();
1766                    pacFileUrl = proxy.getPacFileUrl();
1767                }
1768                synchronized (ActivityManagerService.this) {
1769                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1770                        ProcessRecord r = mLruProcesses.get(i);
1771                        if (r.thread != null) {
1772                            try {
1773                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1774                            } catch (RemoteException ex) {
1775                                Slog.w(TAG, "Failed to update http proxy for: " +
1776                                        r.info.processName);
1777                            }
1778                        }
1779                    }
1780                }
1781            } break;
1782            case PROC_START_TIMEOUT_MSG: {
1783                if (mDidDexOpt) {
1784                    mDidDexOpt = false;
1785                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1786                    nmsg.obj = msg.obj;
1787                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1788                    return;
1789                }
1790                ProcessRecord app = (ProcessRecord)msg.obj;
1791                synchronized (ActivityManagerService.this) {
1792                    processStartTimedOutLocked(app);
1793                }
1794            } break;
1795            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1796                ProcessRecord app = (ProcessRecord)msg.obj;
1797                synchronized (ActivityManagerService.this) {
1798                    processContentProviderPublishTimedOutLocked(app);
1799                }
1800            } break;
1801            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1802                synchronized (ActivityManagerService.this) {
1803                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1804                }
1805            } break;
1806            case KILL_APPLICATION_MSG: {
1807                synchronized (ActivityManagerService.this) {
1808                    int appid = msg.arg1;
1809                    boolean restart = (msg.arg2 == 1);
1810                    Bundle bundle = (Bundle)msg.obj;
1811                    String pkg = bundle.getString("pkg");
1812                    String reason = bundle.getString("reason");
1813                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1814                            false, UserHandle.USER_ALL, reason);
1815                }
1816            } break;
1817            case FINALIZE_PENDING_INTENT_MSG: {
1818                ((PendingIntentRecord)msg.obj).completeFinalize();
1819            } break;
1820            case POST_HEAVY_NOTIFICATION_MSG: {
1821                INotificationManager inm = NotificationManager.getService();
1822                if (inm == null) {
1823                    return;
1824                }
1825
1826                ActivityRecord root = (ActivityRecord)msg.obj;
1827                ProcessRecord process = root.app;
1828                if (process == null) {
1829                    return;
1830                }
1831
1832                try {
1833                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1834                    String text = mContext.getString(R.string.heavy_weight_notification,
1835                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1836                    Notification notification = new Notification.Builder(context)
1837                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1838                            .setWhen(0)
1839                            .setOngoing(true)
1840                            .setTicker(text)
1841                            .setColor(mContext.getColor(
1842                                    com.android.internal.R.color.system_notification_accent_color))
1843                            .setContentTitle(text)
1844                            .setContentText(
1845                                    mContext.getText(R.string.heavy_weight_notification_detail))
1846                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1847                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1848                                    new UserHandle(root.userId)))
1849                            .build();
1850                    try {
1851                        int[] outId = new int[1];
1852                        inm.enqueueNotificationWithTag("android", "android", null,
1853                                R.string.heavy_weight_notification,
1854                                notification, outId, root.userId);
1855                    } catch (RuntimeException e) {
1856                        Slog.w(ActivityManagerService.TAG,
1857                                "Error showing notification for heavy-weight app", e);
1858                    } catch (RemoteException e) {
1859                    }
1860                } catch (NameNotFoundException e) {
1861                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1862                }
1863            } break;
1864            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1865                INotificationManager inm = NotificationManager.getService();
1866                if (inm == null) {
1867                    return;
1868                }
1869                try {
1870                    inm.cancelNotificationWithTag("android", null,
1871                            R.string.heavy_weight_notification,  msg.arg1);
1872                } catch (RuntimeException e) {
1873                    Slog.w(ActivityManagerService.TAG,
1874                            "Error canceling notification for service", e);
1875                } catch (RemoteException e) {
1876                }
1877            } break;
1878            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1879                synchronized (ActivityManagerService.this) {
1880                    checkExcessivePowerUsageLocked(true);
1881                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1882                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1883                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1884                }
1885            } break;
1886            case REPORT_MEM_USAGE_MSG: {
1887                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1888                Thread thread = new Thread() {
1889                    @Override public void run() {
1890                        reportMemUsage(memInfos);
1891                    }
1892                };
1893                thread.start();
1894                break;
1895            }
1896            case REPORT_USER_SWITCH_MSG: {
1897                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1898                break;
1899            }
1900            case CONTINUE_USER_SWITCH_MSG: {
1901                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1902                break;
1903            }
1904            case USER_SWITCH_TIMEOUT_MSG: {
1905                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1906                break;
1907            }
1908            case IMMERSIVE_MODE_LOCK_MSG: {
1909                final boolean nextState = (msg.arg1 != 0);
1910                if (mUpdateLock.isHeld() != nextState) {
1911                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1912                            "Applying new update lock state '" + nextState
1913                            + "' for " + (ActivityRecord)msg.obj);
1914                    if (nextState) {
1915                        mUpdateLock.acquire();
1916                    } else {
1917                        mUpdateLock.release();
1918                    }
1919                }
1920                break;
1921            }
1922            case PERSIST_URI_GRANTS_MSG: {
1923                writeGrantedUriPermissions();
1924                break;
1925            }
1926            case REQUEST_ALL_PSS_MSG: {
1927                synchronized (ActivityManagerService.this) {
1928                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1929                }
1930                break;
1931            }
1932            case START_PROFILES_MSG: {
1933                synchronized (ActivityManagerService.this) {
1934                    mUserController.startProfilesLocked();
1935                }
1936                break;
1937            }
1938            case UPDATE_TIME: {
1939                synchronized (ActivityManagerService.this) {
1940                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1941                        ProcessRecord r = mLruProcesses.get(i);
1942                        if (r.thread != null) {
1943                            try {
1944                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1945                            } catch (RemoteException ex) {
1946                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1947                            }
1948                        }
1949                    }
1950                }
1951                break;
1952            }
1953            case SYSTEM_USER_START_MSG: {
1954                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1955                        Integer.toString(msg.arg1), msg.arg1);
1956                mSystemServiceManager.startUser(msg.arg1);
1957                break;
1958            }
1959            case SYSTEM_USER_UNLOCK_MSG: {
1960                final int userId = msg.arg1;
1961                mSystemServiceManager.unlockUser(userId);
1962                mRecentTasks.cleanupLocked(userId);
1963                installEncryptionUnawareProviders(userId);
1964                break;
1965            }
1966            case SYSTEM_USER_CURRENT_MSG: {
1967                mBatteryStatsService.noteEvent(
1968                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1969                        Integer.toString(msg.arg2), msg.arg2);
1970                mBatteryStatsService.noteEvent(
1971                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1972                        Integer.toString(msg.arg1), msg.arg1);
1973                mSystemServiceManager.switchUser(msg.arg1);
1974                break;
1975            }
1976            case ENTER_ANIMATION_COMPLETE_MSG: {
1977                synchronized (ActivityManagerService.this) {
1978                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1979                    if (r != null && r.app != null && r.app.thread != null) {
1980                        try {
1981                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1982                        } catch (RemoteException e) {
1983                        }
1984                    }
1985                }
1986                break;
1987            }
1988            case FINISH_BOOTING_MSG: {
1989                if (msg.arg1 != 0) {
1990                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1991                    finishBooting();
1992                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1993                }
1994                if (msg.arg2 != 0) {
1995                    enableScreenAfterBoot();
1996                }
1997                break;
1998            }
1999            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2000                try {
2001                    Locale l = (Locale) msg.obj;
2002                    IBinder service = ServiceManager.getService("mount");
2003                    IMountService mountService = IMountService.Stub.asInterface(service);
2004                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2005                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2006                } catch (RemoteException e) {
2007                    Log.e(TAG, "Error storing locale for decryption UI", e);
2008                }
2009                break;
2010            }
2011            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2012                synchronized (ActivityManagerService.this) {
2013                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2014                        try {
2015                            // Make a one-way callback to the listener
2016                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2017                        } catch (RemoteException e){
2018                            // Handled by the RemoteCallbackList
2019                        }
2020                    }
2021                    mTaskStackListeners.finishBroadcast();
2022                }
2023                break;
2024            }
2025            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2026                synchronized (ActivityManagerService.this) {
2027                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2028                        try {
2029                            // Make a one-way callback to the listener
2030                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2031                        } catch (RemoteException e){
2032                            // Handled by the RemoteCallbackList
2033                        }
2034                    }
2035                    mTaskStackListeners.finishBroadcast();
2036                }
2037                break;
2038            }
2039            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2040                final int uid = msg.arg1;
2041                final byte[] firstPacket = (byte[]) msg.obj;
2042
2043                synchronized (mPidsSelfLocked) {
2044                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2045                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2046                        if (p.uid == uid) {
2047                            try {
2048                                p.thread.notifyCleartextNetwork(firstPacket);
2049                            } catch (RemoteException ignored) {
2050                            }
2051                        }
2052                    }
2053                }
2054                break;
2055            }
2056            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2057                final String procName;
2058                final int uid;
2059                final long memLimit;
2060                final String reportPackage;
2061                synchronized (ActivityManagerService.this) {
2062                    procName = mMemWatchDumpProcName;
2063                    uid = mMemWatchDumpUid;
2064                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2065                    if (val == null) {
2066                        val = mMemWatchProcesses.get(procName, 0);
2067                    }
2068                    if (val != null) {
2069                        memLimit = val.first;
2070                        reportPackage = val.second;
2071                    } else {
2072                        memLimit = 0;
2073                        reportPackage = null;
2074                    }
2075                }
2076                if (procName == null) {
2077                    return;
2078                }
2079
2080                if (DEBUG_PSS) Slog.d(TAG_PSS,
2081                        "Showing dump heap notification from " + procName + "/" + uid);
2082
2083                INotificationManager inm = NotificationManager.getService();
2084                if (inm == null) {
2085                    return;
2086                }
2087
2088                String text = mContext.getString(R.string.dump_heap_notification, procName);
2089
2090
2091                Intent deleteIntent = new Intent();
2092                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2093                Intent intent = new Intent();
2094                intent.setClassName("android", DumpHeapActivity.class.getName());
2095                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2096                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2097                if (reportPackage != null) {
2098                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2099                }
2100                int userId = UserHandle.getUserId(uid);
2101                Notification notification = new Notification.Builder(mContext)
2102                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2103                        .setWhen(0)
2104                        .setOngoing(true)
2105                        .setAutoCancel(true)
2106                        .setTicker(text)
2107                        .setColor(mContext.getColor(
2108                                com.android.internal.R.color.system_notification_accent_color))
2109                        .setContentTitle(text)
2110                        .setContentText(
2111                                mContext.getText(R.string.dump_heap_notification_detail))
2112                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2113                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2114                                new UserHandle(userId)))
2115                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2116                                deleteIntent, 0, UserHandle.SYSTEM))
2117                        .build();
2118
2119                try {
2120                    int[] outId = new int[1];
2121                    inm.enqueueNotificationWithTag("android", "android", null,
2122                            R.string.dump_heap_notification,
2123                            notification, outId, userId);
2124                } catch (RuntimeException e) {
2125                    Slog.w(ActivityManagerService.TAG,
2126                            "Error showing notification for dump heap", e);
2127                } catch (RemoteException e) {
2128                }
2129            } break;
2130            case DELETE_DUMPHEAP_MSG: {
2131                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2132                        DumpHeapActivity.JAVA_URI,
2133                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2134                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2135                        UserHandle.myUserId());
2136                synchronized (ActivityManagerService.this) {
2137                    mMemWatchDumpFile = null;
2138                    mMemWatchDumpProcName = null;
2139                    mMemWatchDumpPid = -1;
2140                    mMemWatchDumpUid = -1;
2141                }
2142            } break;
2143            case FOREGROUND_PROFILE_CHANGED_MSG: {
2144                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2145            } break;
2146            case REPORT_TIME_TRACKER_MSG: {
2147                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2148                tracker.deliverResult(mContext);
2149            } break;
2150            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2151                mUserController.dispatchUserSwitchComplete(msg.arg1);
2152            } break;
2153            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2154                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2155                try {
2156                    connection.shutdown();
2157                } catch (RemoteException e) {
2158                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2159                }
2160                // Only a UiAutomation can set this flag and now that
2161                // it is finished we make sure it is reset to its default.
2162                mUserIsMonkey = false;
2163            } break;
2164            case APP_BOOST_DEACTIVATE_MSG: {
2165                synchronized(ActivityManagerService.this) {
2166                    if (mIsBoosted) {
2167                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2168                            nativeMigrateFromBoost();
2169                            mIsBoosted = false;
2170                            mBoostStartTime = 0;
2171                        } else {
2172                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2173                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2174                        }
2175                    }
2176                }
2177            } break;
2178            case IDLE_UIDS_MSG: {
2179                idleUids();
2180            } break;
2181            case LOG_STACK_STATE: {
2182                synchronized (ActivityManagerService.this) {
2183                    mStackSupervisor.logStackState();
2184                }
2185            } break;
2186            case VR_MODE_CHANGE_MSG: {
2187                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2188                vrService.setVrMode(msg.arg1 != 0);
2189            } break;
2190            }
2191        }
2192    };
2193
2194    static final int COLLECT_PSS_BG_MSG = 1;
2195
2196    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2197        @Override
2198        public void handleMessage(Message msg) {
2199            switch (msg.what) {
2200            case COLLECT_PSS_BG_MSG: {
2201                long start = SystemClock.uptimeMillis();
2202                MemInfoReader memInfo = null;
2203                synchronized (ActivityManagerService.this) {
2204                    if (mFullPssPending) {
2205                        mFullPssPending = false;
2206                        memInfo = new MemInfoReader();
2207                    }
2208                }
2209                if (memInfo != null) {
2210                    updateCpuStatsNow();
2211                    long nativeTotalPss = 0;
2212                    synchronized (mProcessCpuTracker) {
2213                        final int N = mProcessCpuTracker.countStats();
2214                        for (int j=0; j<N; j++) {
2215                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2216                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2217                                // This is definitely an application process; skip it.
2218                                continue;
2219                            }
2220                            synchronized (mPidsSelfLocked) {
2221                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2222                                    // This is one of our own processes; skip it.
2223                                    continue;
2224                                }
2225                            }
2226                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2227                        }
2228                    }
2229                    memInfo.readMemInfo();
2230                    synchronized (ActivityManagerService.this) {
2231                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2232                                + (SystemClock.uptimeMillis()-start) + "ms");
2233                        final long cachedKb = memInfo.getCachedSizeKb();
2234                        final long freeKb = memInfo.getFreeSizeKb();
2235                        final long zramKb = memInfo.getZramTotalSizeKb();
2236                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2237                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2238                                kernelKb*1024, nativeTotalPss*1024);
2239                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2240                                nativeTotalPss);
2241                    }
2242                }
2243
2244                int num = 0;
2245                long[] tmp = new long[2];
2246                do {
2247                    ProcessRecord proc;
2248                    int procState;
2249                    int pid;
2250                    long lastPssTime;
2251                    synchronized (ActivityManagerService.this) {
2252                        if (mPendingPssProcesses.size() <= 0) {
2253                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2254                                    "Collected PSS of " + num + " processes in "
2255                                    + (SystemClock.uptimeMillis() - start) + "ms");
2256                            mPendingPssProcesses.clear();
2257                            return;
2258                        }
2259                        proc = mPendingPssProcesses.remove(0);
2260                        procState = proc.pssProcState;
2261                        lastPssTime = proc.lastPssTime;
2262                        if (proc.thread != null && procState == proc.setProcState
2263                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2264                                        < SystemClock.uptimeMillis()) {
2265                            pid = proc.pid;
2266                        } else {
2267                            proc = null;
2268                            pid = 0;
2269                        }
2270                    }
2271                    if (proc != null) {
2272                        long pss = Debug.getPss(pid, tmp, null);
2273                        synchronized (ActivityManagerService.this) {
2274                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2275                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2276                                num++;
2277                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2278                                        SystemClock.uptimeMillis());
2279                            }
2280                        }
2281                    }
2282                } while (true);
2283            }
2284            }
2285        }
2286    };
2287
2288    public void setSystemProcess() {
2289        try {
2290            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2291            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2292            ServiceManager.addService("meminfo", new MemBinder(this));
2293            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2294            ServiceManager.addService("dbinfo", new DbBinder(this));
2295            if (MONITOR_CPU_USAGE) {
2296                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2297            }
2298            ServiceManager.addService("permission", new PermissionController(this));
2299            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2300
2301            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2302                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2303            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2304
2305            synchronized (this) {
2306                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2307                app.persistent = true;
2308                app.pid = MY_PID;
2309                app.maxAdj = ProcessList.SYSTEM_ADJ;
2310                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2311                synchronized (mPidsSelfLocked) {
2312                    mPidsSelfLocked.put(app.pid, app);
2313                }
2314                updateLruProcessLocked(app, false, null);
2315                updateOomAdjLocked();
2316            }
2317        } catch (PackageManager.NameNotFoundException e) {
2318            throw new RuntimeException(
2319                    "Unable to find android system package", e);
2320        }
2321    }
2322
2323    public void setWindowManager(WindowManagerService wm) {
2324        mWindowManager = wm;
2325        mStackSupervisor.setWindowManager(wm);
2326        mActivityStarter.setWindowManager(wm);
2327    }
2328
2329    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2330        mUsageStatsService = usageStatsManager;
2331    }
2332
2333    public void startObservingNativeCrashes() {
2334        final NativeCrashListener ncl = new NativeCrashListener(this);
2335        ncl.start();
2336    }
2337
2338    public IAppOpsService getAppOpsService() {
2339        return mAppOpsService;
2340    }
2341
2342    static class MemBinder extends Binder {
2343        ActivityManagerService mActivityManagerService;
2344        MemBinder(ActivityManagerService activityManagerService) {
2345            mActivityManagerService = activityManagerService;
2346        }
2347
2348        @Override
2349        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2350            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2351                    != PackageManager.PERMISSION_GRANTED) {
2352                pw.println("Permission Denial: can't dump meminfo from from pid="
2353                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2354                        + " without permission " + android.Manifest.permission.DUMP);
2355                return;
2356            }
2357
2358            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2359        }
2360    }
2361
2362    static class GraphicsBinder extends Binder {
2363        ActivityManagerService mActivityManagerService;
2364        GraphicsBinder(ActivityManagerService activityManagerService) {
2365            mActivityManagerService = activityManagerService;
2366        }
2367
2368        @Override
2369        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2370            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2371                    != PackageManager.PERMISSION_GRANTED) {
2372                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2373                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2374                        + " without permission " + android.Manifest.permission.DUMP);
2375                return;
2376            }
2377
2378            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2379        }
2380    }
2381
2382    static class DbBinder extends Binder {
2383        ActivityManagerService mActivityManagerService;
2384        DbBinder(ActivityManagerService activityManagerService) {
2385            mActivityManagerService = activityManagerService;
2386        }
2387
2388        @Override
2389        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2390            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2391                    != PackageManager.PERMISSION_GRANTED) {
2392                pw.println("Permission Denial: can't dump dbinfo from from pid="
2393                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2394                        + " without permission " + android.Manifest.permission.DUMP);
2395                return;
2396            }
2397
2398            mActivityManagerService.dumpDbInfo(fd, pw, args);
2399        }
2400    }
2401
2402    static class CpuBinder extends Binder {
2403        ActivityManagerService mActivityManagerService;
2404        CpuBinder(ActivityManagerService activityManagerService) {
2405            mActivityManagerService = activityManagerService;
2406        }
2407
2408        @Override
2409        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2410            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2411                    != PackageManager.PERMISSION_GRANTED) {
2412                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2413                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2414                        + " without permission " + android.Manifest.permission.DUMP);
2415                return;
2416            }
2417
2418            synchronized (mActivityManagerService.mProcessCpuTracker) {
2419                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2420                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2421                        SystemClock.uptimeMillis()));
2422            }
2423        }
2424    }
2425
2426    public static final class Lifecycle extends SystemService {
2427        private final ActivityManagerService mService;
2428
2429        public Lifecycle(Context context) {
2430            super(context);
2431            mService = new ActivityManagerService(context);
2432        }
2433
2434        @Override
2435        public void onStart() {
2436            mService.start();
2437        }
2438
2439        public ActivityManagerService getService() {
2440            return mService;
2441        }
2442    }
2443
2444    // Note: This method is invoked on the main thread but may need to attach various
2445    // handlers to other threads.  So take care to be explicit about the looper.
2446    public ActivityManagerService(Context systemContext) {
2447        mContext = systemContext;
2448        mFactoryTest = FactoryTest.getMode();
2449        mSystemThread = ActivityThread.currentActivityThread();
2450
2451        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2452
2453        mHandlerThread = new ServiceThread(TAG,
2454                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2455        mHandlerThread.start();
2456        mHandler = new MainHandler(mHandlerThread.getLooper());
2457        mUiHandler = new UiHandler();
2458
2459        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2460                "foreground", BROADCAST_FG_TIMEOUT, false);
2461        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2462                "background", BROADCAST_BG_TIMEOUT, true);
2463        mBroadcastQueues[0] = mFgBroadcastQueue;
2464        mBroadcastQueues[1] = mBgBroadcastQueue;
2465
2466        mServices = new ActiveServices(this);
2467        mProviderMap = new ProviderMap(this);
2468
2469        // TODO: Move creation of battery stats service outside of activity manager service.
2470        File dataDir = Environment.getDataDirectory();
2471        File systemDir = new File(dataDir, "system");
2472        systemDir.mkdirs();
2473        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2474        mBatteryStatsService.getActiveStatistics().readLocked();
2475        mBatteryStatsService.scheduleWriteToDisk();
2476        mOnBattery = DEBUG_POWER ? true
2477                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2478        mBatteryStatsService.getActiveStatistics().setCallback(this);
2479
2480        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2481
2482        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2483        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2484                new IAppOpsCallback.Stub() {
2485                    @Override public void opChanged(int op, int uid, String packageName) {
2486                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2487                            if (mAppOpsService.checkOperation(op, uid, packageName)
2488                                    != AppOpsManager.MODE_ALLOWED) {
2489                                runInBackgroundDisabled(uid);
2490                            }
2491                        }
2492                    }
2493                });
2494
2495        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2496
2497        mUserController = new UserController(this);
2498
2499        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2500            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2501
2502        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2503
2504        mConfiguration.setToDefaults();
2505        mConfiguration.setLocales(LocaleList.getDefault());
2506
2507        mConfigurationSeq = mConfiguration.seq = 1;
2508        mProcessCpuTracker.init();
2509
2510        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2511        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2512        mRecentTasks = new RecentTasks(this);
2513        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2514        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2515        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2516
2517        mProcessCpuThread = new Thread("CpuTracker") {
2518            @Override
2519            public void run() {
2520                while (true) {
2521                    try {
2522                        try {
2523                            synchronized(this) {
2524                                final long now = SystemClock.uptimeMillis();
2525                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2526                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2527                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2528                                //        + ", write delay=" + nextWriteDelay);
2529                                if (nextWriteDelay < nextCpuDelay) {
2530                                    nextCpuDelay = nextWriteDelay;
2531                                }
2532                                if (nextCpuDelay > 0) {
2533                                    mProcessCpuMutexFree.set(true);
2534                                    this.wait(nextCpuDelay);
2535                                }
2536                            }
2537                        } catch (InterruptedException e) {
2538                        }
2539                        updateCpuStatsNow();
2540                    } catch (Exception e) {
2541                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2542                    }
2543                }
2544            }
2545        };
2546
2547        Watchdog.getInstance().addMonitor(this);
2548        Watchdog.getInstance().addThread(mHandler);
2549    }
2550
2551    public void setSystemServiceManager(SystemServiceManager mgr) {
2552        mSystemServiceManager = mgr;
2553    }
2554
2555    public void setInstaller(Installer installer) {
2556        mInstaller = installer;
2557    }
2558
2559    private void start() {
2560        Process.removeAllProcessGroups();
2561        mProcessCpuThread.start();
2562
2563        mBatteryStatsService.publish(mContext);
2564        mAppOpsService.publish(mContext);
2565        Slog.d("AppOps", "AppOpsService published");
2566        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2567    }
2568
2569    public void initPowerManagement() {
2570        mStackSupervisor.initPowerManagement();
2571        mBatteryStatsService.initPowerManagement();
2572        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2573        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2574        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2575        mVoiceWakeLock.setReferenceCounted(false);
2576    }
2577
2578    @Override
2579    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2580            throws RemoteException {
2581        if (code == SYSPROPS_TRANSACTION) {
2582            // We need to tell all apps about the system property change.
2583            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2584            synchronized(this) {
2585                final int NP = mProcessNames.getMap().size();
2586                for (int ip=0; ip<NP; ip++) {
2587                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2588                    final int NA = apps.size();
2589                    for (int ia=0; ia<NA; ia++) {
2590                        ProcessRecord app = apps.valueAt(ia);
2591                        if (app.thread != null) {
2592                            procs.add(app.thread.asBinder());
2593                        }
2594                    }
2595                }
2596            }
2597
2598            int N = procs.size();
2599            for (int i=0; i<N; i++) {
2600                Parcel data2 = Parcel.obtain();
2601                try {
2602                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2603                } catch (RemoteException e) {
2604                }
2605                data2.recycle();
2606            }
2607        }
2608        try {
2609            return super.onTransact(code, data, reply, flags);
2610        } catch (RuntimeException e) {
2611            // The activity manager only throws security exceptions, so let's
2612            // log all others.
2613            if (!(e instanceof SecurityException)) {
2614                Slog.wtf(TAG, "Activity Manager Crash", e);
2615            }
2616            throw e;
2617        }
2618    }
2619
2620    void updateCpuStats() {
2621        final long now = SystemClock.uptimeMillis();
2622        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2623            return;
2624        }
2625        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2626            synchronized (mProcessCpuThread) {
2627                mProcessCpuThread.notify();
2628            }
2629        }
2630    }
2631
2632    void updateCpuStatsNow() {
2633        synchronized (mProcessCpuTracker) {
2634            mProcessCpuMutexFree.set(false);
2635            final long now = SystemClock.uptimeMillis();
2636            boolean haveNewCpuStats = false;
2637
2638            if (MONITOR_CPU_USAGE &&
2639                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2640                mLastCpuTime.set(now);
2641                mProcessCpuTracker.update();
2642                if (mProcessCpuTracker.hasGoodLastStats()) {
2643                    haveNewCpuStats = true;
2644                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2645                    //Slog.i(TAG, "Total CPU usage: "
2646                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2647
2648                    // Slog the cpu usage if the property is set.
2649                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2650                        int user = mProcessCpuTracker.getLastUserTime();
2651                        int system = mProcessCpuTracker.getLastSystemTime();
2652                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2653                        int irq = mProcessCpuTracker.getLastIrqTime();
2654                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2655                        int idle = mProcessCpuTracker.getLastIdleTime();
2656
2657                        int total = user + system + iowait + irq + softIrq + idle;
2658                        if (total == 0) total = 1;
2659
2660                        EventLog.writeEvent(EventLogTags.CPU,
2661                                ((user+system+iowait+irq+softIrq) * 100) / total,
2662                                (user * 100) / total,
2663                                (system * 100) / total,
2664                                (iowait * 100) / total,
2665                                (irq * 100) / total,
2666                                (softIrq * 100) / total);
2667                    }
2668                }
2669            }
2670
2671            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2672            synchronized(bstats) {
2673                synchronized(mPidsSelfLocked) {
2674                    if (haveNewCpuStats) {
2675                        if (bstats.startAddingCpuLocked()) {
2676                            int totalUTime = 0;
2677                            int totalSTime = 0;
2678                            final int N = mProcessCpuTracker.countStats();
2679                            for (int i=0; i<N; i++) {
2680                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2681                                if (!st.working) {
2682                                    continue;
2683                                }
2684                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2685                                totalUTime += st.rel_utime;
2686                                totalSTime += st.rel_stime;
2687                                if (pr != null) {
2688                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2689                                    if (ps == null || !ps.isActive()) {
2690                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2691                                                pr.info.uid, pr.processName);
2692                                    }
2693                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2694                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2695                                } else {
2696                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2697                                    if (ps == null || !ps.isActive()) {
2698                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2699                                                bstats.mapUid(st.uid), st.name);
2700                                    }
2701                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2702                                }
2703                            }
2704                            final int userTime = mProcessCpuTracker.getLastUserTime();
2705                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2706                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2707                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2708                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2709                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2710                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2711                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2712                        }
2713                    }
2714                }
2715
2716                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2717                    mLastWriteTime = now;
2718                    mBatteryStatsService.scheduleWriteToDisk();
2719                }
2720            }
2721        }
2722    }
2723
2724    @Override
2725    public void batteryNeedsCpuUpdate() {
2726        updateCpuStatsNow();
2727    }
2728
2729    @Override
2730    public void batteryPowerChanged(boolean onBattery) {
2731        // When plugging in, update the CPU stats first before changing
2732        // the plug state.
2733        updateCpuStatsNow();
2734        synchronized (this) {
2735            synchronized(mPidsSelfLocked) {
2736                mOnBattery = DEBUG_POWER ? true : onBattery;
2737            }
2738        }
2739    }
2740
2741    @Override
2742    public void batterySendBroadcast(Intent intent) {
2743        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2744                AppOpsManager.OP_NONE, null, false, false,
2745                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2746    }
2747
2748    /**
2749     * Initialize the application bind args. These are passed to each
2750     * process when the bindApplication() IPC is sent to the process. They're
2751     * lazily setup to make sure the services are running when they're asked for.
2752     */
2753    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2754        if (mAppBindArgs == null) {
2755            mAppBindArgs = new HashMap<>();
2756
2757            // Isolated processes won't get this optimization, so that we don't
2758            // violate the rules about which services they have access to.
2759            if (!isolated) {
2760                // Setup the application init args
2761                mAppBindArgs.put("package", ServiceManager.getService("package"));
2762                mAppBindArgs.put("window", ServiceManager.getService("window"));
2763                mAppBindArgs.put(Context.ALARM_SERVICE,
2764                        ServiceManager.getService(Context.ALARM_SERVICE));
2765            }
2766        }
2767        return mAppBindArgs;
2768    }
2769
2770    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2771        if (r == null || mFocusedActivity == r) {
2772            return false;
2773        }
2774
2775        if (!r.isFocusable()) {
2776            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2777            return false;
2778        }
2779
2780        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2781        final ActivityRecord last = mFocusedActivity;
2782        mFocusedActivity = r;
2783        if (r.task.isApplicationTask()) {
2784            if (mCurAppTimeTracker != r.appTimeTracker) {
2785                // We are switching app tracking.  Complete the current one.
2786                if (mCurAppTimeTracker != null) {
2787                    mCurAppTimeTracker.stop();
2788                    mHandler.obtainMessage(
2789                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2790                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2791                    mCurAppTimeTracker = null;
2792                }
2793                if (r.appTimeTracker != null) {
2794                    mCurAppTimeTracker = r.appTimeTracker;
2795                    startTimeTrackingFocusedActivityLocked();
2796                }
2797            } else {
2798                startTimeTrackingFocusedActivityLocked();
2799            }
2800        } else {
2801            r.appTimeTracker = null;
2802        }
2803        if (r.task.voiceInteractor != null) {
2804            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2805        } else {
2806            finishRunningVoiceLocked();
2807            if (last != null && last.task.voiceSession != null) {
2808                // We had been in a voice interaction session, but now focused has
2809                // move to something different.  Just finish the session, we can't
2810                // return to it and retain the proper state and synchronization with
2811                // the voice interaction service.
2812                finishVoiceTask(last.task.voiceSession);
2813            }
2814        }
2815        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2816            mWindowManager.setFocusedApp(r.appToken, true);
2817        }
2818        applyUpdateLockStateLocked(r);
2819        applyUpdateVrModeLocked(r);
2820        if (mFocusedActivity.userId != mLastFocusedUserId) {
2821            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2822            mHandler.obtainMessage(
2823                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2824            mLastFocusedUserId = mFocusedActivity.userId;
2825        }
2826
2827        EventLogTags.writeAmFocusedActivity(
2828                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2829                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2830                reason);
2831        return true;
2832    }
2833
2834    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2835        if (mFocusedActivity != goingAway) {
2836            return;
2837        }
2838
2839        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2840        if (focusedStack != null) {
2841            final ActivityRecord top = focusedStack.topActivity();
2842            if (top != null && top.userId != mLastFocusedUserId) {
2843                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2844                mHandler.sendMessage(
2845                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2846                mLastFocusedUserId = top.userId;
2847            }
2848        }
2849
2850        // Try to move focus to another activity if possible.
2851        if (setFocusedActivityLocked(
2852                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2853            return;
2854        }
2855
2856        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2857                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2858        mFocusedActivity = null;
2859        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2860    }
2861
2862    @Override
2863    public void setFocusedStack(int stackId) {
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2865        synchronized (ActivityManagerService.this) {
2866            ActivityStack stack = mStackSupervisor.getStack(stackId);
2867            if (stack != null) {
2868                ActivityRecord r = stack.topRunningActivityLocked();
2869                if (r != null) {
2870                    setFocusedActivityLocked(r, "setFocusedStack");
2871                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2872                }
2873            }
2874        }
2875    }
2876
2877    @Override
2878    public void setFocusedTask(int taskId) {
2879        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2880        long callingId = Binder.clearCallingIdentity();
2881        try {
2882            synchronized (ActivityManagerService.this) {
2883                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2884                if (task != null) {
2885                    final ActivityRecord r = task.topRunningActivityLocked();
2886                    if (setFocusedActivityLocked(r, "setFocusedTask")) {
2887                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
2888                    }
2889                }
2890            }
2891        } finally {
2892            Binder.restoreCallingIdentity(callingId);
2893        }
2894    }
2895
2896    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2897    @Override
2898    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2899        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2900        synchronized (this) {
2901            if (listener != null) {
2902                mTaskStackListeners.register(listener);
2903            }
2904        }
2905    }
2906
2907    @Override
2908    public void notifyActivityDrawn(IBinder token) {
2909        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2910        synchronized (this) {
2911            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2912            if (r != null) {
2913                r.task.stack.notifyActivityDrawnLocked(r);
2914            }
2915        }
2916    }
2917
2918    final void applyUpdateLockStateLocked(ActivityRecord r) {
2919        // Modifications to the UpdateLock state are done on our handler, outside
2920        // the activity manager's locks.  The new state is determined based on the
2921        // state *now* of the relevant activity record.  The object is passed to
2922        // the handler solely for logging detail, not to be consulted/modified.
2923        final boolean nextState = r != null && r.immersive;
2924        mHandler.sendMessage(
2925                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2926    }
2927
2928    final void applyUpdateVrModeLocked(ActivityRecord r) {
2929        mHandler.sendMessage(
2930                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2931    }
2932
2933    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2934        Message msg = Message.obtain();
2935        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2936        msg.obj = r.task.askedCompatMode ? null : r;
2937        mUiHandler.sendMessage(msg);
2938    }
2939
2940    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2941            String what, Object obj, ProcessRecord srcApp) {
2942        app.lastActivityTime = now;
2943
2944        if (app.activities.size() > 0) {
2945            // Don't want to touch dependent processes that are hosting activities.
2946            return index;
2947        }
2948
2949        int lrui = mLruProcesses.lastIndexOf(app);
2950        if (lrui < 0) {
2951            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2952                    + what + " " + obj + " from " + srcApp);
2953            return index;
2954        }
2955
2956        if (lrui >= index) {
2957            // Don't want to cause this to move dependent processes *back* in the
2958            // list as if they were less frequently used.
2959            return index;
2960        }
2961
2962        if (lrui >= mLruProcessActivityStart) {
2963            // Don't want to touch dependent processes that are hosting activities.
2964            return index;
2965        }
2966
2967        mLruProcesses.remove(lrui);
2968        if (index > 0) {
2969            index--;
2970        }
2971        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2972                + " in LRU list: " + app);
2973        mLruProcesses.add(index, app);
2974        return index;
2975    }
2976
2977    private static void killProcessGroup(int uid, int pid) {
2978        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2979        Process.killProcessGroup(uid, pid);
2980        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2981    }
2982
2983    final void removeLruProcessLocked(ProcessRecord app) {
2984        int lrui = mLruProcesses.lastIndexOf(app);
2985        if (lrui >= 0) {
2986            if (!app.killed) {
2987                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2988                Process.killProcessQuiet(app.pid);
2989                killProcessGroup(app.info.uid, app.pid);
2990            }
2991            if (lrui <= mLruProcessActivityStart) {
2992                mLruProcessActivityStart--;
2993            }
2994            if (lrui <= mLruProcessServiceStart) {
2995                mLruProcessServiceStart--;
2996            }
2997            mLruProcesses.remove(lrui);
2998        }
2999    }
3000
3001    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3002            ProcessRecord client) {
3003        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3004                || app.treatLikeActivity;
3005        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3006        if (!activityChange && hasActivity) {
3007            // The process has activities, so we are only allowing activity-based adjustments
3008            // to move it.  It should be kept in the front of the list with other
3009            // processes that have activities, and we don't want those to change their
3010            // order except due to activity operations.
3011            return;
3012        }
3013
3014        mLruSeq++;
3015        final long now = SystemClock.uptimeMillis();
3016        app.lastActivityTime = now;
3017
3018        // First a quick reject: if the app is already at the position we will
3019        // put it, then there is nothing to do.
3020        if (hasActivity) {
3021            final int N = mLruProcesses.size();
3022            if (N > 0 && mLruProcesses.get(N-1) == app) {
3023                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3024                return;
3025            }
3026        } else {
3027            if (mLruProcessServiceStart > 0
3028                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3029                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3030                return;
3031            }
3032        }
3033
3034        int lrui = mLruProcesses.lastIndexOf(app);
3035
3036        if (app.persistent && lrui >= 0) {
3037            // We don't care about the position of persistent processes, as long as
3038            // they are in the list.
3039            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3040            return;
3041        }
3042
3043        /* In progress: compute new position first, so we can avoid doing work
3044           if the process is not actually going to move.  Not yet working.
3045        int addIndex;
3046        int nextIndex;
3047        boolean inActivity = false, inService = false;
3048        if (hasActivity) {
3049            // Process has activities, put it at the very tipsy-top.
3050            addIndex = mLruProcesses.size();
3051            nextIndex = mLruProcessServiceStart;
3052            inActivity = true;
3053        } else if (hasService) {
3054            // Process has services, put it at the top of the service list.
3055            addIndex = mLruProcessActivityStart;
3056            nextIndex = mLruProcessServiceStart;
3057            inActivity = true;
3058            inService = true;
3059        } else  {
3060            // Process not otherwise of interest, it goes to the top of the non-service area.
3061            addIndex = mLruProcessServiceStart;
3062            if (client != null) {
3063                int clientIndex = mLruProcesses.lastIndexOf(client);
3064                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3065                        + app);
3066                if (clientIndex >= 0 && addIndex > clientIndex) {
3067                    addIndex = clientIndex;
3068                }
3069            }
3070            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3071        }
3072
3073        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3074                + mLruProcessActivityStart + "): " + app);
3075        */
3076
3077        if (lrui >= 0) {
3078            if (lrui < mLruProcessActivityStart) {
3079                mLruProcessActivityStart--;
3080            }
3081            if (lrui < mLruProcessServiceStart) {
3082                mLruProcessServiceStart--;
3083            }
3084            /*
3085            if (addIndex > lrui) {
3086                addIndex--;
3087            }
3088            if (nextIndex > lrui) {
3089                nextIndex--;
3090            }
3091            */
3092            mLruProcesses.remove(lrui);
3093        }
3094
3095        /*
3096        mLruProcesses.add(addIndex, app);
3097        if (inActivity) {
3098            mLruProcessActivityStart++;
3099        }
3100        if (inService) {
3101            mLruProcessActivityStart++;
3102        }
3103        */
3104
3105        int nextIndex;
3106        if (hasActivity) {
3107            final int N = mLruProcesses.size();
3108            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3109                // Process doesn't have activities, but has clients with
3110                // activities...  move it up, but one below the top (the top
3111                // should always have a real activity).
3112                if (DEBUG_LRU) Slog.d(TAG_LRU,
3113                        "Adding to second-top of LRU activity list: " + app);
3114                mLruProcesses.add(N - 1, app);
3115                // To keep it from spamming the LRU list (by making a bunch of clients),
3116                // we will push down any other entries owned by the app.
3117                final int uid = app.info.uid;
3118                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3119                    ProcessRecord subProc = mLruProcesses.get(i);
3120                    if (subProc.info.uid == uid) {
3121                        // We want to push this one down the list.  If the process after
3122                        // it is for the same uid, however, don't do so, because we don't
3123                        // want them internally to be re-ordered.
3124                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3125                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3126                                    "Pushing uid " + uid + " swapping at " + i + ": "
3127                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3128                            ProcessRecord tmp = mLruProcesses.get(i);
3129                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3130                            mLruProcesses.set(i - 1, tmp);
3131                            i--;
3132                        }
3133                    } else {
3134                        // A gap, we can stop here.
3135                        break;
3136                    }
3137                }
3138            } else {
3139                // Process has activities, put it at the very tipsy-top.
3140                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3141                mLruProcesses.add(app);
3142            }
3143            nextIndex = mLruProcessServiceStart;
3144        } else if (hasService) {
3145            // Process has services, put it at the top of the service list.
3146            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3147            mLruProcesses.add(mLruProcessActivityStart, app);
3148            nextIndex = mLruProcessServiceStart;
3149            mLruProcessActivityStart++;
3150        } else  {
3151            // Process not otherwise of interest, it goes to the top of the non-service area.
3152            int index = mLruProcessServiceStart;
3153            if (client != null) {
3154                // If there is a client, don't allow the process to be moved up higher
3155                // in the list than that client.
3156                int clientIndex = mLruProcesses.lastIndexOf(client);
3157                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3158                        + " when updating " + app);
3159                if (clientIndex <= lrui) {
3160                    // Don't allow the client index restriction to push it down farther in the
3161                    // list than it already is.
3162                    clientIndex = lrui;
3163                }
3164                if (clientIndex >= 0 && index > clientIndex) {
3165                    index = clientIndex;
3166                }
3167            }
3168            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3169            mLruProcesses.add(index, app);
3170            nextIndex = index-1;
3171            mLruProcessActivityStart++;
3172            mLruProcessServiceStart++;
3173        }
3174
3175        // If the app is currently using a content provider or service,
3176        // bump those processes as well.
3177        for (int j=app.connections.size()-1; j>=0; j--) {
3178            ConnectionRecord cr = app.connections.valueAt(j);
3179            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3180                    && cr.binding.service.app != null
3181                    && cr.binding.service.app.lruSeq != mLruSeq
3182                    && !cr.binding.service.app.persistent) {
3183                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3184                        "service connection", cr, app);
3185            }
3186        }
3187        for (int j=app.conProviders.size()-1; j>=0; j--) {
3188            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3189            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3190                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3191                        "provider reference", cpr, app);
3192            }
3193        }
3194    }
3195
3196    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3197        if (uid == Process.SYSTEM_UID) {
3198            // The system gets to run in any process.  If there are multiple
3199            // processes with the same uid, just pick the first (this
3200            // should never happen).
3201            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3202            if (procs == null) return null;
3203            final int procCount = procs.size();
3204            for (int i = 0; i < procCount; i++) {
3205                final int procUid = procs.keyAt(i);
3206                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3207                    // Don't use an app process or different user process for system component.
3208                    continue;
3209                }
3210                return procs.valueAt(i);
3211            }
3212        }
3213        ProcessRecord proc = mProcessNames.get(processName, uid);
3214        if (false && proc != null && !keepIfLarge
3215                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3216                && proc.lastCachedPss >= 4000) {
3217            // Turn this condition on to cause killing to happen regularly, for testing.
3218            if (proc.baseProcessTracker != null) {
3219                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3220            }
3221            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3222        } else if (proc != null && !keepIfLarge
3223                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3224                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3225            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3226            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3227                if (proc.baseProcessTracker != null) {
3228                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3229                }
3230                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3231            }
3232        }
3233        return proc;
3234    }
3235
3236    void notifyPackageUse(String packageName) {
3237        IPackageManager pm = AppGlobals.getPackageManager();
3238        try {
3239            pm.notifyPackageUse(packageName);
3240        } catch (RemoteException e) {
3241        }
3242    }
3243
3244    boolean isNextTransitionForward() {
3245        int transit = mWindowManager.getPendingAppTransition();
3246        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3247                || transit == AppTransition.TRANSIT_TASK_OPEN
3248                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3249    }
3250
3251    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3252            String processName, String abiOverride, int uid, Runnable crashHandler) {
3253        synchronized(this) {
3254            ApplicationInfo info = new ApplicationInfo();
3255            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3256            // For isolated processes, the former contains the parent's uid and the latter the
3257            // actual uid of the isolated process.
3258            // In the special case introduced by this method (which is, starting an isolated
3259            // process directly from the SystemServer without an actual parent app process) the
3260            // closest thing to a parent's uid is SYSTEM_UID.
3261            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3262            // the |isolated| logic in the ProcessRecord constructor.
3263            info.uid = Process.SYSTEM_UID;
3264            info.processName = processName;
3265            info.className = entryPoint;
3266            info.packageName = "android";
3267            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3268                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3269                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3270                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3271                    crashHandler);
3272            return proc != null ? proc.pid : 0;
3273        }
3274    }
3275
3276    final ProcessRecord startProcessLocked(String processName,
3277            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3278            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3279            boolean isolated, boolean keepIfLarge) {
3280        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3281                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3282                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3283                null /* crashHandler */);
3284    }
3285
3286    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3287            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3288            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3289            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3290        long startTime = SystemClock.elapsedRealtime();
3291        ProcessRecord app;
3292        if (!isolated) {
3293            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3294            checkTime(startTime, "startProcess: after getProcessRecord");
3295
3296            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3297                // If we are in the background, then check to see if this process
3298                // is bad.  If so, we will just silently fail.
3299                if (mBadProcesses.get(info.processName, info.uid) != null) {
3300                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3301                            + "/" + info.processName);
3302                    return null;
3303                }
3304            } else {
3305                // When the user is explicitly starting a process, then clear its
3306                // crash count so that we won't make it bad until they see at
3307                // least one crash dialog again, and make the process good again
3308                // if it had been bad.
3309                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3310                        + "/" + info.processName);
3311                mProcessCrashTimes.remove(info.processName, info.uid);
3312                if (mBadProcesses.get(info.processName, info.uid) != null) {
3313                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3314                            UserHandle.getUserId(info.uid), info.uid,
3315                            info.processName);
3316                    mBadProcesses.remove(info.processName, info.uid);
3317                    if (app != null) {
3318                        app.bad = false;
3319                    }
3320                }
3321            }
3322        } else {
3323            // If this is an isolated process, it can't re-use an existing process.
3324            app = null;
3325        }
3326
3327        // app launch boost for big.little configurations
3328        // use cpusets to migrate freshly launched tasks to big cores
3329        synchronized(ActivityManagerService.this) {
3330            nativeMigrateToBoost();
3331            mIsBoosted = true;
3332            mBoostStartTime = SystemClock.uptimeMillis();
3333            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3334            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3335        }
3336
3337        // We don't have to do anything more if:
3338        // (1) There is an existing application record; and
3339        // (2) The caller doesn't think it is dead, OR there is no thread
3340        //     object attached to it so we know it couldn't have crashed; and
3341        // (3) There is a pid assigned to it, so it is either starting or
3342        //     already running.
3343        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3344                + " app=" + app + " knownToBeDead=" + knownToBeDead
3345                + " thread=" + (app != null ? app.thread : null)
3346                + " pid=" + (app != null ? app.pid : -1));
3347        if (app != null && app.pid > 0) {
3348            if (!knownToBeDead || app.thread == null) {
3349                // We already have the app running, or are waiting for it to
3350                // come up (we have a pid but not yet its thread), so keep it.
3351                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3352                // If this is a new package in the process, add the package to the list
3353                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3354                checkTime(startTime, "startProcess: done, added package to proc");
3355                return app;
3356            }
3357
3358            // An application record is attached to a previous process,
3359            // clean it up now.
3360            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3361            checkTime(startTime, "startProcess: bad proc running, killing");
3362            killProcessGroup(app.info.uid, app.pid);
3363            handleAppDiedLocked(app, true, true);
3364            checkTime(startTime, "startProcess: done killing old proc");
3365        }
3366
3367        String hostingNameStr = hostingName != null
3368                ? hostingName.flattenToShortString() : null;
3369
3370        if (app == null) {
3371            checkTime(startTime, "startProcess: creating new process record");
3372            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3373            if (app == null) {
3374                Slog.w(TAG, "Failed making new process record for "
3375                        + processName + "/" + info.uid + " isolated=" + isolated);
3376                return null;
3377            }
3378            app.crashHandler = crashHandler;
3379            checkTime(startTime, "startProcess: done creating new process record");
3380        } else {
3381            // If this is a new package in the process, add the package to the list
3382            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3383            checkTime(startTime, "startProcess: added package to existing proc");
3384        }
3385
3386        // If the system is not ready yet, then hold off on starting this
3387        // process until it is.
3388        if (!mProcessesReady
3389                && !isAllowedWhileBooting(info)
3390                && !allowWhileBooting) {
3391            if (!mProcessesOnHold.contains(app)) {
3392                mProcessesOnHold.add(app);
3393            }
3394            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3395                    "System not ready, putting on hold: " + app);
3396            checkTime(startTime, "startProcess: returning with proc on hold");
3397            return app;
3398        }
3399
3400        checkTime(startTime, "startProcess: stepping in to startProcess");
3401        startProcessLocked(
3402                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3403        checkTime(startTime, "startProcess: done starting proc!");
3404        return (app.pid != 0) ? app : null;
3405    }
3406
3407    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3408        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3409    }
3410
3411    private final void startProcessLocked(ProcessRecord app,
3412            String hostingType, String hostingNameStr) {
3413        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3414                null /* entryPoint */, null /* entryPointArgs */);
3415    }
3416
3417    private final void startProcessLocked(ProcessRecord app, String hostingType,
3418            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3419        long startTime = SystemClock.elapsedRealtime();
3420        if (app.pid > 0 && app.pid != MY_PID) {
3421            checkTime(startTime, "startProcess: removing from pids map");
3422            synchronized (mPidsSelfLocked) {
3423                mPidsSelfLocked.remove(app.pid);
3424                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3425            }
3426            checkTime(startTime, "startProcess: done removing from pids map");
3427            app.setPid(0);
3428        }
3429
3430        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3431                "startProcessLocked removing on hold: " + app);
3432        mProcessesOnHold.remove(app);
3433
3434        checkTime(startTime, "startProcess: starting to update cpu stats");
3435        updateCpuStats();
3436        checkTime(startTime, "startProcess: done updating cpu stats");
3437
3438        try {
3439            try {
3440                final int userId = UserHandle.getUserId(app.uid);
3441                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3442            } catch (RemoteException e) {
3443                throw e.rethrowAsRuntimeException();
3444            }
3445
3446            int uid = app.uid;
3447            int[] gids = null;
3448            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3449            if (!app.isolated) {
3450                int[] permGids = null;
3451                try {
3452                    checkTime(startTime, "startProcess: getting gids from package manager");
3453                    final IPackageManager pm = AppGlobals.getPackageManager();
3454                    permGids = pm.getPackageGids(app.info.packageName,
3455                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3456                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3457                            MountServiceInternal.class);
3458                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3459                            app.info.packageName);
3460                } catch (RemoteException e) {
3461                    throw e.rethrowAsRuntimeException();
3462                }
3463
3464                /*
3465                 * Add shared application and profile GIDs so applications can share some
3466                 * resources like shared libraries and access user-wide resources
3467                 */
3468                if (ArrayUtils.isEmpty(permGids)) {
3469                    gids = new int[2];
3470                } else {
3471                    gids = new int[permGids.length + 2];
3472                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3473                }
3474                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3475                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3476            }
3477            checkTime(startTime, "startProcess: building args");
3478            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3479                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3480                        && mTopComponent != null
3481                        && app.processName.equals(mTopComponent.getPackageName())) {
3482                    uid = 0;
3483                }
3484                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3485                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3486                    uid = 0;
3487                }
3488            }
3489            int debugFlags = 0;
3490            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3491                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3492                // Also turn on CheckJNI for debuggable apps. It's quite
3493                // awkward to turn on otherwise.
3494                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3495            }
3496            // Run the app in safe mode if its manifest requests so or the
3497            // system is booted in safe mode.
3498            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3499                mSafeMode == true) {
3500                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3501            }
3502            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3503                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3504            }
3505            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3506            if ("true".equals(genDebugInfoProperty)) {
3507                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3508            }
3509            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3510                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3511            }
3512            if ("1".equals(SystemProperties.get("debug.assert"))) {
3513                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3514            }
3515
3516            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3517            if (requiredAbi == null) {
3518                requiredAbi = Build.SUPPORTED_ABIS[0];
3519            }
3520
3521            String instructionSet = null;
3522            if (app.info.primaryCpuAbi != null) {
3523                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3524            }
3525
3526            app.gids = gids;
3527            app.requiredAbi = requiredAbi;
3528            app.instructionSet = instructionSet;
3529
3530            // Start the process.  It will either succeed and return a result containing
3531            // the PID of the new process, or else throw a RuntimeException.
3532            boolean isActivityProcess = (entryPoint == null);
3533            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3534            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3535                    app.processName);
3536            checkTime(startTime, "startProcess: asking zygote to start proc");
3537            Process.ProcessStartResult startResult = Process.start(entryPoint,
3538                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3539                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3540                    app.info.dataDir, entryPointArgs);
3541            checkTime(startTime, "startProcess: returned from zygote!");
3542            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3543
3544            if (app.isolated) {
3545                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3546            }
3547            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3548            checkTime(startTime, "startProcess: done updating battery stats");
3549
3550            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3551                    UserHandle.getUserId(uid), startResult.pid, uid,
3552                    app.processName, hostingType,
3553                    hostingNameStr != null ? hostingNameStr : "");
3554
3555            if (app.persistent) {
3556                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3557            }
3558
3559            if (DEBUG_PROCESSES) {
3560                checkTime(startTime, "startProcess: building log message");
3561                StringBuilder buf = mStringBuilder;
3562                buf.setLength(0);
3563                buf.append("Start proc ");
3564                buf.append(startResult.pid);
3565                buf.append(':');
3566                buf.append(app.processName);
3567                buf.append('/');
3568                UserHandle.formatUid(buf, uid);
3569                if (!isActivityProcess) {
3570                    buf.append(" [");
3571                    buf.append(entryPoint);
3572                    buf.append("]");
3573                }
3574                buf.append(" for ");
3575                buf.append(hostingType);
3576                if (hostingNameStr != null) {
3577                    buf.append(" ");
3578                    buf.append(hostingNameStr);
3579                }
3580                Slog.i(TAG, buf.toString());
3581            }
3582            app.setPid(startResult.pid);
3583            app.usingWrapper = startResult.usingWrapper;
3584            app.removed = false;
3585            app.killed = false;
3586            app.killedByAm = false;
3587            checkTime(startTime, "startProcess: starting to update pids map");
3588            synchronized (mPidsSelfLocked) {
3589                this.mPidsSelfLocked.put(startResult.pid, app);
3590                if (isActivityProcess) {
3591                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3592                    msg.obj = app;
3593                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3594                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3595                }
3596            }
3597            checkTime(startTime, "startProcess: done updating pids map");
3598        } catch (RuntimeException e) {
3599            // XXX do better error recovery.
3600            app.setPid(0);
3601            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3602            if (app.isolated) {
3603                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3604            }
3605            Slog.e(TAG, "Failure starting process " + app.processName, e);
3606        }
3607    }
3608
3609    void updateUsageStats(ActivityRecord component, boolean resumed) {
3610        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3611                "updateUsageStats: comp=" + component + "res=" + resumed);
3612        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3613        if (resumed) {
3614            if (mUsageStatsService != null) {
3615                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3616                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3617            }
3618            synchronized (stats) {
3619                stats.noteActivityResumedLocked(component.app.uid);
3620            }
3621        } else {
3622            if (mUsageStatsService != null) {
3623                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3624                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3625            }
3626            synchronized (stats) {
3627                stats.noteActivityPausedLocked(component.app.uid);
3628            }
3629        }
3630    }
3631
3632    Intent getHomeIntent() {
3633        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3634        intent.setComponent(mTopComponent);
3635        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3636        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3637            intent.addCategory(Intent.CATEGORY_HOME);
3638        }
3639        return intent;
3640    }
3641
3642    boolean startHomeActivityLocked(int userId, String reason) {
3643        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3644                && mTopAction == null) {
3645            // We are running in factory test mode, but unable to find
3646            // the factory test app, so just sit around displaying the
3647            // error message and don't try to start anything.
3648            return false;
3649        }
3650        Intent intent = getHomeIntent();
3651        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3652        if (aInfo != null) {
3653            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3654            // Don't do this if the home app is currently being
3655            // instrumented.
3656            aInfo = new ActivityInfo(aInfo);
3657            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3658            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3659                    aInfo.applicationInfo.uid, true);
3660            if (app == null || app.instrumentationClass == null) {
3661                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3662                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3663            }
3664        }
3665
3666        return true;
3667    }
3668
3669    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3670        ActivityInfo ai = null;
3671        ComponentName comp = intent.getComponent();
3672        try {
3673            if (comp != null) {
3674                // Factory test.
3675                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3676            } else {
3677                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3678                        intent,
3679                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3680                        flags, userId);
3681
3682                if (info != null) {
3683                    ai = info.activityInfo;
3684                }
3685            }
3686        } catch (RemoteException e) {
3687            // ignore
3688        }
3689
3690        return ai;
3691    }
3692
3693    /**
3694     * Starts the "new version setup screen" if appropriate.
3695     */
3696    void startSetupActivityLocked() {
3697        // Only do this once per boot.
3698        if (mCheckedForSetup) {
3699            return;
3700        }
3701
3702        // We will show this screen if the current one is a different
3703        // version than the last one shown, and we are not running in
3704        // low-level factory test mode.
3705        final ContentResolver resolver = mContext.getContentResolver();
3706        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3707                Settings.Global.getInt(resolver,
3708                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3709            mCheckedForSetup = true;
3710
3711            // See if we should be showing the platform update setup UI.
3712            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3713            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3714                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3715            if (!ris.isEmpty()) {
3716                final ResolveInfo ri = ris.get(0);
3717                String vers = ri.activityInfo.metaData != null
3718                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3719                        : null;
3720                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3721                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3722                            Intent.METADATA_SETUP_VERSION);
3723                }
3724                String lastVers = Settings.Secure.getString(
3725                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3726                if (vers != null && !vers.equals(lastVers)) {
3727                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3728                    intent.setComponent(new ComponentName(
3729                            ri.activityInfo.packageName, ri.activityInfo.name));
3730                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3731                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3732                            null, 0, 0, 0, null, false, false, null, null, null);
3733                }
3734            }
3735        }
3736    }
3737
3738    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3739        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3740    }
3741
3742    void enforceNotIsolatedCaller(String caller) {
3743        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3744            throw new SecurityException("Isolated process not allowed to call " + caller);
3745        }
3746    }
3747
3748    void enforceShellRestriction(String restriction, int userHandle) {
3749        if (Binder.getCallingUid() == Process.SHELL_UID) {
3750            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3751                throw new SecurityException("Shell does not have permission to access user "
3752                        + userHandle);
3753            }
3754        }
3755    }
3756
3757    @Override
3758    public int getFrontActivityScreenCompatMode() {
3759        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3760        synchronized (this) {
3761            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3762        }
3763    }
3764
3765    @Override
3766    public void setFrontActivityScreenCompatMode(int mode) {
3767        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3768                "setFrontActivityScreenCompatMode");
3769        synchronized (this) {
3770            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3771        }
3772    }
3773
3774    @Override
3775    public int getPackageScreenCompatMode(String packageName) {
3776        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3777        synchronized (this) {
3778            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3779        }
3780    }
3781
3782    @Override
3783    public void setPackageScreenCompatMode(String packageName, int mode) {
3784        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3785                "setPackageScreenCompatMode");
3786        synchronized (this) {
3787            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3788        }
3789    }
3790
3791    @Override
3792    public boolean getPackageAskScreenCompat(String packageName) {
3793        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3794        synchronized (this) {
3795            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3796        }
3797    }
3798
3799    @Override
3800    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3801        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3802                "setPackageAskScreenCompat");
3803        synchronized (this) {
3804            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3805        }
3806    }
3807
3808    private boolean hasUsageStatsPermission(String callingPackage) {
3809        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3810                Binder.getCallingUid(), callingPackage);
3811        if (mode == AppOpsManager.MODE_DEFAULT) {
3812            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3813                    == PackageManager.PERMISSION_GRANTED;
3814        }
3815        return mode == AppOpsManager.MODE_ALLOWED;
3816    }
3817
3818    @Override
3819    public int getPackageProcessState(String packageName, String callingPackage) {
3820        if (!hasUsageStatsPermission(callingPackage)) {
3821            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3822                    "getPackageProcessState");
3823        }
3824
3825        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3826        synchronized (this) {
3827            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3828                final ProcessRecord proc = mLruProcesses.get(i);
3829                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3830                        || procState > proc.setProcState) {
3831                    boolean found = false;
3832                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3833                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3834                            procState = proc.setProcState;
3835                            found = true;
3836                        }
3837                    }
3838                    if (proc.pkgDeps != null && !found) {
3839                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3840                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3841                                procState = proc.setProcState;
3842                                break;
3843                            }
3844                        }
3845                    }
3846                }
3847            }
3848        }
3849        return procState;
3850    }
3851
3852    @Override
3853    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3854        synchronized (this) {
3855            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3856            if (app == null) {
3857                return false;
3858            }
3859            if (app.trimMemoryLevel < level && app.thread != null &&
3860                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3861                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3862                try {
3863                    app.thread.scheduleTrimMemory(level);
3864                    app.trimMemoryLevel = level;
3865                    return true;
3866                } catch (RemoteException e) {
3867                    // Fallthrough to failure case.
3868                }
3869            }
3870        }
3871        return false;
3872    }
3873
3874    private void dispatchProcessesChanged() {
3875        int N;
3876        synchronized (this) {
3877            N = mPendingProcessChanges.size();
3878            if (mActiveProcessChanges.length < N) {
3879                mActiveProcessChanges = new ProcessChangeItem[N];
3880            }
3881            mPendingProcessChanges.toArray(mActiveProcessChanges);
3882            mPendingProcessChanges.clear();
3883            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3884                    "*** Delivering " + N + " process changes");
3885        }
3886
3887        int i = mProcessObservers.beginBroadcast();
3888        while (i > 0) {
3889            i--;
3890            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3891            if (observer != null) {
3892                try {
3893                    for (int j=0; j<N; j++) {
3894                        ProcessChangeItem item = mActiveProcessChanges[j];
3895                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3896                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3897                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3898                                    + item.uid + ": " + item.foregroundActivities);
3899                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3900                                    item.foregroundActivities);
3901                        }
3902                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3903                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3904                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3905                                    + ": " + item.processState);
3906                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3907                        }
3908                    }
3909                } catch (RemoteException e) {
3910                }
3911            }
3912        }
3913        mProcessObservers.finishBroadcast();
3914
3915        synchronized (this) {
3916            for (int j=0; j<N; j++) {
3917                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3918            }
3919        }
3920    }
3921
3922    private void dispatchProcessDied(int pid, int uid) {
3923        int i = mProcessObservers.beginBroadcast();
3924        while (i > 0) {
3925            i--;
3926            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3927            if (observer != null) {
3928                try {
3929                    observer.onProcessDied(pid, uid);
3930                } catch (RemoteException e) {
3931                }
3932            }
3933        }
3934        mProcessObservers.finishBroadcast();
3935    }
3936
3937    private void dispatchUidsChanged() {
3938        int N;
3939        synchronized (this) {
3940            N = mPendingUidChanges.size();
3941            if (mActiveUidChanges.length < N) {
3942                mActiveUidChanges = new UidRecord.ChangeItem[N];
3943            }
3944            for (int i=0; i<N; i++) {
3945                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3946                mActiveUidChanges[i] = change;
3947                if (change.uidRecord != null) {
3948                    change.uidRecord.pendingChange = null;
3949                    change.uidRecord = null;
3950                }
3951            }
3952            mPendingUidChanges.clear();
3953            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3954                    "*** Delivering " + N + " uid changes");
3955        }
3956
3957        if (mLocalPowerManager != null) {
3958            for (int j=0; j<N; j++) {
3959                UidRecord.ChangeItem item = mActiveUidChanges[j];
3960                if (item.change == UidRecord.CHANGE_GONE
3961                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3962                    mLocalPowerManager.uidGone(item.uid);
3963                } else {
3964                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3965                }
3966            }
3967        }
3968
3969        int i = mUidObservers.beginBroadcast();
3970        while (i > 0) {
3971            i--;
3972            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3973            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3974            if (observer != null) {
3975                try {
3976                    for (int j=0; j<N; j++) {
3977                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3978                        final int change = item.change;
3979                        UidRecord validateUid = null;
3980                        if (VALIDATE_UID_STATES && i == 0) {
3981                            validateUid = mValidateUids.get(item.uid);
3982                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3983                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3984                                validateUid = new UidRecord(item.uid);
3985                                mValidateUids.put(item.uid, validateUid);
3986                            }
3987                        }
3988                        if (change == UidRecord.CHANGE_IDLE
3989                                || change == UidRecord.CHANGE_GONE_IDLE) {
3990                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3991                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3992                                        "UID idle uid=" + item.uid);
3993                                observer.onUidIdle(item.uid);
3994                            }
3995                            if (VALIDATE_UID_STATES && i == 0) {
3996                                if (validateUid != null) {
3997                                    validateUid.idle = true;
3998                                }
3999                            }
4000                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4001                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4002                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4003                                        "UID active uid=" + item.uid);
4004                                observer.onUidActive(item.uid);
4005                            }
4006                            if (VALIDATE_UID_STATES && i == 0) {
4007                                validateUid.idle = false;
4008                            }
4009                        }
4010                        if (change == UidRecord.CHANGE_GONE
4011                                || change == UidRecord.CHANGE_GONE_IDLE) {
4012                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4013                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4014                                        "UID gone uid=" + item.uid);
4015                                observer.onUidGone(item.uid);
4016                            }
4017                            if (VALIDATE_UID_STATES && i == 0) {
4018                                if (validateUid != null) {
4019                                    mValidateUids.remove(item.uid);
4020                                }
4021                            }
4022                        } else {
4023                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4024                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4025                                        "UID CHANGED uid=" + item.uid
4026                                                + ": " + item.processState);
4027                                observer.onUidStateChanged(item.uid, item.processState);
4028                            }
4029                            if (VALIDATE_UID_STATES && i == 0) {
4030                                validateUid.curProcState = validateUid.setProcState
4031                                        = item.processState;
4032                            }
4033                        }
4034                    }
4035                } catch (RemoteException e) {
4036                }
4037            }
4038        }
4039        mUidObservers.finishBroadcast();
4040
4041        synchronized (this) {
4042            for (int j=0; j<N; j++) {
4043                mAvailUidChanges.add(mActiveUidChanges[j]);
4044            }
4045        }
4046    }
4047
4048    @Override
4049    public final int startActivity(IApplicationThread caller, String callingPackage,
4050            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4051            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4052        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4053                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4054                UserHandle.getCallingUserId());
4055    }
4056
4057    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4058        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4059        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4060                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4061                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4062
4063        // TODO: Switch to user app stacks here.
4064        String mimeType = intent.getType();
4065        final Uri data = intent.getData();
4066        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4067            mimeType = getProviderMimeType(data, userId);
4068        }
4069        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4070
4071        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4072        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4073                null, 0, 0, null, null, null, null, false, userId, container, null);
4074    }
4075
4076    @Override
4077    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4078            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4079            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4080        enforceNotIsolatedCaller("startActivity");
4081        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4082                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4083        // TODO: Switch to user app stacks here.
4084        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4085                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4086                profilerInfo, null, null, bOptions, false, userId, null, null);
4087    }
4088
4089    @Override
4090    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4091            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4092            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4093            int userId) {
4094
4095        // This is very dangerous -- it allows you to perform a start activity (including
4096        // permission grants) as any app that may launch one of your own activities.  So
4097        // we will only allow this to be done from activities that are part of the core framework,
4098        // and then only when they are running as the system.
4099        final ActivityRecord sourceRecord;
4100        final int targetUid;
4101        final String targetPackage;
4102        synchronized (this) {
4103            if (resultTo == null) {
4104                throw new SecurityException("Must be called from an activity");
4105            }
4106            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4107            if (sourceRecord == null) {
4108                throw new SecurityException("Called with bad activity token: " + resultTo);
4109            }
4110            if (!sourceRecord.info.packageName.equals("android")) {
4111                throw new SecurityException(
4112                        "Must be called from an activity that is declared in the android package");
4113            }
4114            if (sourceRecord.app == null) {
4115                throw new SecurityException("Called without a process attached to activity");
4116            }
4117            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4118                // This is still okay, as long as this activity is running under the
4119                // uid of the original calling activity.
4120                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4121                    throw new SecurityException(
4122                            "Calling activity in uid " + sourceRecord.app.uid
4123                                    + " must be system uid or original calling uid "
4124                                    + sourceRecord.launchedFromUid);
4125                }
4126            }
4127            if (ignoreTargetSecurity) {
4128                if (intent.getComponent() == null) {
4129                    throw new SecurityException(
4130                            "Component must be specified with ignoreTargetSecurity");
4131                }
4132                if (intent.getSelector() != null) {
4133                    throw new SecurityException(
4134                            "Selector not allowed with ignoreTargetSecurity");
4135                }
4136            }
4137            targetUid = sourceRecord.launchedFromUid;
4138            targetPackage = sourceRecord.launchedFromPackage;
4139        }
4140
4141        if (userId == UserHandle.USER_NULL) {
4142            userId = UserHandle.getUserId(sourceRecord.app.uid);
4143        }
4144
4145        // TODO: Switch to user app stacks here.
4146        try {
4147            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4148                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4149                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4150            return ret;
4151        } catch (SecurityException e) {
4152            // XXX need to figure out how to propagate to original app.
4153            // A SecurityException here is generally actually a fault of the original
4154            // calling activity (such as a fairly granting permissions), so propagate it
4155            // back to them.
4156            /*
4157            StringBuilder msg = new StringBuilder();
4158            msg.append("While launching");
4159            msg.append(intent.toString());
4160            msg.append(": ");
4161            msg.append(e.getMessage());
4162            */
4163            throw e;
4164        }
4165    }
4166
4167    @Override
4168    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4169            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4170            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4171        enforceNotIsolatedCaller("startActivityAndWait");
4172        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4173                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4174        WaitResult res = new WaitResult();
4175        // TODO: Switch to user app stacks here.
4176        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4177                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4178                bOptions, false, userId, null, null);
4179        return res;
4180    }
4181
4182    @Override
4183    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4184            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4185            int startFlags, Configuration config, Bundle bOptions, int userId) {
4186        enforceNotIsolatedCaller("startActivityWithConfig");
4187        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4188                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4189        // TODO: Switch to user app stacks here.
4190        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4191                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4192                null, null, config, bOptions, false, userId, null, null);
4193        return ret;
4194    }
4195
4196    @Override
4197    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4198            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4199            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4200            throws TransactionTooLargeException {
4201        enforceNotIsolatedCaller("startActivityIntentSender");
4202        // Refuse possible leaked file descriptors
4203        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4204            throw new IllegalArgumentException("File descriptors passed in Intent");
4205        }
4206
4207        IIntentSender sender = intent.getTarget();
4208        if (!(sender instanceof PendingIntentRecord)) {
4209            throw new IllegalArgumentException("Bad PendingIntent object");
4210        }
4211
4212        PendingIntentRecord pir = (PendingIntentRecord)sender;
4213
4214        synchronized (this) {
4215            // If this is coming from the currently resumed activity, it is
4216            // effectively saying that app switches are allowed at this point.
4217            final ActivityStack stack = getFocusedStack();
4218            if (stack.mResumedActivity != null &&
4219                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4220                mAppSwitchesAllowedTime = 0;
4221            }
4222        }
4223        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4224                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4225        return ret;
4226    }
4227
4228    @Override
4229    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4230            Intent intent, String resolvedType, IVoiceInteractionSession session,
4231            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4232            Bundle bOptions, int userId) {
4233        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4234                != PackageManager.PERMISSION_GRANTED) {
4235            String msg = "Permission Denial: startVoiceActivity() from pid="
4236                    + Binder.getCallingPid()
4237                    + ", uid=" + Binder.getCallingUid()
4238                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4239            Slog.w(TAG, msg);
4240            throw new SecurityException(msg);
4241        }
4242        if (session == null || interactor == null) {
4243            throw new NullPointerException("null session or interactor");
4244        }
4245        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4246                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4247        // TODO: Switch to user app stacks here.
4248        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4249                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4250                null, bOptions, false, userId, null, null);
4251    }
4252
4253    @Override
4254    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4255        synchronized (this) {
4256            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4257                if (keepAwake) {
4258                    mVoiceWakeLock.acquire();
4259                } else {
4260                    mVoiceWakeLock.release();
4261                }
4262            }
4263        }
4264    }
4265
4266    @Override
4267    public boolean startNextMatchingActivity(IBinder callingActivity,
4268            Intent intent, Bundle bOptions) {
4269        // Refuse possible leaked file descriptors
4270        if (intent != null && intent.hasFileDescriptors() == true) {
4271            throw new IllegalArgumentException("File descriptors passed in Intent");
4272        }
4273        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4274
4275        synchronized (this) {
4276            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4277            if (r == null) {
4278                ActivityOptions.abort(options);
4279                return false;
4280            }
4281            if (r.app == null || r.app.thread == null) {
4282                // The caller is not running...  d'oh!
4283                ActivityOptions.abort(options);
4284                return false;
4285            }
4286            intent = new Intent(intent);
4287            // The caller is not allowed to change the data.
4288            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4289            // And we are resetting to find the next component...
4290            intent.setComponent(null);
4291
4292            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4293
4294            ActivityInfo aInfo = null;
4295            try {
4296                List<ResolveInfo> resolves =
4297                    AppGlobals.getPackageManager().queryIntentActivities(
4298                            intent, r.resolvedType,
4299                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4300                            UserHandle.getCallingUserId());
4301
4302                // Look for the original activity in the list...
4303                final int N = resolves != null ? resolves.size() : 0;
4304                for (int i=0; i<N; i++) {
4305                    ResolveInfo rInfo = resolves.get(i);
4306                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4307                            && rInfo.activityInfo.name.equals(r.info.name)) {
4308                        // We found the current one...  the next matching is
4309                        // after it.
4310                        i++;
4311                        if (i<N) {
4312                            aInfo = resolves.get(i).activityInfo;
4313                        }
4314                        if (debug) {
4315                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4316                                    + "/" + r.info.name);
4317                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4318                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4319                        }
4320                        break;
4321                    }
4322                }
4323            } catch (RemoteException e) {
4324            }
4325
4326            if (aInfo == null) {
4327                // Nobody who is next!
4328                ActivityOptions.abort(options);
4329                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4330                return false;
4331            }
4332
4333            intent.setComponent(new ComponentName(
4334                    aInfo.applicationInfo.packageName, aInfo.name));
4335            intent.setFlags(intent.getFlags()&~(
4336                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4337                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4338                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4339                    Intent.FLAG_ACTIVITY_NEW_TASK));
4340
4341            // Okay now we need to start the new activity, replacing the
4342            // currently running activity.  This is a little tricky because
4343            // we want to start the new one as if the current one is finished,
4344            // but not finish the current one first so that there is no flicker.
4345            // And thus...
4346            final boolean wasFinishing = r.finishing;
4347            r.finishing = true;
4348
4349            // Propagate reply information over to the new activity.
4350            final ActivityRecord resultTo = r.resultTo;
4351            final String resultWho = r.resultWho;
4352            final int requestCode = r.requestCode;
4353            r.resultTo = null;
4354            if (resultTo != null) {
4355                resultTo.removeResultsLocked(r, resultWho, requestCode);
4356            }
4357
4358            final long origId = Binder.clearCallingIdentity();
4359            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4360                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4361                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4362                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4363                    false, false, null, null, null);
4364            Binder.restoreCallingIdentity(origId);
4365
4366            r.finishing = wasFinishing;
4367            if (res != ActivityManager.START_SUCCESS) {
4368                return false;
4369            }
4370            return true;
4371        }
4372    }
4373
4374    @Override
4375    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4376        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4377            String msg = "Permission Denial: startActivityFromRecents called without " +
4378                    START_TASKS_FROM_RECENTS;
4379            Slog.w(TAG, msg);
4380            throw new SecurityException(msg);
4381        }
4382        final long origId = Binder.clearCallingIdentity();
4383        try {
4384            return startActivityFromRecentsInner(taskId, bOptions);
4385        } finally {
4386            Binder.restoreCallingIdentity(origId);
4387        }
4388    }
4389
4390    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4391        final TaskRecord task;
4392        final int callingUid;
4393        final String callingPackage;
4394        final Intent intent;
4395        final int userId;
4396        synchronized (this) {
4397            final ActivityOptions activityOptions = (bOptions != null)
4398                    ? new ActivityOptions(bOptions) : null;
4399            final int launchStackId = (activityOptions != null)
4400                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4401
4402            if (launchStackId == HOME_STACK_ID) {
4403                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4404                        + taskId + " can't be launch in the home stack.");
4405            }
4406            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4407            if (task == null) {
4408                throw new IllegalArgumentException(
4409                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4410            }
4411
4412            if (launchStackId != INVALID_STACK_ID) {
4413                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4414                    mWindowManager.setDockedStackCreateState(
4415                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4416                }
4417                if (task.stack.mStackId != launchStackId) {
4418                    mStackSupervisor.moveTaskToStackLocked(
4419                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4420                            ANIMATE);
4421                }
4422            }
4423
4424            // If the user must confirm credentials (e.g. when first launching a work app and the
4425            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4426            if (!mUserController.shouldConfirmCredentials(task.userId)
4427                    && task.getRootActivity() != null) {
4428                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4429                return ActivityManager.START_TASK_TO_FRONT;
4430            }
4431            callingUid = task.mCallingUid;
4432            callingPackage = task.mCallingPackage;
4433            intent = task.intent;
4434            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4435            userId = task.userId;
4436        }
4437        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4438                bOptions, userId, null, task);
4439    }
4440
4441    final int startActivityInPackage(int uid, String callingPackage,
4442            Intent intent, String resolvedType, IBinder resultTo,
4443            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4444            IActivityContainer container, TaskRecord inTask) {
4445
4446        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4447                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4448
4449        // TODO: Switch to user app stacks here.
4450        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4451                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4452                null, null, null, bOptions, false, userId, container, inTask);
4453        return ret;
4454    }
4455
4456    @Override
4457    public final int startActivities(IApplicationThread caller, String callingPackage,
4458            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4459            int userId) {
4460        enforceNotIsolatedCaller("startActivities");
4461        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4462                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4463        // TODO: Switch to user app stacks here.
4464        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4465                resolvedTypes, resultTo, bOptions, userId);
4466        return ret;
4467    }
4468
4469    final int startActivitiesInPackage(int uid, String callingPackage,
4470            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4471            Bundle bOptions, int userId) {
4472
4473        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4474                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4475        // TODO: Switch to user app stacks here.
4476        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4477                resultTo, bOptions, userId);
4478        return ret;
4479    }
4480
4481    @Override
4482    public void reportActivityFullyDrawn(IBinder token) {
4483        synchronized (this) {
4484            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4485            if (r == null) {
4486                return;
4487            }
4488            r.reportFullyDrawnLocked();
4489        }
4490    }
4491
4492    @Override
4493    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4494        synchronized (this) {
4495            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4496            if (r == null) {
4497                return;
4498            }
4499            TaskRecord task = r.task;
4500            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4501                // Fixed screen orientation isn't supported when activities aren't in full screen
4502                // mode.
4503                return;
4504            }
4505            final long origId = Binder.clearCallingIdentity();
4506            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4507            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4508                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4509            if (config != null) {
4510                r.frozenBeforeDestroy = true;
4511                if (!updateConfigurationLocked(config, r, false)) {
4512                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4513                }
4514            }
4515            Binder.restoreCallingIdentity(origId);
4516        }
4517    }
4518
4519    @Override
4520    public int getRequestedOrientation(IBinder token) {
4521        synchronized (this) {
4522            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4523            if (r == null) {
4524                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4525            }
4526            return mWindowManager.getAppOrientation(r.appToken);
4527        }
4528    }
4529
4530    /**
4531     * This is the internal entry point for handling Activity.finish().
4532     *
4533     * @param token The Binder token referencing the Activity we want to finish.
4534     * @param resultCode Result code, if any, from this Activity.
4535     * @param resultData Result data (Intent), if any, from this Activity.
4536     * @param finishTask Whether to finish the task associated with this Activity.
4537     *
4538     * @return Returns true if the activity successfully finished, or false if it is still running.
4539     */
4540    @Override
4541    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4542            int finishTask) {
4543        // Refuse possible leaked file descriptors
4544        if (resultData != null && resultData.hasFileDescriptors() == true) {
4545            throw new IllegalArgumentException("File descriptors passed in Intent");
4546        }
4547
4548        synchronized(this) {
4549            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4550            if (r == null) {
4551                return true;
4552            }
4553            // Keep track of the root activity of the task before we finish it
4554            TaskRecord tr = r.task;
4555            ActivityRecord rootR = tr.getRootActivity();
4556            if (rootR == null) {
4557                Slog.w(TAG, "Finishing task with all activities already finished");
4558            }
4559            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4560            // finish.
4561            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4562                    mStackSupervisor.isLastLockedTask(tr)) {
4563                Slog.i(TAG, "Not finishing task in lock task mode");
4564                mStackSupervisor.showLockTaskToast();
4565                return false;
4566            }
4567            if (mController != null) {
4568                // Find the first activity that is not finishing.
4569                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4570                if (next != null) {
4571                    // ask watcher if this is allowed
4572                    boolean resumeOK = true;
4573                    try {
4574                        resumeOK = mController.activityResuming(next.packageName);
4575                    } catch (RemoteException e) {
4576                        mController = null;
4577                        Watchdog.getInstance().setActivityController(null);
4578                    }
4579
4580                    if (!resumeOK) {
4581                        Slog.i(TAG, "Not finishing activity because controller resumed");
4582                        return false;
4583                    }
4584                }
4585            }
4586            final long origId = Binder.clearCallingIdentity();
4587            try {
4588                boolean res;
4589                final boolean finishWithRootActivity =
4590                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4591                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4592                        || (finishWithRootActivity && r == rootR)) {
4593                    // If requested, remove the task that is associated to this activity only if it
4594                    // was the root activity in the task. The result code and data is ignored
4595                    // because we don't support returning them across task boundaries. Also, to
4596                    // keep backwards compatibility we remove the task from recents when finishing
4597                    // task with root activity.
4598                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4599                    if (!res) {
4600                        Slog.i(TAG, "Removing task failed to finish activity");
4601                    }
4602                } else {
4603                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4604                            resultData, "app-request", true);
4605                    if (!res) {
4606                        Slog.i(TAG, "Failed to finish by app-request");
4607                    }
4608                }
4609                return res;
4610            } finally {
4611                Binder.restoreCallingIdentity(origId);
4612            }
4613        }
4614    }
4615
4616    @Override
4617    public final void finishHeavyWeightApp() {
4618        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4619                != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        synchronized(this) {
4629            if (mHeavyWeightProcess == null) {
4630                return;
4631            }
4632
4633            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4634            for (int i = 0; i < activities.size(); i++) {
4635                ActivityRecord r = activities.get(i);
4636                if (!r.finishing && r.isInStackLocked()) {
4637                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4638                            null, "finish-heavy", true);
4639                }
4640            }
4641
4642            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4643                    mHeavyWeightProcess.userId, 0));
4644            mHeavyWeightProcess = null;
4645        }
4646    }
4647
4648    @Override
4649    public void crashApplication(int uid, int initialPid, String packageName,
4650            String message) {
4651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4652                != PackageManager.PERMISSION_GRANTED) {
4653            String msg = "Permission Denial: crashApplication() from pid="
4654                    + Binder.getCallingPid()
4655                    + ", uid=" + Binder.getCallingUid()
4656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4657            Slog.w(TAG, msg);
4658            throw new SecurityException(msg);
4659        }
4660
4661        synchronized(this) {
4662            ProcessRecord proc = null;
4663
4664            // Figure out which process to kill.  We don't trust that initialPid
4665            // still has any relation to current pids, so must scan through the
4666            // list.
4667            synchronized (mPidsSelfLocked) {
4668                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4669                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4670                    if (p.uid != uid) {
4671                        continue;
4672                    }
4673                    if (p.pid == initialPid) {
4674                        proc = p;
4675                        break;
4676                    }
4677                    if (p.pkgList.containsKey(packageName)) {
4678                        proc = p;
4679                    }
4680                }
4681            }
4682
4683            if (proc == null) {
4684                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4685                        + " initialPid=" + initialPid
4686                        + " packageName=" + packageName);
4687                return;
4688            }
4689
4690            if (proc.thread != null) {
4691                if (proc.pid == Process.myPid()) {
4692                    Log.w(TAG, "crashApplication: trying to crash self!");
4693                    return;
4694                }
4695                long ident = Binder.clearCallingIdentity();
4696                try {
4697                    proc.thread.scheduleCrash(message);
4698                } catch (RemoteException e) {
4699                }
4700                Binder.restoreCallingIdentity(ident);
4701            }
4702        }
4703    }
4704
4705    @Override
4706    public final void finishSubActivity(IBinder token, String resultWho,
4707            int requestCode) {
4708        synchronized(this) {
4709            final long origId = Binder.clearCallingIdentity();
4710            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4711            if (r != null) {
4712                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4713            }
4714            Binder.restoreCallingIdentity(origId);
4715        }
4716    }
4717
4718    @Override
4719    public boolean finishActivityAffinity(IBinder token) {
4720        synchronized(this) {
4721            final long origId = Binder.clearCallingIdentity();
4722            try {
4723                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4724                if (r == null) {
4725                    return false;
4726                }
4727
4728                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4729                // can finish.
4730                final TaskRecord task = r.task;
4731                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4732                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4733                    mStackSupervisor.showLockTaskToast();
4734                    return false;
4735                }
4736                return task.stack.finishActivityAffinityLocked(r);
4737            } finally {
4738                Binder.restoreCallingIdentity(origId);
4739            }
4740        }
4741    }
4742
4743    @Override
4744    public void finishVoiceTask(IVoiceInteractionSession session) {
4745        synchronized(this) {
4746            final long origId = Binder.clearCallingIdentity();
4747            try {
4748                mStackSupervisor.finishVoiceTask(session);
4749            } finally {
4750                Binder.restoreCallingIdentity(origId);
4751            }
4752        }
4753
4754    }
4755
4756    @Override
4757    public boolean releaseActivityInstance(IBinder token) {
4758        synchronized(this) {
4759            final long origId = Binder.clearCallingIdentity();
4760            try {
4761                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4762                if (r == null) {
4763                    return false;
4764                }
4765                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4766            } finally {
4767                Binder.restoreCallingIdentity(origId);
4768            }
4769        }
4770    }
4771
4772    @Override
4773    public void releaseSomeActivities(IApplicationThread appInt) {
4774        synchronized(this) {
4775            final long origId = Binder.clearCallingIdentity();
4776            try {
4777                ProcessRecord app = getRecordForAppLocked(appInt);
4778                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4779            } finally {
4780                Binder.restoreCallingIdentity(origId);
4781            }
4782        }
4783    }
4784
4785    @Override
4786    public boolean willActivityBeVisible(IBinder token) {
4787        synchronized(this) {
4788            ActivityStack stack = ActivityRecord.getStackLocked(token);
4789            if (stack != null) {
4790                return stack.willActivityBeVisibleLocked(token);
4791            }
4792            return false;
4793        }
4794    }
4795
4796    @Override
4797    public void overridePendingTransition(IBinder token, String packageName,
4798            int enterAnim, int exitAnim) {
4799        synchronized(this) {
4800            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4801            if (self == null) {
4802                return;
4803            }
4804
4805            final long origId = Binder.clearCallingIdentity();
4806
4807            if (self.state == ActivityState.RESUMED
4808                    || self.state == ActivityState.PAUSING) {
4809                mWindowManager.overridePendingAppTransition(packageName,
4810                        enterAnim, exitAnim, null);
4811            }
4812
4813            Binder.restoreCallingIdentity(origId);
4814        }
4815    }
4816
4817    /**
4818     * Main function for removing an existing process from the activity manager
4819     * as a result of that process going away.  Clears out all connections
4820     * to the process.
4821     */
4822    private final void handleAppDiedLocked(ProcessRecord app,
4823            boolean restarting, boolean allowRestart) {
4824        int pid = app.pid;
4825        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4826        if (!kept && !restarting) {
4827            removeLruProcessLocked(app);
4828            if (pid > 0) {
4829                ProcessList.remove(pid);
4830            }
4831        }
4832
4833        if (mProfileProc == app) {
4834            clearProfilerLocked();
4835        }
4836
4837        // Remove this application's activities from active lists.
4838        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4839
4840        app.activities.clear();
4841
4842        if (app.instrumentationClass != null) {
4843            Slog.w(TAG, "Crash of app " + app.processName
4844                  + " running instrumentation " + app.instrumentationClass);
4845            Bundle info = new Bundle();
4846            info.putString("shortMsg", "Process crashed.");
4847            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4848        }
4849
4850        if (!restarting && hasVisibleActivities
4851                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4852            // If there was nothing to resume, and we are not already restarting this process, but
4853            // there is a visible activity that is hosted by the process...  then make sure all
4854            // visible activities are running, taking care of restarting this process.
4855            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4856        }
4857    }
4858
4859    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4860        IBinder threadBinder = thread.asBinder();
4861        // Find the application record.
4862        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4863            ProcessRecord rec = mLruProcesses.get(i);
4864            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4865                return i;
4866            }
4867        }
4868        return -1;
4869    }
4870
4871    final ProcessRecord getRecordForAppLocked(
4872            IApplicationThread thread) {
4873        if (thread == null) {
4874            return null;
4875        }
4876
4877        int appIndex = getLRURecordIndexForAppLocked(thread);
4878        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4879    }
4880
4881    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4882        // If there are no longer any background processes running,
4883        // and the app that died was not running instrumentation,
4884        // then tell everyone we are now low on memory.
4885        boolean haveBg = false;
4886        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4887            ProcessRecord rec = mLruProcesses.get(i);
4888            if (rec.thread != null
4889                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4890                haveBg = true;
4891                break;
4892            }
4893        }
4894
4895        if (!haveBg) {
4896            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4897            if (doReport) {
4898                long now = SystemClock.uptimeMillis();
4899                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4900                    doReport = false;
4901                } else {
4902                    mLastMemUsageReportTime = now;
4903                }
4904            }
4905            final ArrayList<ProcessMemInfo> memInfos
4906                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4907            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4908            long now = SystemClock.uptimeMillis();
4909            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4910                ProcessRecord rec = mLruProcesses.get(i);
4911                if (rec == dyingProc || rec.thread == null) {
4912                    continue;
4913                }
4914                if (doReport) {
4915                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4916                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4917                }
4918                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4919                    // The low memory report is overriding any current
4920                    // state for a GC request.  Make sure to do
4921                    // heavy/important/visible/foreground processes first.
4922                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4923                        rec.lastRequestedGc = 0;
4924                    } else {
4925                        rec.lastRequestedGc = rec.lastLowMemory;
4926                    }
4927                    rec.reportLowMemory = true;
4928                    rec.lastLowMemory = now;
4929                    mProcessesToGc.remove(rec);
4930                    addProcessToGcListLocked(rec);
4931                }
4932            }
4933            if (doReport) {
4934                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4935                mHandler.sendMessage(msg);
4936            }
4937            scheduleAppGcsLocked();
4938        }
4939    }
4940
4941    final void appDiedLocked(ProcessRecord app) {
4942       appDiedLocked(app, app.pid, app.thread, false);
4943    }
4944
4945    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4946            boolean fromBinderDied) {
4947        // First check if this ProcessRecord is actually active for the pid.
4948        synchronized (mPidsSelfLocked) {
4949            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4950            if (curProc != app) {
4951                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4952                return;
4953            }
4954        }
4955
4956        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4957        synchronized (stats) {
4958            stats.noteProcessDiedLocked(app.info.uid, pid);
4959        }
4960
4961        if (!app.killed) {
4962            if (!fromBinderDied) {
4963                Process.killProcessQuiet(pid);
4964            }
4965            killProcessGroup(app.info.uid, pid);
4966            app.killed = true;
4967        }
4968
4969        // Clean up already done if the process has been re-started.
4970        if (app.pid == pid && app.thread != null &&
4971                app.thread.asBinder() == thread.asBinder()) {
4972            boolean doLowMem = app.instrumentationClass == null;
4973            boolean doOomAdj = doLowMem;
4974            if (!app.killedByAm) {
4975                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4976                        + ") has died");
4977                mAllowLowerMemLevel = true;
4978            } else {
4979                // Note that we always want to do oom adj to update our state with the
4980                // new number of procs.
4981                mAllowLowerMemLevel = false;
4982                doLowMem = false;
4983            }
4984            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4985            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4986                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4987            handleAppDiedLocked(app, false, true);
4988
4989            if (doOomAdj) {
4990                updateOomAdjLocked();
4991            }
4992            if (doLowMem) {
4993                doLowMemReportIfNeededLocked(app);
4994            }
4995        } else if (app.pid != pid) {
4996            // A new process has already been started.
4997            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4998                    + ") has died and restarted (pid " + app.pid + ").");
4999            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5000        } else if (DEBUG_PROCESSES) {
5001            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5002                    + thread.asBinder());
5003        }
5004    }
5005
5006    /**
5007     * If a stack trace dump file is configured, dump process stack traces.
5008     * @param clearTraces causes the dump file to be erased prior to the new
5009     *    traces being written, if true; when false, the new traces will be
5010     *    appended to any existing file content.
5011     * @param firstPids of dalvik VM processes to dump stack traces for first
5012     * @param lastPids of dalvik VM processes to dump stack traces for last
5013     * @param nativeProcs optional list of native process names to dump stack crawls
5014     * @return file containing stack traces, or null if no dump file is configured
5015     */
5016    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5017            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5018        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5019        if (tracesPath == null || tracesPath.length() == 0) {
5020            return null;
5021        }
5022
5023        File tracesFile = new File(tracesPath);
5024        try {
5025            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5026            tracesFile.createNewFile();
5027            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5028        } catch (IOException e) {
5029            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5030            return null;
5031        }
5032
5033        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5034        return tracesFile;
5035    }
5036
5037    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5038            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5039        // Use a FileObserver to detect when traces finish writing.
5040        // The order of traces is considered important to maintain for legibility.
5041        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5042            @Override
5043            public synchronized void onEvent(int event, String path) { notify(); }
5044        };
5045
5046        try {
5047            observer.startWatching();
5048
5049            // First collect all of the stacks of the most important pids.
5050            if (firstPids != null) {
5051                try {
5052                    int num = firstPids.size();
5053                    for (int i = 0; i < num; i++) {
5054                        synchronized (observer) {
5055                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5056                            observer.wait(200);  // Wait for write-close, give up after 200msec
5057                        }
5058                    }
5059                } catch (InterruptedException e) {
5060                    Slog.wtf(TAG, e);
5061                }
5062            }
5063
5064            // Next collect the stacks of the native pids
5065            if (nativeProcs != null) {
5066                int[] pids = Process.getPidsForCommands(nativeProcs);
5067                if (pids != null) {
5068                    for (int pid : pids) {
5069                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5070                    }
5071                }
5072            }
5073
5074            // Lastly, measure CPU usage.
5075            if (processCpuTracker != null) {
5076                processCpuTracker.init();
5077                System.gc();
5078                processCpuTracker.update();
5079                try {
5080                    synchronized (processCpuTracker) {
5081                        processCpuTracker.wait(500); // measure over 1/2 second.
5082                    }
5083                } catch (InterruptedException e) {
5084                }
5085                processCpuTracker.update();
5086
5087                // We'll take the stack crawls of just the top apps using CPU.
5088                final int N = processCpuTracker.countWorkingStats();
5089                int numProcs = 0;
5090                for (int i=0; i<N && numProcs<5; i++) {
5091                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5092                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5093                        numProcs++;
5094                        try {
5095                            synchronized (observer) {
5096                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5097                                observer.wait(200);  // Wait for write-close, give up after 200msec
5098                            }
5099                        } catch (InterruptedException e) {
5100                            Slog.wtf(TAG, e);
5101                        }
5102
5103                    }
5104                }
5105            }
5106        } finally {
5107            observer.stopWatching();
5108        }
5109    }
5110
5111    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5112        if (true || IS_USER_BUILD) {
5113            return;
5114        }
5115        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5116        if (tracesPath == null || tracesPath.length() == 0) {
5117            return;
5118        }
5119
5120        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5121        StrictMode.allowThreadDiskWrites();
5122        try {
5123            final File tracesFile = new File(tracesPath);
5124            final File tracesDir = tracesFile.getParentFile();
5125            final File tracesTmp = new File(tracesDir, "__tmp__");
5126            try {
5127                if (tracesFile.exists()) {
5128                    tracesTmp.delete();
5129                    tracesFile.renameTo(tracesTmp);
5130                }
5131                StringBuilder sb = new StringBuilder();
5132                Time tobj = new Time();
5133                tobj.set(System.currentTimeMillis());
5134                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5135                sb.append(": ");
5136                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5137                sb.append(" since ");
5138                sb.append(msg);
5139                FileOutputStream fos = new FileOutputStream(tracesFile);
5140                fos.write(sb.toString().getBytes());
5141                if (app == null) {
5142                    fos.write("\n*** No application process!".getBytes());
5143                }
5144                fos.close();
5145                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5146            } catch (IOException e) {
5147                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5148                return;
5149            }
5150
5151            if (app != null) {
5152                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5153                firstPids.add(app.pid);
5154                dumpStackTraces(tracesPath, firstPids, null, null, null);
5155            }
5156
5157            File lastTracesFile = null;
5158            File curTracesFile = null;
5159            for (int i=9; i>=0; i--) {
5160                String name = String.format(Locale.US, "slow%02d.txt", i);
5161                curTracesFile = new File(tracesDir, name);
5162                if (curTracesFile.exists()) {
5163                    if (lastTracesFile != null) {
5164                        curTracesFile.renameTo(lastTracesFile);
5165                    } else {
5166                        curTracesFile.delete();
5167                    }
5168                }
5169                lastTracesFile = curTracesFile;
5170            }
5171            tracesFile.renameTo(curTracesFile);
5172            if (tracesTmp.exists()) {
5173                tracesTmp.renameTo(tracesFile);
5174            }
5175        } finally {
5176            StrictMode.setThreadPolicy(oldPolicy);
5177        }
5178    }
5179
5180    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5181            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5182        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5183        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5184
5185        if (mController != null) {
5186            try {
5187                // 0 == continue, -1 = kill process immediately
5188                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5189                if (res < 0 && app.pid != MY_PID) {
5190                    app.kill("anr", true);
5191                }
5192            } catch (RemoteException e) {
5193                mController = null;
5194                Watchdog.getInstance().setActivityController(null);
5195            }
5196        }
5197
5198        long anrTime = SystemClock.uptimeMillis();
5199        if (MONITOR_CPU_USAGE) {
5200            updateCpuStatsNow();
5201        }
5202
5203        synchronized (this) {
5204            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5205            if (mShuttingDown) {
5206                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5207                return;
5208            } else if (app.notResponding) {
5209                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5210                return;
5211            } else if (app.crashing) {
5212                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5213                return;
5214            }
5215
5216            // In case we come through here for the same app before completing
5217            // this one, mark as anring now so we will bail out.
5218            app.notResponding = true;
5219
5220            // Log the ANR to the event log.
5221            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5222                    app.processName, app.info.flags, annotation);
5223
5224            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5225            firstPids.add(app.pid);
5226
5227            int parentPid = app.pid;
5228            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5229            if (parentPid != app.pid) firstPids.add(parentPid);
5230
5231            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5232
5233            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5234                ProcessRecord r = mLruProcesses.get(i);
5235                if (r != null && r.thread != null) {
5236                    int pid = r.pid;
5237                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5238                        if (r.persistent) {
5239                            firstPids.add(pid);
5240                        } else {
5241                            lastPids.put(pid, Boolean.TRUE);
5242                        }
5243                    }
5244                }
5245            }
5246        }
5247
5248        // Log the ANR to the main log.
5249        StringBuilder info = new StringBuilder();
5250        info.setLength(0);
5251        info.append("ANR in ").append(app.processName);
5252        if (activity != null && activity.shortComponentName != null) {
5253            info.append(" (").append(activity.shortComponentName).append(")");
5254        }
5255        info.append("\n");
5256        info.append("PID: ").append(app.pid).append("\n");
5257        if (annotation != null) {
5258            info.append("Reason: ").append(annotation).append("\n");
5259        }
5260        if (parent != null && parent != activity) {
5261            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5262        }
5263
5264        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5265
5266        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5267                NATIVE_STACKS_OF_INTEREST);
5268
5269        String cpuInfo = null;
5270        if (MONITOR_CPU_USAGE) {
5271            updateCpuStatsNow();
5272            synchronized (mProcessCpuTracker) {
5273                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5274            }
5275            info.append(processCpuTracker.printCurrentLoad());
5276            info.append(cpuInfo);
5277        }
5278
5279        info.append(processCpuTracker.printCurrentState(anrTime));
5280
5281        Slog.e(TAG, info.toString());
5282        if (tracesFile == null) {
5283            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5284            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5285        }
5286
5287        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5288                cpuInfo, tracesFile, null);
5289
5290        if (mController != null) {
5291            try {
5292                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5293                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5294                if (res != 0) {
5295                    if (res < 0 && app.pid != MY_PID) {
5296                        app.kill("anr", true);
5297                    } else {
5298                        synchronized (this) {
5299                            mServices.scheduleServiceTimeoutLocked(app);
5300                        }
5301                    }
5302                    return;
5303                }
5304            } catch (RemoteException e) {
5305                mController = null;
5306                Watchdog.getInstance().setActivityController(null);
5307            }
5308        }
5309
5310        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5311        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5312                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5313
5314        synchronized (this) {
5315            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5316
5317            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5318                app.kill("bg anr", true);
5319                return;
5320            }
5321
5322            // Set the app's notResponding state, and look up the errorReportReceiver
5323            makeAppNotRespondingLocked(app,
5324                    activity != null ? activity.shortComponentName : null,
5325                    annotation != null ? "ANR " + annotation : "ANR",
5326                    info.toString());
5327
5328            // Bring up the infamous App Not Responding dialog
5329            Message msg = Message.obtain();
5330            HashMap<String, Object> map = new HashMap<String, Object>();
5331            msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5332            msg.obj = map;
5333            msg.arg1 = aboveSystem ? 1 : 0;
5334            map.put("app", app);
5335            if (activity != null) {
5336                map.put("activity", activity);
5337            }
5338
5339            mUiHandler.sendMessage(msg);
5340        }
5341    }
5342
5343    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5344        if (!mLaunchWarningShown) {
5345            mLaunchWarningShown = true;
5346            mUiHandler.post(new Runnable() {
5347                @Override
5348                public void run() {
5349                    synchronized (ActivityManagerService.this) {
5350                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5351                        d.show();
5352                        mUiHandler.postDelayed(new Runnable() {
5353                            @Override
5354                            public void run() {
5355                                synchronized (ActivityManagerService.this) {
5356                                    d.dismiss();
5357                                    mLaunchWarningShown = false;
5358                                }
5359                            }
5360                        }, 4000);
5361                    }
5362                }
5363            });
5364        }
5365    }
5366
5367    @Override
5368    public boolean clearApplicationUserData(final String packageName,
5369            final IPackageDataObserver observer, int userId) {
5370        enforceNotIsolatedCaller("clearApplicationUserData");
5371        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5372            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5373        }
5374        int uid = Binder.getCallingUid();
5375        int pid = Binder.getCallingPid();
5376        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5377                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5378        long callingId = Binder.clearCallingIdentity();
5379        try {
5380            IPackageManager pm = AppGlobals.getPackageManager();
5381            int pkgUid = -1;
5382            synchronized(this) {
5383                try {
5384                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5385                } catch (RemoteException e) {
5386                }
5387                if (pkgUid == -1) {
5388                    Slog.w(TAG, "Invalid packageName: " + packageName);
5389                    if (observer != null) {
5390                        try {
5391                            observer.onRemoveCompleted(packageName, false);
5392                        } catch (RemoteException e) {
5393                            Slog.i(TAG, "Observer no longer exists.");
5394                        }
5395                    }
5396                    return false;
5397                }
5398                if (uid == pkgUid || checkComponentPermission(
5399                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5400                        pid, uid, -1, true)
5401                        == PackageManager.PERMISSION_GRANTED) {
5402                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5403                } else {
5404                    throw new SecurityException("PID " + pid + " does not have permission "
5405                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5406                                    + " of package " + packageName);
5407                }
5408
5409                // Remove all tasks match the cleared application package and user
5410                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5411                    final TaskRecord tr = mRecentTasks.get(i);
5412                    final String taskPackageName =
5413                            tr.getBaseIntent().getComponent().getPackageName();
5414                    if (tr.userId != userId) continue;
5415                    if (!taskPackageName.equals(packageName)) continue;
5416                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5417                }
5418            }
5419
5420            try {
5421                // Clear application user data
5422                pm.clearApplicationUserData(packageName, observer, userId);
5423
5424                synchronized(this) {
5425                    // Remove all permissions granted from/to this package
5426                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5427                }
5428
5429                // Remove all zen rules created by this package; revoke it's zen access.
5430                INotificationManager inm = NotificationManager.getService();
5431                inm.removeAutomaticZenRules(packageName);
5432                inm.setNotificationPolicyAccessGranted(packageName, false);
5433
5434                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5435                        Uri.fromParts("package", packageName, null));
5436                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5437                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438                        null, null, 0, null, null, null, null, false, false, userId);
5439            } catch (RemoteException e) {
5440            }
5441        } finally {
5442            Binder.restoreCallingIdentity(callingId);
5443        }
5444        return true;
5445    }
5446
5447    @Override
5448    public void killBackgroundProcesses(final String packageName, int userId) {
5449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5450                != PackageManager.PERMISSION_GRANTED &&
5451                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5452                        != PackageManager.PERMISSION_GRANTED) {
5453            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5454                    + Binder.getCallingPid()
5455                    + ", uid=" + Binder.getCallingUid()
5456                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5457            Slog.w(TAG, msg);
5458            throw new SecurityException(msg);
5459        }
5460
5461        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5462                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5463        long callingId = Binder.clearCallingIdentity();
5464        try {
5465            IPackageManager pm = AppGlobals.getPackageManager();
5466            synchronized(this) {
5467                int appId = -1;
5468                try {
5469                    appId = UserHandle.getAppId(
5470                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5471                } catch (RemoteException e) {
5472                }
5473                if (appId == -1) {
5474                    Slog.w(TAG, "Invalid packageName: " + packageName);
5475                    return;
5476                }
5477                killPackageProcessesLocked(packageName, appId, userId,
5478                        ProcessList.SERVICE_ADJ, false, true, true, false, true, "kill background");
5479            }
5480        } finally {
5481            Binder.restoreCallingIdentity(callingId);
5482        }
5483    }
5484
5485    @Override
5486    public void killAllBackgroundProcesses() {
5487        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5488                != PackageManager.PERMISSION_GRANTED) {
5489            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5490                    + Binder.getCallingPid()
5491                    + ", uid=" + Binder.getCallingUid()
5492                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5493            Slog.w(TAG, msg);
5494            throw new SecurityException(msg);
5495        }
5496
5497        long callingId = Binder.clearCallingIdentity();
5498        try {
5499            synchronized(this) {
5500                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5501                final int NP = mProcessNames.getMap().size();
5502                for (int ip=0; ip<NP; ip++) {
5503                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5504                    final int NA = apps.size();
5505                    for (int ia=0; ia<NA; ia++) {
5506                        ProcessRecord app = apps.valueAt(ia);
5507                        if (app.persistent) {
5508                            // we don't kill persistent processes
5509                            continue;
5510                        }
5511                        if (app.removed) {
5512                            procs.add(app);
5513                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5514                            app.removed = true;
5515                            procs.add(app);
5516                        }
5517                    }
5518                }
5519
5520                int N = procs.size();
5521                for (int i=0; i<N; i++) {
5522                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5523                }
5524                mAllowLowerMemLevel = true;
5525                updateOomAdjLocked();
5526                doLowMemReportIfNeededLocked(null);
5527            }
5528        } finally {
5529            Binder.restoreCallingIdentity(callingId);
5530        }
5531    }
5532
5533    @Override
5534    public void forceStopPackage(final String packageName, int userId) {
5535        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5536                != PackageManager.PERMISSION_GRANTED) {
5537            String msg = "Permission Denial: forceStopPackage() from pid="
5538                    + Binder.getCallingPid()
5539                    + ", uid=" + Binder.getCallingUid()
5540                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5541            Slog.w(TAG, msg);
5542            throw new SecurityException(msg);
5543        }
5544        final int callingPid = Binder.getCallingPid();
5545        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5546                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5547        long callingId = Binder.clearCallingIdentity();
5548        try {
5549            IPackageManager pm = AppGlobals.getPackageManager();
5550            synchronized(this) {
5551                int[] users = userId == UserHandle.USER_ALL
5552                        ? mUserController.getUsers() : new int[] { userId };
5553                for (int user : users) {
5554                    int pkgUid = -1;
5555                    try {
5556                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5557                                user);
5558                    } catch (RemoteException e) {
5559                    }
5560                    if (pkgUid == -1) {
5561                        Slog.w(TAG, "Invalid packageName: " + packageName);
5562                        continue;
5563                    }
5564                    try {
5565                        pm.setPackageStoppedState(packageName, true, user);
5566                    } catch (RemoteException e) {
5567                    } catch (IllegalArgumentException e) {
5568                        Slog.w(TAG, "Failed trying to unstop package "
5569                                + packageName + ": " + e);
5570                    }
5571                    if (mUserController.isUserRunningLocked(user, 0)) {
5572                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5573                    }
5574                }
5575            }
5576        } finally {
5577            Binder.restoreCallingIdentity(callingId);
5578        }
5579    }
5580
5581    @Override
5582    public void addPackageDependency(String packageName) {
5583        synchronized (this) {
5584            int callingPid = Binder.getCallingPid();
5585            if (callingPid == Process.myPid()) {
5586                //  Yeah, um, no.
5587                return;
5588            }
5589            ProcessRecord proc;
5590            synchronized (mPidsSelfLocked) {
5591                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5592            }
5593            if (proc != null) {
5594                if (proc.pkgDeps == null) {
5595                    proc.pkgDeps = new ArraySet<String>(1);
5596                }
5597                proc.pkgDeps.add(packageName);
5598            }
5599        }
5600    }
5601
5602    /*
5603     * The pkg name and app id have to be specified.
5604     */
5605    @Override
5606    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5607        if (pkg == null) {
5608            return;
5609        }
5610        // Make sure the uid is valid.
5611        if (appid < 0) {
5612            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5613            return;
5614        }
5615        int callerUid = Binder.getCallingUid();
5616        // Only the system server can kill an application
5617        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5618            // Post an aysnc message to kill the application
5619            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5620            msg.arg1 = appid;
5621            msg.arg2 = 0;
5622            Bundle bundle = new Bundle();
5623            bundle.putString("pkg", pkg);
5624            bundle.putString("reason", reason);
5625            msg.obj = bundle;
5626            mHandler.sendMessage(msg);
5627        } else {
5628            throw new SecurityException(callerUid + " cannot kill pkg: " +
5629                    pkg);
5630        }
5631    }
5632
5633    @Override
5634    public void closeSystemDialogs(String reason) {
5635        enforceNotIsolatedCaller("closeSystemDialogs");
5636
5637        final int pid = Binder.getCallingPid();
5638        final int uid = Binder.getCallingUid();
5639        final long origId = Binder.clearCallingIdentity();
5640        try {
5641            synchronized (this) {
5642                // Only allow this from foreground processes, so that background
5643                // applications can't abuse it to prevent system UI from being shown.
5644                if (uid >= Process.FIRST_APPLICATION_UID) {
5645                    ProcessRecord proc;
5646                    synchronized (mPidsSelfLocked) {
5647                        proc = mPidsSelfLocked.get(pid);
5648                    }
5649                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5650                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5651                                + " from background process " + proc);
5652                        return;
5653                    }
5654                }
5655                closeSystemDialogsLocked(reason);
5656            }
5657        } finally {
5658            Binder.restoreCallingIdentity(origId);
5659        }
5660    }
5661
5662    void closeSystemDialogsLocked(String reason) {
5663        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5664        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5665                | Intent.FLAG_RECEIVER_FOREGROUND);
5666        if (reason != null) {
5667            intent.putExtra("reason", reason);
5668        }
5669        mWindowManager.closeSystemDialogs(reason);
5670
5671        mStackSupervisor.closeSystemDialogsLocked();
5672
5673        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5674                AppOpsManager.OP_NONE, null, false, false,
5675                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5676    }
5677
5678    @Override
5679    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5680        enforceNotIsolatedCaller("getProcessMemoryInfo");
5681        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5682        for (int i=pids.length-1; i>=0; i--) {
5683            ProcessRecord proc;
5684            int oomAdj;
5685            synchronized (this) {
5686                synchronized (mPidsSelfLocked) {
5687                    proc = mPidsSelfLocked.get(pids[i]);
5688                    oomAdj = proc != null ? proc.setAdj : 0;
5689                }
5690            }
5691            infos[i] = new Debug.MemoryInfo();
5692            Debug.getMemoryInfo(pids[i], infos[i]);
5693            if (proc != null) {
5694                synchronized (this) {
5695                    if (proc.thread != null && proc.setAdj == oomAdj) {
5696                        // Record this for posterity if the process has been stable.
5697                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5698                                infos[i].getTotalUss(), false, proc.pkgList);
5699                    }
5700                }
5701            }
5702        }
5703        return infos;
5704    }
5705
5706    @Override
5707    public long[] getProcessPss(int[] pids) {
5708        enforceNotIsolatedCaller("getProcessPss");
5709        long[] pss = new long[pids.length];
5710        for (int i=pids.length-1; i>=0; i--) {
5711            ProcessRecord proc;
5712            int oomAdj;
5713            synchronized (this) {
5714                synchronized (mPidsSelfLocked) {
5715                    proc = mPidsSelfLocked.get(pids[i]);
5716                    oomAdj = proc != null ? proc.setAdj : 0;
5717                }
5718            }
5719            long[] tmpUss = new long[1];
5720            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5721            if (proc != null) {
5722                synchronized (this) {
5723                    if (proc.thread != null && proc.setAdj == oomAdj) {
5724                        // Record this for posterity if the process has been stable.
5725                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5726                    }
5727                }
5728            }
5729        }
5730        return pss;
5731    }
5732
5733    @Override
5734    public void killApplicationProcess(String processName, int uid) {
5735        if (processName == null) {
5736            return;
5737        }
5738
5739        int callerUid = Binder.getCallingUid();
5740        // Only the system server can kill an application
5741        if (callerUid == Process.SYSTEM_UID) {
5742            synchronized (this) {
5743                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5744                if (app != null && app.thread != null) {
5745                    try {
5746                        app.thread.scheduleSuicide();
5747                    } catch (RemoteException e) {
5748                        // If the other end already died, then our work here is done.
5749                    }
5750                } else {
5751                    Slog.w(TAG, "Process/uid not found attempting kill of "
5752                            + processName + " / " + uid);
5753                }
5754            }
5755        } else {
5756            throw new SecurityException(callerUid + " cannot kill app process: " +
5757                    processName);
5758        }
5759    }
5760
5761    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5762        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5763                false, true, false, false, UserHandle.getUserId(uid), reason);
5764        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5765                Uri.fromParts("package", packageName, null));
5766        if (!mProcessesReady) {
5767            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5768                    | Intent.FLAG_RECEIVER_FOREGROUND);
5769        }
5770        intent.putExtra(Intent.EXTRA_UID, uid);
5771        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5772        broadcastIntentLocked(null, null, intent,
5773                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5774                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5775    }
5776
5777
5778    private final boolean killPackageProcessesLocked(String packageName, int appId,
5779            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5780            boolean doit, boolean evenPersistent, boolean killPackageApp, String reason) {
5781        ArrayList<ProcessRecord> procs = new ArrayList<>();
5782
5783        // Remove all processes this package may have touched: all with the
5784        // same UID (except for the system or root user), and all whose name
5785        // matches the package name.
5786        final int NP = mProcessNames.getMap().size();
5787        for (int ip=0; ip<NP; ip++) {
5788            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5789            final int NA = apps.size();
5790            for (int ia=0; ia<NA; ia++) {
5791                ProcessRecord app = apps.valueAt(ia);
5792                if (app.persistent && !evenPersistent) {
5793                    // we don't kill persistent processes
5794                    continue;
5795                }
5796                if (app.removed) {
5797                    if (doit) {
5798                        procs.add(app);
5799                    }
5800                    continue;
5801                }
5802
5803                // Skip process if it doesn't meet our oom adj requirement.
5804                if (app.setAdj < minOomAdj) {
5805                    continue;
5806                }
5807
5808                // If no package is specified, we call all processes under the
5809                // give user id.
5810                if (packageName == null) {
5811                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5812                        continue;
5813                    }
5814                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5815                        continue;
5816                    }
5817                // Package has been specified, we want to hit all processes
5818                // that match it.  We need to qualify this by the processes
5819                // that are running under the specified app and user ID.
5820                } else {
5821                    final boolean isDep = app.pkgDeps != null
5822                            && app.pkgDeps.contains(packageName);
5823                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5824                        continue;
5825                    }
5826                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5827                        continue;
5828                    }
5829                    if ((!killPackageApp || !app.pkgList.containsKey(packageName)) && !isDep) {
5830                        continue;
5831                    }
5832                }
5833
5834                // Process has passed all conditions, kill it!
5835                if (!doit) {
5836                    return true;
5837                }
5838                app.removed = true;
5839                procs.add(app);
5840            }
5841        }
5842
5843        int N = procs.size();
5844        for (int i=0; i<N; i++) {
5845            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5846        }
5847        updateOomAdjLocked();
5848        return N > 0;
5849    }
5850
5851    private void cleanupDisabledPackageComponentsLocked(
5852            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5853
5854        Set<String> disabledClasses = null;
5855        boolean packageDisabled = false;
5856        IPackageManager pm = AppGlobals.getPackageManager();
5857
5858        if (changedClasses == null) {
5859            // Nothing changed...
5860            return;
5861        }
5862
5863        // Determine enable/disable state of the package and its components.
5864        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5865        for (int i = changedClasses.length - 1; i >= 0; i--) {
5866            final String changedClass = changedClasses[i];
5867
5868            if (changedClass.equals(packageName)) {
5869                try {
5870                    // Entire package setting changed
5871                    enabled = pm.getApplicationEnabledSetting(packageName,
5872                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5873                } catch (Exception e) {
5874                    // No such package/component; probably racing with uninstall.  In any
5875                    // event it means we have nothing further to do here.
5876                    return;
5877                }
5878                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5879                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5880                if (packageDisabled) {
5881                    // Entire package is disabled.
5882                    // No need to continue to check component states.
5883                    disabledClasses = null;
5884                    break;
5885                }
5886            } else {
5887                try {
5888                    enabled = pm.getComponentEnabledSetting(
5889                            new ComponentName(packageName, changedClass),
5890                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5891                } catch (Exception e) {
5892                    // As above, probably racing with uninstall.
5893                    return;
5894                }
5895                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5896                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5897                    if (disabledClasses == null) {
5898                        disabledClasses = new ArraySet<>(changedClasses.length);
5899                    }
5900                    disabledClasses.add(changedClass);
5901                }
5902            }
5903        }
5904
5905        if (!packageDisabled && disabledClasses == null) {
5906            // Nothing to do here...
5907            return;
5908        }
5909
5910        // Clean-up disabled activities.
5911        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5912                packageName, disabledClasses, true, false, userId) && mBooted) {
5913            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5914            mStackSupervisor.scheduleIdleLocked();
5915        }
5916
5917        // Clean-up disabled tasks
5918        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5919
5920        // Clean-up disabled services.
5921        mServices.bringDownDisabledPackageServicesLocked(
5922                packageName, disabledClasses, userId, false, killProcess, true);
5923
5924        // Clean-up disabled providers.
5925        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5926        mProviderMap.collectPackageProvidersLocked(
5927                packageName, disabledClasses, true, false, userId, providers);
5928        for (int i = providers.size() - 1; i >= 0; i--) {
5929            removeDyingProviderLocked(null, providers.get(i), true);
5930        }
5931
5932        // Clean-up disabled broadcast receivers.
5933        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5934            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5935                    packageName, disabledClasses, userId, true);
5936        }
5937
5938    }
5939
5940    final boolean forceStopPackageLocked(String packageName, int appId,
5941            boolean callerWillRestart, boolean purgeCache, boolean doit,
5942            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5943        int i;
5944
5945        if (userId == UserHandle.USER_ALL && packageName == null) {
5946            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5947        }
5948
5949        if (appId < 0 && packageName != null) {
5950            try {
5951                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5952                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5953            } catch (RemoteException e) {
5954            }
5955        }
5956
5957        if (doit) {
5958            if (packageName != null) {
5959                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5960                        + " user=" + userId + ": " + reason);
5961            } else {
5962                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5963            }
5964
5965            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5966            for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5967                SparseArray<Long> ba = pmap.valueAt(ip);
5968                for (i = ba.size() - 1; i >= 0; i--) {
5969                    boolean remove = false;
5970                    final int entUid = ba.keyAt(i);
5971                    if (packageName != null) {
5972                        if (userId == UserHandle.USER_ALL) {
5973                            if (UserHandle.getAppId(entUid) == appId) {
5974                                remove = true;
5975                            }
5976                        } else {
5977                            if (entUid == UserHandle.getUid(userId, appId)) {
5978                                remove = true;
5979                            }
5980                        }
5981                    } else if (UserHandle.getUserId(entUid) == userId) {
5982                        remove = true;
5983                    }
5984                    if (remove) {
5985                        ba.removeAt(i);
5986                    }
5987                }
5988                if (ba.size() == 0) {
5989                    pmap.removeAt(ip);
5990                }
5991            }
5992        }
5993
5994        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5995                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, true,
5996                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5997
5998        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5999                packageName, null, doit, evenPersistent, userId)) {
6000            if (!doit) {
6001                return true;
6002            }
6003            didSomething = true;
6004        }
6005
6006        if (mServices.bringDownDisabledPackageServicesLocked(
6007                packageName, null, userId, evenPersistent, true, doit)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013
6014        if (packageName == null) {
6015            // Remove all sticky broadcasts from this user.
6016            mStickyBroadcasts.remove(userId);
6017        }
6018
6019        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6020        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6021                userId, providers)) {
6022            if (!doit) {
6023                return true;
6024            }
6025            didSomething = true;
6026        }
6027        for (i = providers.size() - 1; i >= 0; i--) {
6028            removeDyingProviderLocked(null, providers.get(i), true);
6029        }
6030
6031        // Remove transient permissions granted from/to this package/user
6032        removeUriPermissionsForPackageLocked(packageName, userId, false);
6033
6034        if (doit) {
6035            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6036                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6037                        packageName, null, userId, doit);
6038            }
6039        }
6040
6041        if (packageName == null || uninstalling) {
6042            // Remove pending intents.  For now we only do this when force
6043            // stopping users, because we have some problems when doing this
6044            // for packages -- app widgets are not currently cleaned up for
6045            // such packages, so they can be left with bad pending intents.
6046            if (mIntentSenderRecords.size() > 0) {
6047                Iterator<WeakReference<PendingIntentRecord>> it
6048                        = mIntentSenderRecords.values().iterator();
6049                while (it.hasNext()) {
6050                    WeakReference<PendingIntentRecord> wpir = it.next();
6051                    if (wpir == null) {
6052                        it.remove();
6053                        continue;
6054                    }
6055                    PendingIntentRecord pir = wpir.get();
6056                    if (pir == null) {
6057                        it.remove();
6058                        continue;
6059                    }
6060                    if (packageName == null) {
6061                        // Stopping user, remove all objects for the user.
6062                        if (pir.key.userId != userId) {
6063                            // Not the same user, skip it.
6064                            continue;
6065                        }
6066                    } else {
6067                        if (UserHandle.getAppId(pir.uid) != appId) {
6068                            // Different app id, skip it.
6069                            continue;
6070                        }
6071                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6072                            // Different user, skip it.
6073                            continue;
6074                        }
6075                        if (!pir.key.packageName.equals(packageName)) {
6076                            // Different package, skip it.
6077                            continue;
6078                        }
6079                    }
6080                    if (!doit) {
6081                        return true;
6082                    }
6083                    didSomething = true;
6084                    it.remove();
6085                    pir.canceled = true;
6086                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6087                        pir.key.activity.pendingResults.remove(pir.ref);
6088                    }
6089                }
6090            }
6091        }
6092
6093        if (doit) {
6094            if (purgeCache && packageName != null) {
6095                AttributeCache ac = AttributeCache.instance();
6096                if (ac != null) {
6097                    ac.removePackage(packageName);
6098                }
6099            }
6100            if (mBooted) {
6101                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6102                mStackSupervisor.scheduleIdleLocked();
6103            }
6104        }
6105
6106        return didSomething;
6107    }
6108
6109    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6110        ProcessRecord old = mProcessNames.remove(name, uid);
6111        if (old != null) {
6112            old.uidRecord.numProcs--;
6113            if (old.uidRecord.numProcs == 0) {
6114                // No more processes using this uid, tell clients it is gone.
6115                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6116                        "No more processes in " + old.uidRecord);
6117                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6118                mActiveUids.remove(uid);
6119                mBatteryStatsService.noteUidProcessState(uid,
6120                        ActivityManager.PROCESS_STATE_NONEXISTENT);
6121            }
6122            old.uidRecord = null;
6123        }
6124        mIsolatedProcesses.remove(uid);
6125        return old;
6126    }
6127
6128    private final void addProcessNameLocked(ProcessRecord proc) {
6129        // We shouldn't already have a process under this name, but just in case we
6130        // need to clean up whatever may be there now.
6131        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6132        if (old == proc && proc.persistent) {
6133            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6134            Slog.w(TAG, "Re-adding persistent process " + proc);
6135        } else if (old != null) {
6136            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6137        }
6138        UidRecord uidRec = mActiveUids.get(proc.uid);
6139        if (uidRec == null) {
6140            uidRec = new UidRecord(proc.uid);
6141            // This is the first appearance of the uid, report it now!
6142            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6143                    "Creating new process uid: " + uidRec);
6144            mActiveUids.put(proc.uid, uidRec);
6145            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6146            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6147        }
6148        proc.uidRecord = uidRec;
6149        uidRec.numProcs++;
6150        mProcessNames.put(proc.processName, proc.uid, proc);
6151        if (proc.isolated) {
6152            mIsolatedProcesses.put(proc.uid, proc);
6153        }
6154    }
6155
6156    private final boolean removeProcessLocked(ProcessRecord app,
6157            boolean callerWillRestart, boolean allowRestart, String reason) {
6158        final String name = app.processName;
6159        final int uid = app.uid;
6160        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6161            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6162
6163        removeProcessNameLocked(name, uid);
6164        if (mHeavyWeightProcess == app) {
6165            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6166                    mHeavyWeightProcess.userId, 0));
6167            mHeavyWeightProcess = null;
6168        }
6169        boolean needRestart = false;
6170        if (app.pid > 0 && app.pid != MY_PID) {
6171            int pid = app.pid;
6172            synchronized (mPidsSelfLocked) {
6173                mPidsSelfLocked.remove(pid);
6174                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6175            }
6176            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6177            if (app.isolated) {
6178                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6179            }
6180            boolean willRestart = false;
6181            if (app.persistent && !app.isolated) {
6182                if (!callerWillRestart) {
6183                    willRestart = true;
6184                } else {
6185                    needRestart = true;
6186                }
6187            }
6188            app.kill(reason, true);
6189            handleAppDiedLocked(app, willRestart, allowRestart);
6190            if (willRestart) {
6191                removeLruProcessLocked(app);
6192                addAppLocked(app.info, false, null /* ABI override */);
6193            }
6194        } else {
6195            mRemovedProcesses.add(app);
6196        }
6197
6198        return needRestart;
6199    }
6200
6201    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6202        cleanupAppInLaunchingProvidersLocked(app, true);
6203        removeProcessLocked(app, false, true, "timeout publishing content providers");
6204    }
6205
6206    private final void processStartTimedOutLocked(ProcessRecord app) {
6207        final int pid = app.pid;
6208        boolean gone = false;
6209        synchronized (mPidsSelfLocked) {
6210            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6211            if (knownApp != null && knownApp.thread == null) {
6212                mPidsSelfLocked.remove(pid);
6213                gone = true;
6214            }
6215        }
6216
6217        if (gone) {
6218            Slog.w(TAG, "Process " + app + " failed to attach");
6219            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6220                    pid, app.uid, app.processName);
6221            removeProcessNameLocked(app.processName, app.uid);
6222            if (mHeavyWeightProcess == app) {
6223                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6224                        mHeavyWeightProcess.userId, 0));
6225                mHeavyWeightProcess = null;
6226            }
6227            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6228            if (app.isolated) {
6229                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6230            }
6231            // Take care of any launching providers waiting for this process.
6232            cleanupAppInLaunchingProvidersLocked(app, true);
6233            // Take care of any services that are waiting for the process.
6234            mServices.processStartTimedOutLocked(app);
6235            app.kill("start timeout", true);
6236            removeLruProcessLocked(app);
6237            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6238                Slog.w(TAG, "Unattached app died before backup, skipping");
6239                try {
6240                    IBackupManager bm = IBackupManager.Stub.asInterface(
6241                            ServiceManager.getService(Context.BACKUP_SERVICE));
6242                    bm.agentDisconnected(app.info.packageName);
6243                } catch (RemoteException e) {
6244                    // Can't happen; the backup manager is local
6245                }
6246            }
6247            if (isPendingBroadcastProcessLocked(pid)) {
6248                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6249                skipPendingBroadcastLocked(pid);
6250            }
6251        } else {
6252            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6253        }
6254    }
6255
6256    private final boolean attachApplicationLocked(IApplicationThread thread,
6257            int pid) {
6258
6259        // Find the application record that is being attached...  either via
6260        // the pid if we are running in multiple processes, or just pull the
6261        // next app record if we are emulating process with anonymous threads.
6262        ProcessRecord app;
6263        if (pid != MY_PID && pid >= 0) {
6264            synchronized (mPidsSelfLocked) {
6265                app = mPidsSelfLocked.get(pid);
6266            }
6267        } else {
6268            app = null;
6269        }
6270
6271        if (app == null) {
6272            Slog.w(TAG, "No pending application record for pid " + pid
6273                    + " (IApplicationThread " + thread + "); dropping process");
6274            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6275            if (pid > 0 && pid != MY_PID) {
6276                Process.killProcessQuiet(pid);
6277                //TODO: killProcessGroup(app.info.uid, pid);
6278            } else {
6279                try {
6280                    thread.scheduleExit();
6281                } catch (Exception e) {
6282                    // Ignore exceptions.
6283                }
6284            }
6285            return false;
6286        }
6287
6288        // If this application record is still attached to a previous
6289        // process, clean it up now.
6290        if (app.thread != null) {
6291            handleAppDiedLocked(app, true, true);
6292        }
6293
6294        // Tell the process all about itself.
6295
6296        if (DEBUG_ALL) Slog.v(
6297                TAG, "Binding process pid " + pid + " to record " + app);
6298
6299        final String processName = app.processName;
6300        try {
6301            AppDeathRecipient adr = new AppDeathRecipient(
6302                    app, pid, thread);
6303            thread.asBinder().linkToDeath(adr, 0);
6304            app.deathRecipient = adr;
6305        } catch (RemoteException e) {
6306            app.resetPackageList(mProcessStats);
6307            startProcessLocked(app, "link fail", processName);
6308            return false;
6309        }
6310
6311        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6312
6313        app.makeActive(thread, mProcessStats);
6314        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6315        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6316        app.forcingToForeground = null;
6317        updateProcessForegroundLocked(app, false, false);
6318        app.hasShownUi = false;
6319        app.debugging = false;
6320        app.cached = false;
6321        app.killedByAm = false;
6322
6323        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6324
6325        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6326        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6327
6328        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6329            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6330            msg.obj = app;
6331            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6332        }
6333
6334        if (!normalMode) {
6335            Slog.i(TAG, "Launching preboot mode app: " + app);
6336        }
6337
6338        if (DEBUG_ALL) Slog.v(
6339            TAG, "New app record " + app
6340            + " thread=" + thread.asBinder() + " pid=" + pid);
6341        try {
6342            int testMode = IApplicationThread.DEBUG_OFF;
6343            if (mDebugApp != null && mDebugApp.equals(processName)) {
6344                testMode = mWaitForDebugger
6345                    ? IApplicationThread.DEBUG_WAIT
6346                    : IApplicationThread.DEBUG_ON;
6347                app.debugging = true;
6348                if (mDebugTransient) {
6349                    mDebugApp = mOrigDebugApp;
6350                    mWaitForDebugger = mOrigWaitForDebugger;
6351                }
6352            }
6353            String profileFile = app.instrumentationProfileFile;
6354            ParcelFileDescriptor profileFd = null;
6355            int samplingInterval = 0;
6356            boolean profileAutoStop = false;
6357            if (mProfileApp != null && mProfileApp.equals(processName)) {
6358                mProfileProc = app;
6359                profileFile = mProfileFile;
6360                profileFd = mProfileFd;
6361                samplingInterval = mSamplingInterval;
6362                profileAutoStop = mAutoStopProfiler;
6363            }
6364            boolean enableTrackAllocation = false;
6365            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6366                enableTrackAllocation = true;
6367                mTrackAllocationApp = null;
6368            }
6369
6370            // If the app is being launched for restore or full backup, set it up specially
6371            boolean isRestrictedBackupMode = false;
6372            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6373                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6374                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6375                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6376            }
6377
6378            notifyPackageUse(app.instrumentationInfo != null
6379                    ? app.instrumentationInfo.packageName
6380                    : app.info.packageName);
6381            if (app.instrumentationClass != null) {
6382                notifyPackageUse(app.instrumentationClass.getPackageName());
6383            }
6384            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6385                    + processName + " with config " + mConfiguration);
6386            ApplicationInfo appInfo = app.instrumentationInfo != null
6387                    ? app.instrumentationInfo : app.info;
6388            app.compat = compatibilityInfoForPackageLocked(appInfo);
6389            if (profileFd != null) {
6390                profileFd = profileFd.dup();
6391            }
6392            ProfilerInfo profilerInfo = profileFile == null ? null
6393                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6394            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6395                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6396                    app.instrumentationUiAutomationConnection, testMode,
6397                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6398                    isRestrictedBackupMode || !normalMode, app.persistent,
6399                    new Configuration(mConfiguration), app.compat,
6400                    getCommonServicesLocked(app.isolated),
6401                    mCoreSettingsObserver.getCoreSettingsLocked());
6402            updateLruProcessLocked(app, false, null);
6403            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6404        } catch (Exception e) {
6405            // todo: Yikes!  What should we do?  For now we will try to
6406            // start another process, but that could easily get us in
6407            // an infinite loop of restarting processes...
6408            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6409
6410            app.resetPackageList(mProcessStats);
6411            app.unlinkDeathRecipient();
6412            startProcessLocked(app, "bind fail", processName);
6413            return false;
6414        }
6415
6416        // Remove this record from the list of starting applications.
6417        mPersistentStartingProcesses.remove(app);
6418        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6419                "Attach application locked removing on hold: " + app);
6420        mProcessesOnHold.remove(app);
6421
6422        boolean badApp = false;
6423        boolean didSomething = false;
6424
6425        // See if the top visible activity is waiting to run in this process...
6426        if (normalMode) {
6427            try {
6428                if (mStackSupervisor.attachApplicationLocked(app)) {
6429                    didSomething = true;
6430                }
6431            } catch (Exception e) {
6432                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6433                badApp = true;
6434            }
6435        }
6436
6437        // Find any services that should be running in this process...
6438        if (!badApp) {
6439            try {
6440                didSomething |= mServices.attachApplicationLocked(app, processName);
6441            } catch (Exception e) {
6442                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6443                badApp = true;
6444            }
6445        }
6446
6447        // Check if a next-broadcast receiver is in this process...
6448        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6449            try {
6450                didSomething |= sendPendingBroadcastsLocked(app);
6451            } catch (Exception e) {
6452                // If the app died trying to launch the receiver we declare it 'bad'
6453                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6454                badApp = true;
6455            }
6456        }
6457
6458        // Check whether the next backup agent is in this process...
6459        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6460            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6461                    "New app is backup target, launching agent for " + app);
6462            notifyPackageUse(mBackupTarget.appInfo.packageName);
6463            try {
6464                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6465                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6466                        mBackupTarget.backupMode);
6467            } catch (Exception e) {
6468                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6469                badApp = true;
6470            }
6471        }
6472
6473        if (badApp) {
6474            app.kill("error during init", true);
6475            handleAppDiedLocked(app, false, true);
6476            return false;
6477        }
6478
6479        if (!didSomething) {
6480            updateOomAdjLocked();
6481        }
6482
6483        return true;
6484    }
6485
6486    @Override
6487    public final void attachApplication(IApplicationThread thread) {
6488        synchronized (this) {
6489            int callingPid = Binder.getCallingPid();
6490            final long origId = Binder.clearCallingIdentity();
6491            attachApplicationLocked(thread, callingPid);
6492            Binder.restoreCallingIdentity(origId);
6493        }
6494    }
6495
6496    @Override
6497    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6498        final long origId = Binder.clearCallingIdentity();
6499        synchronized (this) {
6500            ActivityStack stack = ActivityRecord.getStackLocked(token);
6501            if (stack != null) {
6502                ActivityRecord r =
6503                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6504                if (stopProfiling) {
6505                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6506                        try {
6507                            mProfileFd.close();
6508                        } catch (IOException e) {
6509                        }
6510                        clearProfilerLocked();
6511                    }
6512                }
6513            }
6514        }
6515        Binder.restoreCallingIdentity(origId);
6516    }
6517
6518    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6519        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6520                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6521    }
6522
6523    void enableScreenAfterBoot() {
6524        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6525                SystemClock.uptimeMillis());
6526        mWindowManager.enableScreenAfterBoot();
6527
6528        synchronized (this) {
6529            updateEventDispatchingLocked();
6530        }
6531    }
6532
6533    @Override
6534    public void showBootMessage(final CharSequence msg, final boolean always) {
6535        if (Binder.getCallingUid() != Process.myUid()) {
6536            // These days only the core system can call this, so apps can't get in
6537            // the way of what we show about running them.
6538        }
6539        mWindowManager.showBootMessage(msg, always);
6540    }
6541
6542    @Override
6543    public void keyguardWaitingForActivityDrawn() {
6544        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6545        final long token = Binder.clearCallingIdentity();
6546        try {
6547            synchronized (this) {
6548                if (DEBUG_LOCKSCREEN) logLockScreen("");
6549                mWindowManager.keyguardWaitingForActivityDrawn();
6550                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6551                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6552                    updateSleepIfNeededLocked();
6553                }
6554            }
6555        } finally {
6556            Binder.restoreCallingIdentity(token);
6557        }
6558    }
6559
6560    @Override
6561    public void keyguardGoingAway(boolean disableWindowAnimations,
6562            boolean keyguardGoingToNotificationShade) {
6563        enforceNotIsolatedCaller("keyguardGoingAway");
6564        final long token = Binder.clearCallingIdentity();
6565        try {
6566            synchronized (this) {
6567                if (DEBUG_LOCKSCREEN) logLockScreen("");
6568                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6569                        keyguardGoingToNotificationShade);
6570                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6571                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6572                    updateSleepIfNeededLocked();
6573                }
6574            }
6575        } finally {
6576            Binder.restoreCallingIdentity(token);
6577        }
6578    }
6579
6580    final void finishBooting() {
6581        synchronized (this) {
6582            if (!mBootAnimationComplete) {
6583                mCallFinishBooting = true;
6584                return;
6585            }
6586            mCallFinishBooting = false;
6587        }
6588
6589        ArraySet<String> completedIsas = new ArraySet<String>();
6590        for (String abi : Build.SUPPORTED_ABIS) {
6591            Process.establishZygoteConnectionForAbi(abi);
6592            final String instructionSet = VMRuntime.getInstructionSet(abi);
6593            if (!completedIsas.contains(instructionSet)) {
6594                try {
6595                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6596                } catch (InstallerException e) {
6597                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6598                }
6599                completedIsas.add(instructionSet);
6600            }
6601        }
6602
6603        IntentFilter pkgFilter = new IntentFilter();
6604        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6605        pkgFilter.addDataScheme("package");
6606        mContext.registerReceiver(new BroadcastReceiver() {
6607            @Override
6608            public void onReceive(Context context, Intent intent) {
6609                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6610                if (pkgs != null) {
6611                    for (String pkg : pkgs) {
6612                        synchronized (ActivityManagerService.this) {
6613                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6614                                    0, "query restart")) {
6615                                setResultCode(Activity.RESULT_OK);
6616                                return;
6617                            }
6618                        }
6619                    }
6620                }
6621            }
6622        }, pkgFilter);
6623
6624        IntentFilter dumpheapFilter = new IntentFilter();
6625        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6626        mContext.registerReceiver(new BroadcastReceiver() {
6627            @Override
6628            public void onReceive(Context context, Intent intent) {
6629                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6630                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6631                } else {
6632                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6633                }
6634            }
6635        }, dumpheapFilter);
6636
6637        // Let system services know.
6638        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6639
6640        synchronized (this) {
6641            // Ensure that any processes we had put on hold are now started
6642            // up.
6643            final int NP = mProcessesOnHold.size();
6644            if (NP > 0) {
6645                ArrayList<ProcessRecord> procs =
6646                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6647                for (int ip=0; ip<NP; ip++) {
6648                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6649                            + procs.get(ip));
6650                    startProcessLocked(procs.get(ip), "on-hold", null);
6651                }
6652            }
6653
6654            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6655                // Start looking for apps that are abusing wake locks.
6656                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6657                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6658                // Tell anyone interested that we are done booting!
6659                SystemProperties.set("sys.boot_completed", "1");
6660
6661                // And trigger dev.bootcomplete if we are not showing encryption progress
6662                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6663                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6664                    SystemProperties.set("dev.bootcomplete", "1");
6665                }
6666                mUserController.sendBootCompletedLocked(
6667                        new IIntentReceiver.Stub() {
6668                            @Override
6669                            public void performReceive(Intent intent, int resultCode,
6670                                    String data, Bundle extras, boolean ordered,
6671                                    boolean sticky, int sendingUser) {
6672                                synchronized (ActivityManagerService.this) {
6673                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6674                                            true, false);
6675                                }
6676                            }
6677                        });
6678                scheduleStartProfilesLocked();
6679            }
6680        }
6681    }
6682
6683    @Override
6684    public void bootAnimationComplete() {
6685        final boolean callFinishBooting;
6686        synchronized (this) {
6687            callFinishBooting = mCallFinishBooting;
6688            mBootAnimationComplete = true;
6689        }
6690        if (callFinishBooting) {
6691            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6692            finishBooting();
6693            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6694        }
6695    }
6696
6697    final void ensureBootCompleted() {
6698        boolean booting;
6699        boolean enableScreen;
6700        synchronized (this) {
6701            booting = mBooting;
6702            mBooting = false;
6703            enableScreen = !mBooted;
6704            mBooted = true;
6705        }
6706
6707        if (booting) {
6708            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6709            finishBooting();
6710            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6711        }
6712
6713        if (enableScreen) {
6714            enableScreenAfterBoot();
6715        }
6716    }
6717
6718    @Override
6719    public final void activityResumed(IBinder token) {
6720        final long origId = Binder.clearCallingIdentity();
6721        synchronized(this) {
6722            ActivityStack stack = ActivityRecord.getStackLocked(token);
6723            if (stack != null) {
6724                ActivityRecord.activityResumedLocked(token);
6725            }
6726        }
6727        Binder.restoreCallingIdentity(origId);
6728    }
6729
6730    @Override
6731    public final void activityPaused(IBinder token) {
6732        final long origId = Binder.clearCallingIdentity();
6733        synchronized(this) {
6734            ActivityStack stack = ActivityRecord.getStackLocked(token);
6735            if (stack != null) {
6736                stack.activityPausedLocked(token, false);
6737            }
6738        }
6739        Binder.restoreCallingIdentity(origId);
6740    }
6741
6742    @Override
6743    public final void activityStopped(IBinder token, Bundle icicle,
6744            PersistableBundle persistentState, CharSequence description) {
6745        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6746
6747        // Refuse possible leaked file descriptors
6748        if (icicle != null && icicle.hasFileDescriptors()) {
6749            throw new IllegalArgumentException("File descriptors passed in Bundle");
6750        }
6751
6752        final long origId = Binder.clearCallingIdentity();
6753
6754        synchronized (this) {
6755            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6756            if (r != null) {
6757                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6758            }
6759        }
6760
6761        trimApplications();
6762
6763        Binder.restoreCallingIdentity(origId);
6764    }
6765
6766    @Override
6767    public final void activityDestroyed(IBinder token) {
6768        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6769        synchronized (this) {
6770            ActivityStack stack = ActivityRecord.getStackLocked(token);
6771            if (stack != null) {
6772                stack.activityDestroyedLocked(token, "activityDestroyed");
6773            }
6774        }
6775    }
6776
6777    @Override
6778    public final void activityRelaunched(IBinder token) {
6779        final long origId = Binder.clearCallingIdentity();
6780        synchronized (this) {
6781            mStackSupervisor.activityRelaunchedLocked(token);
6782        }
6783        Binder.restoreCallingIdentity(origId);
6784    }
6785
6786    @Override
6787    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6788            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6789        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6790                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6791        synchronized (this) {
6792            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6793            if (record == null) {
6794                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6795                        + "found for: " + token);
6796            }
6797            record.setSizeConfigurations(horizontalSizeConfiguration,
6798                    verticalSizeConfigurations, smallestSizeConfigurations);
6799        }
6800    }
6801
6802    @Override
6803    public final void backgroundResourcesReleased(IBinder token) {
6804        final long origId = Binder.clearCallingIdentity();
6805        try {
6806            synchronized (this) {
6807                ActivityStack stack = ActivityRecord.getStackLocked(token);
6808                if (stack != null) {
6809                    stack.backgroundResourcesReleased();
6810                }
6811            }
6812        } finally {
6813            Binder.restoreCallingIdentity(origId);
6814        }
6815    }
6816
6817    @Override
6818    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6819        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6820    }
6821
6822    @Override
6823    public final void notifyEnterAnimationComplete(IBinder token) {
6824        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6825    }
6826
6827    @Override
6828    public String getCallingPackage(IBinder token) {
6829        synchronized (this) {
6830            ActivityRecord r = getCallingRecordLocked(token);
6831            return r != null ? r.info.packageName : null;
6832        }
6833    }
6834
6835    @Override
6836    public ComponentName getCallingActivity(IBinder token) {
6837        synchronized (this) {
6838            ActivityRecord r = getCallingRecordLocked(token);
6839            return r != null ? r.intent.getComponent() : null;
6840        }
6841    }
6842
6843    private ActivityRecord getCallingRecordLocked(IBinder token) {
6844        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6845        if (r == null) {
6846            return null;
6847        }
6848        return r.resultTo;
6849    }
6850
6851    @Override
6852    public ComponentName getActivityClassForToken(IBinder token) {
6853        synchronized(this) {
6854            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6855            if (r == null) {
6856                return null;
6857            }
6858            return r.intent.getComponent();
6859        }
6860    }
6861
6862    @Override
6863    public String getPackageForToken(IBinder token) {
6864        synchronized(this) {
6865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6866            if (r == null) {
6867                return null;
6868            }
6869            return r.packageName;
6870        }
6871    }
6872
6873    @Override
6874    public boolean isRootVoiceInteraction(IBinder token) {
6875        synchronized(this) {
6876            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6877            if (r == null) {
6878                return false;
6879            }
6880            return r.rootVoiceInteraction;
6881        }
6882    }
6883
6884    @Override
6885    public IIntentSender getIntentSender(int type,
6886            String packageName, IBinder token, String resultWho,
6887            int requestCode, Intent[] intents, String[] resolvedTypes,
6888            int flags, Bundle bOptions, int userId) {
6889        enforceNotIsolatedCaller("getIntentSender");
6890        // Refuse possible leaked file descriptors
6891        if (intents != null) {
6892            if (intents.length < 1) {
6893                throw new IllegalArgumentException("Intents array length must be >= 1");
6894            }
6895            for (int i=0; i<intents.length; i++) {
6896                Intent intent = intents[i];
6897                if (intent != null) {
6898                    if (intent.hasFileDescriptors()) {
6899                        throw new IllegalArgumentException("File descriptors passed in Intent");
6900                    }
6901                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6902                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6903                        throw new IllegalArgumentException(
6904                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6905                    }
6906                    intents[i] = new Intent(intent);
6907                }
6908            }
6909            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6910                throw new IllegalArgumentException(
6911                        "Intent array length does not match resolvedTypes length");
6912            }
6913        }
6914        if (bOptions != null) {
6915            if (bOptions.hasFileDescriptors()) {
6916                throw new IllegalArgumentException("File descriptors passed in options");
6917            }
6918        }
6919
6920        synchronized(this) {
6921            int callingUid = Binder.getCallingUid();
6922            int origUserId = userId;
6923            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6924                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6925                    ALLOW_NON_FULL, "getIntentSender", null);
6926            if (origUserId == UserHandle.USER_CURRENT) {
6927                // We don't want to evaluate this until the pending intent is
6928                // actually executed.  However, we do want to always do the
6929                // security checking for it above.
6930                userId = UserHandle.USER_CURRENT;
6931            }
6932            try {
6933                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6934                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6935                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6936                    if (!UserHandle.isSameApp(callingUid, uid)) {
6937                        String msg = "Permission Denial: getIntentSender() from pid="
6938                            + Binder.getCallingPid()
6939                            + ", uid=" + Binder.getCallingUid()
6940                            + ", (need uid=" + uid + ")"
6941                            + " is not allowed to send as package " + packageName;
6942                        Slog.w(TAG, msg);
6943                        throw new SecurityException(msg);
6944                    }
6945                }
6946
6947                return getIntentSenderLocked(type, packageName, callingUid, userId,
6948                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6949
6950            } catch (RemoteException e) {
6951                throw new SecurityException(e);
6952            }
6953        }
6954    }
6955
6956    IIntentSender getIntentSenderLocked(int type, String packageName,
6957            int callingUid, int userId, IBinder token, String resultWho,
6958            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6959            Bundle bOptions) {
6960        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6961        ActivityRecord activity = null;
6962        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6963            activity = ActivityRecord.isInStackLocked(token);
6964            if (activity == null) {
6965                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6966                return null;
6967            }
6968            if (activity.finishing) {
6969                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6970                return null;
6971            }
6972        }
6973
6974        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6975        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6976        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6977        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6978                |PendingIntent.FLAG_UPDATE_CURRENT);
6979
6980        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6981                type, packageName, activity, resultWho,
6982                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6983        WeakReference<PendingIntentRecord> ref;
6984        ref = mIntentSenderRecords.get(key);
6985        PendingIntentRecord rec = ref != null ? ref.get() : null;
6986        if (rec != null) {
6987            if (!cancelCurrent) {
6988                if (updateCurrent) {
6989                    if (rec.key.requestIntent != null) {
6990                        rec.key.requestIntent.replaceExtras(intents != null ?
6991                                intents[intents.length - 1] : null);
6992                    }
6993                    if (intents != null) {
6994                        intents[intents.length-1] = rec.key.requestIntent;
6995                        rec.key.allIntents = intents;
6996                        rec.key.allResolvedTypes = resolvedTypes;
6997                    } else {
6998                        rec.key.allIntents = null;
6999                        rec.key.allResolvedTypes = null;
7000                    }
7001                }
7002                return rec;
7003            }
7004            rec.canceled = true;
7005            mIntentSenderRecords.remove(key);
7006        }
7007        if (noCreate) {
7008            return rec;
7009        }
7010        rec = new PendingIntentRecord(this, key, callingUid);
7011        mIntentSenderRecords.put(key, rec.ref);
7012        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7013            if (activity.pendingResults == null) {
7014                activity.pendingResults
7015                        = new HashSet<WeakReference<PendingIntentRecord>>();
7016            }
7017            activity.pendingResults.add(rec.ref);
7018        }
7019        return rec;
7020    }
7021
7022    @Override
7023    public void cancelIntentSender(IIntentSender sender) {
7024        if (!(sender instanceof PendingIntentRecord)) {
7025            return;
7026        }
7027        synchronized(this) {
7028            PendingIntentRecord rec = (PendingIntentRecord)sender;
7029            try {
7030                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7031                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7032                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7033                    String msg = "Permission Denial: cancelIntentSender() from pid="
7034                        + Binder.getCallingPid()
7035                        + ", uid=" + Binder.getCallingUid()
7036                        + " is not allowed to cancel packges "
7037                        + rec.key.packageName;
7038                    Slog.w(TAG, msg);
7039                    throw new SecurityException(msg);
7040                }
7041            } catch (RemoteException e) {
7042                throw new SecurityException(e);
7043            }
7044            cancelIntentSenderLocked(rec, true);
7045        }
7046    }
7047
7048    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7049        rec.canceled = true;
7050        mIntentSenderRecords.remove(rec.key);
7051        if (cleanActivity && rec.key.activity != null) {
7052            rec.key.activity.pendingResults.remove(rec.ref);
7053        }
7054    }
7055
7056    @Override
7057    public String getPackageForIntentSender(IIntentSender pendingResult) {
7058        if (!(pendingResult instanceof PendingIntentRecord)) {
7059            return null;
7060        }
7061        try {
7062            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7063            return res.key.packageName;
7064        } catch (ClassCastException e) {
7065        }
7066        return null;
7067    }
7068
7069    @Override
7070    public int getUidForIntentSender(IIntentSender sender) {
7071        if (sender instanceof PendingIntentRecord) {
7072            try {
7073                PendingIntentRecord res = (PendingIntentRecord)sender;
7074                return res.uid;
7075            } catch (ClassCastException e) {
7076            }
7077        }
7078        return -1;
7079    }
7080
7081    @Override
7082    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7083        if (!(pendingResult instanceof PendingIntentRecord)) {
7084            return false;
7085        }
7086        try {
7087            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7088            if (res.key.allIntents == null) {
7089                return false;
7090            }
7091            for (int i=0; i<res.key.allIntents.length; i++) {
7092                Intent intent = res.key.allIntents[i];
7093                if (intent.getPackage() != null && intent.getComponent() != null) {
7094                    return false;
7095                }
7096            }
7097            return true;
7098        } catch (ClassCastException e) {
7099        }
7100        return false;
7101    }
7102
7103    @Override
7104    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7105        if (!(pendingResult instanceof PendingIntentRecord)) {
7106            return false;
7107        }
7108        try {
7109            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7110            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7111                return true;
7112            }
7113            return false;
7114        } catch (ClassCastException e) {
7115        }
7116        return false;
7117    }
7118
7119    @Override
7120    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7121        if (!(pendingResult instanceof PendingIntentRecord)) {
7122            return null;
7123        }
7124        try {
7125            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7126            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7127        } catch (ClassCastException e) {
7128        }
7129        return null;
7130    }
7131
7132    @Override
7133    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7134        if (!(pendingResult instanceof PendingIntentRecord)) {
7135            return null;
7136        }
7137        try {
7138            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7139            synchronized (this) {
7140                return getTagForIntentSenderLocked(res, prefix);
7141            }
7142        } catch (ClassCastException e) {
7143        }
7144        return null;
7145    }
7146
7147    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7148        final Intent intent = res.key.requestIntent;
7149        if (intent != null) {
7150            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7151                    || res.lastTagPrefix.equals(prefix))) {
7152                return res.lastTag;
7153            }
7154            res.lastTagPrefix = prefix;
7155            final StringBuilder sb = new StringBuilder(128);
7156            if (prefix != null) {
7157                sb.append(prefix);
7158            }
7159            if (intent.getAction() != null) {
7160                sb.append(intent.getAction());
7161            } else if (intent.getComponent() != null) {
7162                intent.getComponent().appendShortString(sb);
7163            } else {
7164                sb.append("?");
7165            }
7166            return res.lastTag = sb.toString();
7167        }
7168        return null;
7169    }
7170
7171    @Override
7172    public void setProcessLimit(int max) {
7173        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7174                "setProcessLimit()");
7175        synchronized (this) {
7176            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7177            mProcessLimitOverride = max;
7178        }
7179        trimApplications();
7180    }
7181
7182    @Override
7183    public int getProcessLimit() {
7184        synchronized (this) {
7185            return mProcessLimitOverride;
7186        }
7187    }
7188
7189    void foregroundTokenDied(ForegroundToken token) {
7190        synchronized (ActivityManagerService.this) {
7191            synchronized (mPidsSelfLocked) {
7192                ForegroundToken cur
7193                    = mForegroundProcesses.get(token.pid);
7194                if (cur != token) {
7195                    return;
7196                }
7197                mForegroundProcesses.remove(token.pid);
7198                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7199                if (pr == null) {
7200                    return;
7201                }
7202                pr.forcingToForeground = null;
7203                updateProcessForegroundLocked(pr, false, false);
7204            }
7205            updateOomAdjLocked();
7206        }
7207    }
7208
7209    @Override
7210    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7211        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7212                "setProcessForeground()");
7213        synchronized(this) {
7214            boolean changed = false;
7215
7216            synchronized (mPidsSelfLocked) {
7217                ProcessRecord pr = mPidsSelfLocked.get(pid);
7218                if (pr == null && isForeground) {
7219                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7220                    return;
7221                }
7222                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7223                if (oldToken != null) {
7224                    oldToken.token.unlinkToDeath(oldToken, 0);
7225                    mForegroundProcesses.remove(pid);
7226                    if (pr != null) {
7227                        pr.forcingToForeground = null;
7228                    }
7229                    changed = true;
7230                }
7231                if (isForeground && token != null) {
7232                    ForegroundToken newToken = new ForegroundToken() {
7233                        @Override
7234                        public void binderDied() {
7235                            foregroundTokenDied(this);
7236                        }
7237                    };
7238                    newToken.pid = pid;
7239                    newToken.token = token;
7240                    try {
7241                        token.linkToDeath(newToken, 0);
7242                        mForegroundProcesses.put(pid, newToken);
7243                        pr.forcingToForeground = token;
7244                        changed = true;
7245                    } catch (RemoteException e) {
7246                        // If the process died while doing this, we will later
7247                        // do the cleanup with the process death link.
7248                    }
7249                }
7250            }
7251
7252            if (changed) {
7253                updateOomAdjLocked();
7254            }
7255        }
7256    }
7257
7258    @Override
7259    public boolean isAppForeground(int uid) throws RemoteException {
7260        synchronized (this) {
7261            UidRecord uidRec = mActiveUids.get(uid);
7262            if (uidRec == null || uidRec.idle) {
7263                return false;
7264            }
7265            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7266        }
7267    }
7268
7269    @Override
7270    public boolean inMultiWindowMode(IBinder token) {
7271        final long origId = Binder.clearCallingIdentity();
7272        try {
7273            synchronized(this) {
7274                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7275                if (r == null) {
7276                    return false;
7277                }
7278                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7279                return !r.task.mFullscreen;
7280            }
7281        } finally {
7282            Binder.restoreCallingIdentity(origId);
7283        }
7284    }
7285
7286    @Override
7287    public boolean inPictureInPictureMode(IBinder token) {
7288        final long origId = Binder.clearCallingIdentity();
7289        try {
7290            synchronized(this) {
7291                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7292                if (stack == null) {
7293                    return false;
7294                }
7295                return stack.mStackId == PINNED_STACK_ID;
7296            }
7297        } finally {
7298            Binder.restoreCallingIdentity(origId);
7299        }
7300    }
7301
7302    @Override
7303    public void enterPictureInPictureMode(IBinder token) {
7304        final long origId = Binder.clearCallingIdentity();
7305        try {
7306            synchronized(this) {
7307                if (!mSupportsPictureInPicture) {
7308                    throw new IllegalStateException("enterPictureInPictureMode: "
7309                            + "Device doesn't support picture-in-picture mode.");
7310                }
7311
7312                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7313
7314                if (r == null) {
7315                    throw new IllegalStateException("enterPictureInPictureMode: "
7316                            + "Can't find activity for token=" + token);
7317                }
7318
7319                if (!r.supportsPictureInPicture()) {
7320                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7321                            + "Picture-In-Picture not supported for r=" + r);
7322                }
7323
7324                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7325                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7326                        ? mDefaultPinnedStackBounds : null;
7327
7328                mStackSupervisor.moveActivityToStackLocked(
7329                        r, PINNED_STACK_ID, "enterPictureInPictureMode", bounds);
7330            }
7331        } finally {
7332            Binder.restoreCallingIdentity(origId);
7333        }
7334    }
7335
7336    // =========================================================
7337    // PROCESS INFO
7338    // =========================================================
7339
7340    static class ProcessInfoService extends IProcessInfoService.Stub {
7341        final ActivityManagerService mActivityManagerService;
7342        ProcessInfoService(ActivityManagerService activityManagerService) {
7343            mActivityManagerService = activityManagerService;
7344        }
7345
7346        @Override
7347        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7348            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7349                    /*in*/ pids, /*out*/ states, null);
7350        }
7351
7352        @Override
7353        public void getProcessStatesAndOomScoresFromPids(
7354                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7355            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7356                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7357        }
7358    }
7359
7360    /**
7361     * For each PID in the given input array, write the current process state
7362     * for that process into the states array, or -1 to indicate that no
7363     * process with the given PID exists. If scores array is provided, write
7364     * the oom score for the process into the scores array, with INVALID_ADJ
7365     * indicating the PID doesn't exist.
7366     */
7367    public void getProcessStatesAndOomScoresForPIDs(
7368            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7369        if (scores != null) {
7370            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7371                    "getProcessStatesAndOomScoresForPIDs()");
7372        }
7373
7374        if (pids == null) {
7375            throw new NullPointerException("pids");
7376        } else if (states == null) {
7377            throw new NullPointerException("states");
7378        } else if (pids.length != states.length) {
7379            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7380        } else if (scores != null && pids.length != scores.length) {
7381            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7382        }
7383
7384        synchronized (mPidsSelfLocked) {
7385            for (int i = 0; i < pids.length; i++) {
7386                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7387                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7388                        pr.curProcState;
7389                if (scores != null) {
7390                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7391                }
7392            }
7393        }
7394    }
7395
7396    // =========================================================
7397    // PERMISSIONS
7398    // =========================================================
7399
7400    static class PermissionController extends IPermissionController.Stub {
7401        ActivityManagerService mActivityManagerService;
7402        PermissionController(ActivityManagerService activityManagerService) {
7403            mActivityManagerService = activityManagerService;
7404        }
7405
7406        @Override
7407        public boolean checkPermission(String permission, int pid, int uid) {
7408            return mActivityManagerService.checkPermission(permission, pid,
7409                    uid) == PackageManager.PERMISSION_GRANTED;
7410        }
7411
7412        @Override
7413        public String[] getPackagesForUid(int uid) {
7414            return mActivityManagerService.mContext.getPackageManager()
7415                    .getPackagesForUid(uid);
7416        }
7417
7418        @Override
7419        public boolean isRuntimePermission(String permission) {
7420            try {
7421                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7422                        .getPermissionInfo(permission, 0);
7423                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7424            } catch (NameNotFoundException nnfe) {
7425                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7426            }
7427            return false;
7428        }
7429    }
7430
7431    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7432        @Override
7433        public int checkComponentPermission(String permission, int pid, int uid,
7434                int owningUid, boolean exported) {
7435            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7436                    owningUid, exported);
7437        }
7438
7439        @Override
7440        public Object getAMSLock() {
7441            return ActivityManagerService.this;
7442        }
7443    }
7444
7445    /**
7446     * This can be called with or without the global lock held.
7447     */
7448    int checkComponentPermission(String permission, int pid, int uid,
7449            int owningUid, boolean exported) {
7450        if (pid == MY_PID) {
7451            return PackageManager.PERMISSION_GRANTED;
7452        }
7453        return ActivityManager.checkComponentPermission(permission, uid,
7454                owningUid, exported);
7455    }
7456
7457    /**
7458     * As the only public entry point for permissions checking, this method
7459     * can enforce the semantic that requesting a check on a null global
7460     * permission is automatically denied.  (Internally a null permission
7461     * string is used when calling {@link #checkComponentPermission} in cases
7462     * when only uid-based security is needed.)
7463     *
7464     * This can be called with or without the global lock held.
7465     */
7466    @Override
7467    public int checkPermission(String permission, int pid, int uid) {
7468        if (permission == null) {
7469            return PackageManager.PERMISSION_DENIED;
7470        }
7471        return checkComponentPermission(permission, pid, uid, -1, true);
7472    }
7473
7474    @Override
7475    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7476        if (permission == null) {
7477            return PackageManager.PERMISSION_DENIED;
7478        }
7479
7480        // We might be performing an operation on behalf of an indirect binder
7481        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7482        // client identity accordingly before proceeding.
7483        Identity tlsIdentity = sCallerIdentity.get();
7484        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7485            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7486                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7487            uid = tlsIdentity.uid;
7488            pid = tlsIdentity.pid;
7489        }
7490
7491        return checkComponentPermission(permission, pid, uid, -1, true);
7492    }
7493
7494    /**
7495     * Binder IPC calls go through the public entry point.
7496     * This can be called with or without the global lock held.
7497     */
7498    int checkCallingPermission(String permission) {
7499        return checkPermission(permission,
7500                Binder.getCallingPid(),
7501                UserHandle.getAppId(Binder.getCallingUid()));
7502    }
7503
7504    /**
7505     * This can be called with or without the global lock held.
7506     */
7507    void enforceCallingPermission(String permission, String func) {
7508        if (checkCallingPermission(permission)
7509                == PackageManager.PERMISSION_GRANTED) {
7510            return;
7511        }
7512
7513        String msg = "Permission Denial: " + func + " from pid="
7514                + Binder.getCallingPid()
7515                + ", uid=" + Binder.getCallingUid()
7516                + " requires " + permission;
7517        Slog.w(TAG, msg);
7518        throw new SecurityException(msg);
7519    }
7520
7521    /**
7522     * Determine if UID is holding permissions required to access {@link Uri} in
7523     * the given {@link ProviderInfo}. Final permission checking is always done
7524     * in {@link ContentProvider}.
7525     */
7526    private final boolean checkHoldingPermissionsLocked(
7527            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7528        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7529                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7530        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7531            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7532                    != PERMISSION_GRANTED) {
7533                return false;
7534            }
7535        }
7536        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7537    }
7538
7539    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7540            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7541        if (pi.applicationInfo.uid == uid) {
7542            return true;
7543        } else if (!pi.exported) {
7544            return false;
7545        }
7546
7547        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7548        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7549        try {
7550            // check if target holds top-level <provider> permissions
7551            if (!readMet && pi.readPermission != null && considerUidPermissions
7552                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7553                readMet = true;
7554            }
7555            if (!writeMet && pi.writePermission != null && considerUidPermissions
7556                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7557                writeMet = true;
7558            }
7559
7560            // track if unprotected read/write is allowed; any denied
7561            // <path-permission> below removes this ability
7562            boolean allowDefaultRead = pi.readPermission == null;
7563            boolean allowDefaultWrite = pi.writePermission == null;
7564
7565            // check if target holds any <path-permission> that match uri
7566            final PathPermission[] pps = pi.pathPermissions;
7567            if (pps != null) {
7568                final String path = grantUri.uri.getPath();
7569                int i = pps.length;
7570                while (i > 0 && (!readMet || !writeMet)) {
7571                    i--;
7572                    PathPermission pp = pps[i];
7573                    if (pp.match(path)) {
7574                        if (!readMet) {
7575                            final String pprperm = pp.getReadPermission();
7576                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7577                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7578                                    + ": match=" + pp.match(path)
7579                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7580                            if (pprperm != null) {
7581                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7582                                        == PERMISSION_GRANTED) {
7583                                    readMet = true;
7584                                } else {
7585                                    allowDefaultRead = false;
7586                                }
7587                            }
7588                        }
7589                        if (!writeMet) {
7590                            final String ppwperm = pp.getWritePermission();
7591                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7592                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7593                                    + ": match=" + pp.match(path)
7594                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7595                            if (ppwperm != null) {
7596                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7597                                        == PERMISSION_GRANTED) {
7598                                    writeMet = true;
7599                                } else {
7600                                    allowDefaultWrite = false;
7601                                }
7602                            }
7603                        }
7604                    }
7605                }
7606            }
7607
7608            // grant unprotected <provider> read/write, if not blocked by
7609            // <path-permission> above
7610            if (allowDefaultRead) readMet = true;
7611            if (allowDefaultWrite) writeMet = true;
7612
7613        } catch (RemoteException e) {
7614            return false;
7615        }
7616
7617        return readMet && writeMet;
7618    }
7619
7620    public int getAppStartMode(int uid, String packageName) {
7621        synchronized (this) {
7622            return checkAllowBackgroundLocked(uid, packageName, -1);
7623        }
7624    }
7625
7626    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7627        UidRecord uidRec = mActiveUids.get(uid);
7628        if (uidRec == null || uidRec.idle) {
7629            if (callingPid >= 0) {
7630                ProcessRecord proc;
7631                synchronized (mPidsSelfLocked) {
7632                    proc = mPidsSelfLocked.get(callingPid);
7633                }
7634                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7635                    // Whoever is instigating this is in the foreground, so we will allow it
7636                    // to go through.
7637                    return ActivityManager.APP_START_MODE_NORMAL;
7638                }
7639            }
7640            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7641                    != AppOpsManager.MODE_ALLOWED) {
7642                return ActivityManager.APP_START_MODE_DELAYED;
7643            }
7644        }
7645        return ActivityManager.APP_START_MODE_NORMAL;
7646    }
7647
7648    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7649        ProviderInfo pi = null;
7650        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7651        if (cpr != null) {
7652            pi = cpr.info;
7653        } else {
7654            try {
7655                pi = AppGlobals.getPackageManager().resolveContentProvider(
7656                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7657            } catch (RemoteException ex) {
7658            }
7659        }
7660        return pi;
7661    }
7662
7663    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7664        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7665        if (targetUris != null) {
7666            return targetUris.get(grantUri);
7667        }
7668        return null;
7669    }
7670
7671    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7672            String targetPkg, int targetUid, GrantUri grantUri) {
7673        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7674        if (targetUris == null) {
7675            targetUris = Maps.newArrayMap();
7676            mGrantedUriPermissions.put(targetUid, targetUris);
7677        }
7678
7679        UriPermission perm = targetUris.get(grantUri);
7680        if (perm == null) {
7681            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7682            targetUris.put(grantUri, perm);
7683        }
7684
7685        return perm;
7686    }
7687
7688    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7689            final int modeFlags) {
7690        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7691        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7692                : UriPermission.STRENGTH_OWNED;
7693
7694        // Root gets to do everything.
7695        if (uid == 0) {
7696            return true;
7697        }
7698
7699        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7700        if (perms == null) return false;
7701
7702        // First look for exact match
7703        final UriPermission exactPerm = perms.get(grantUri);
7704        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7705            return true;
7706        }
7707
7708        // No exact match, look for prefixes
7709        final int N = perms.size();
7710        for (int i = 0; i < N; i++) {
7711            final UriPermission perm = perms.valueAt(i);
7712            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7713                    && perm.getStrength(modeFlags) >= minStrength) {
7714                return true;
7715            }
7716        }
7717
7718        return false;
7719    }
7720
7721    /**
7722     * @param uri This uri must NOT contain an embedded userId.
7723     * @param userId The userId in which the uri is to be resolved.
7724     */
7725    @Override
7726    public int checkUriPermission(Uri uri, int pid, int uid,
7727            final int modeFlags, int userId, IBinder callerToken) {
7728        enforceNotIsolatedCaller("checkUriPermission");
7729
7730        // Another redirected-binder-call permissions check as in
7731        // {@link checkPermissionWithToken}.
7732        Identity tlsIdentity = sCallerIdentity.get();
7733        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7734            uid = tlsIdentity.uid;
7735            pid = tlsIdentity.pid;
7736        }
7737
7738        // Our own process gets to do everything.
7739        if (pid == MY_PID) {
7740            return PackageManager.PERMISSION_GRANTED;
7741        }
7742        synchronized (this) {
7743            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7744                    ? PackageManager.PERMISSION_GRANTED
7745                    : PackageManager.PERMISSION_DENIED;
7746        }
7747    }
7748
7749    /**
7750     * Check if the targetPkg can be granted permission to access uri by
7751     * the callingUid using the given modeFlags.  Throws a security exception
7752     * if callingUid is not allowed to do this.  Returns the uid of the target
7753     * if the URI permission grant should be performed; returns -1 if it is not
7754     * needed (for example targetPkg already has permission to access the URI).
7755     * If you already know the uid of the target, you can supply it in
7756     * lastTargetUid else set that to -1.
7757     */
7758    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7759            final int modeFlags, int lastTargetUid) {
7760        if (!Intent.isAccessUriMode(modeFlags)) {
7761            return -1;
7762        }
7763
7764        if (targetPkg != null) {
7765            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7766                    "Checking grant " + targetPkg + " permission to " + grantUri);
7767        }
7768
7769        final IPackageManager pm = AppGlobals.getPackageManager();
7770
7771        // If this is not a content: uri, we can't do anything with it.
7772        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7773            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7774                    "Can't grant URI permission for non-content URI: " + grantUri);
7775            return -1;
7776        }
7777
7778        final String authority = grantUri.uri.getAuthority();
7779        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7780        if (pi == null) {
7781            Slog.w(TAG, "No content provider found for permission check: " +
7782                    grantUri.uri.toSafeString());
7783            return -1;
7784        }
7785
7786        int targetUid = lastTargetUid;
7787        if (targetUid < 0 && targetPkg != null) {
7788            try {
7789                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7790                        UserHandle.getUserId(callingUid));
7791                if (targetUid < 0) {
7792                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7793                            "Can't grant URI permission no uid for: " + targetPkg);
7794                    return -1;
7795                }
7796            } catch (RemoteException ex) {
7797                return -1;
7798            }
7799        }
7800
7801        if (targetUid >= 0) {
7802            // First...  does the target actually need this permission?
7803            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7804                // No need to grant the target this permission.
7805                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                        "Target " + targetPkg + " already has full permission to " + grantUri);
7807                return -1;
7808            }
7809        } else {
7810            // First...  there is no target package, so can anyone access it?
7811            boolean allowed = pi.exported;
7812            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7813                if (pi.readPermission != null) {
7814                    allowed = false;
7815                }
7816            }
7817            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7818                if (pi.writePermission != null) {
7819                    allowed = false;
7820                }
7821            }
7822            if (allowed) {
7823                return -1;
7824            }
7825        }
7826
7827        /* There is a special cross user grant if:
7828         * - The target is on another user.
7829         * - Apps on the current user can access the uri without any uid permissions.
7830         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7831         * grant uri permissions.
7832         */
7833        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7834                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7835                modeFlags, false /*without considering the uid permissions*/);
7836
7837        // Second...  is the provider allowing granting of URI permissions?
7838        if (!specialCrossUserGrant) {
7839            if (!pi.grantUriPermissions) {
7840                throw new SecurityException("Provider " + pi.packageName
7841                        + "/" + pi.name
7842                        + " does not allow granting of Uri permissions (uri "
7843                        + grantUri + ")");
7844            }
7845            if (pi.uriPermissionPatterns != null) {
7846                final int N = pi.uriPermissionPatterns.length;
7847                boolean allowed = false;
7848                for (int i=0; i<N; i++) {
7849                    if (pi.uriPermissionPatterns[i] != null
7850                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7851                        allowed = true;
7852                        break;
7853                    }
7854                }
7855                if (!allowed) {
7856                    throw new SecurityException("Provider " + pi.packageName
7857                            + "/" + pi.name
7858                            + " does not allow granting of permission to path of Uri "
7859                            + grantUri);
7860                }
7861            }
7862        }
7863
7864        // Third...  does the caller itself have permission to access
7865        // this uri?
7866        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7867            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7868                // Require they hold a strong enough Uri permission
7869                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7870                    throw new SecurityException("Uid " + callingUid
7871                            + " does not have permission to uri " + grantUri);
7872                }
7873            }
7874        }
7875        return targetUid;
7876    }
7877
7878    /**
7879     * @param uri This uri must NOT contain an embedded userId.
7880     * @param userId The userId in which the uri is to be resolved.
7881     */
7882    @Override
7883    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7884            final int modeFlags, int userId) {
7885        enforceNotIsolatedCaller("checkGrantUriPermission");
7886        synchronized(this) {
7887            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7888                    new GrantUri(userId, uri, false), modeFlags, -1);
7889        }
7890    }
7891
7892    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7893            final int modeFlags, UriPermissionOwner owner) {
7894        if (!Intent.isAccessUriMode(modeFlags)) {
7895            return;
7896        }
7897
7898        // So here we are: the caller has the assumed permission
7899        // to the uri, and the target doesn't.  Let's now give this to
7900        // the target.
7901
7902        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7903                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7904
7905        final String authority = grantUri.uri.getAuthority();
7906        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7907        if (pi == null) {
7908            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7909            return;
7910        }
7911
7912        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7913            grantUri.prefix = true;
7914        }
7915        final UriPermission perm = findOrCreateUriPermissionLocked(
7916                pi.packageName, targetPkg, targetUid, grantUri);
7917        perm.grantModes(modeFlags, owner);
7918    }
7919
7920    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7921            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7922        if (targetPkg == null) {
7923            throw new NullPointerException("targetPkg");
7924        }
7925        int targetUid;
7926        final IPackageManager pm = AppGlobals.getPackageManager();
7927        try {
7928            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7929        } catch (RemoteException ex) {
7930            return;
7931        }
7932
7933        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7934                targetUid);
7935        if (targetUid < 0) {
7936            return;
7937        }
7938
7939        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7940                owner);
7941    }
7942
7943    static class NeededUriGrants extends ArrayList<GrantUri> {
7944        final String targetPkg;
7945        final int targetUid;
7946        final int flags;
7947
7948        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7949            this.targetPkg = targetPkg;
7950            this.targetUid = targetUid;
7951            this.flags = flags;
7952        }
7953    }
7954
7955    /**
7956     * Like checkGrantUriPermissionLocked, but takes an Intent.
7957     */
7958    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7959            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7960        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7961                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7962                + " clip=" + (intent != null ? intent.getClipData() : null)
7963                + " from " + intent + "; flags=0x"
7964                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7965
7966        if (targetPkg == null) {
7967            throw new NullPointerException("targetPkg");
7968        }
7969
7970        if (intent == null) {
7971            return null;
7972        }
7973        Uri data = intent.getData();
7974        ClipData clip = intent.getClipData();
7975        if (data == null && clip == null) {
7976            return null;
7977        }
7978        // Default userId for uris in the intent (if they don't specify it themselves)
7979        int contentUserHint = intent.getContentUserHint();
7980        if (contentUserHint == UserHandle.USER_CURRENT) {
7981            contentUserHint = UserHandle.getUserId(callingUid);
7982        }
7983        final IPackageManager pm = AppGlobals.getPackageManager();
7984        int targetUid;
7985        if (needed != null) {
7986            targetUid = needed.targetUid;
7987        } else {
7988            try {
7989                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7990                        targetUserId);
7991            } catch (RemoteException ex) {
7992                return null;
7993            }
7994            if (targetUid < 0) {
7995                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7996                        "Can't grant URI permission no uid for: " + targetPkg
7997                        + " on user " + targetUserId);
7998                return null;
7999            }
8000        }
8001        if (data != null) {
8002            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8003            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8004                    targetUid);
8005            if (targetUid > 0) {
8006                if (needed == null) {
8007                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8008                }
8009                needed.add(grantUri);
8010            }
8011        }
8012        if (clip != null) {
8013            for (int i=0; i<clip.getItemCount(); i++) {
8014                Uri uri = clip.getItemAt(i).getUri();
8015                if (uri != null) {
8016                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8017                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8018                            targetUid);
8019                    if (targetUid > 0) {
8020                        if (needed == null) {
8021                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8022                        }
8023                        needed.add(grantUri);
8024                    }
8025                } else {
8026                    Intent clipIntent = clip.getItemAt(i).getIntent();
8027                    if (clipIntent != null) {
8028                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8029                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8030                        if (newNeeded != null) {
8031                            needed = newNeeded;
8032                        }
8033                    }
8034                }
8035            }
8036        }
8037
8038        return needed;
8039    }
8040
8041    /**
8042     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8043     */
8044    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8045            UriPermissionOwner owner) {
8046        if (needed != null) {
8047            for (int i=0; i<needed.size(); i++) {
8048                GrantUri grantUri = needed.get(i);
8049                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8050                        grantUri, needed.flags, owner);
8051            }
8052        }
8053    }
8054
8055    void grantUriPermissionFromIntentLocked(int callingUid,
8056            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8057        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8058                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8059        if (needed == null) {
8060            return;
8061        }
8062
8063        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8064    }
8065
8066    /**
8067     * @param uri This uri must NOT contain an embedded userId.
8068     * @param userId The userId in which the uri is to be resolved.
8069     */
8070    @Override
8071    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8072            final int modeFlags, int userId) {
8073        enforceNotIsolatedCaller("grantUriPermission");
8074        GrantUri grantUri = new GrantUri(userId, uri, false);
8075        synchronized(this) {
8076            final ProcessRecord r = getRecordForAppLocked(caller);
8077            if (r == null) {
8078                throw new SecurityException("Unable to find app for caller "
8079                        + caller
8080                        + " when granting permission to uri " + grantUri);
8081            }
8082            if (targetPkg == null) {
8083                throw new IllegalArgumentException("null target");
8084            }
8085            if (grantUri == null) {
8086                throw new IllegalArgumentException("null uri");
8087            }
8088
8089            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8090                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8091                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8092                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8093
8094            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8095                    UserHandle.getUserId(r.uid));
8096        }
8097    }
8098
8099    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8100        if (perm.modeFlags == 0) {
8101            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8102                    perm.targetUid);
8103            if (perms != null) {
8104                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8105                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8106
8107                perms.remove(perm.uri);
8108                if (perms.isEmpty()) {
8109                    mGrantedUriPermissions.remove(perm.targetUid);
8110                }
8111            }
8112        }
8113    }
8114
8115    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8116        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8117                "Revoking all granted permissions to " + grantUri);
8118
8119        final IPackageManager pm = AppGlobals.getPackageManager();
8120        final String authority = grantUri.uri.getAuthority();
8121        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8122        if (pi == null) {
8123            Slog.w(TAG, "No content provider found for permission revoke: "
8124                    + grantUri.toSafeString());
8125            return;
8126        }
8127
8128        // Does the caller have this permission on the URI?
8129        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8130            // If they don't have direct access to the URI, then revoke any
8131            // ownerless URI permissions that have been granted to them.
8132            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8133            if (perms != null) {
8134                boolean persistChanged = false;
8135                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8136                    final UriPermission perm = it.next();
8137                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8138                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8139                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8140                                "Revoking non-owned " + perm.targetUid
8141                                + " permission to " + perm.uri);
8142                        persistChanged |= perm.revokeModes(
8143                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8144                        if (perm.modeFlags == 0) {
8145                            it.remove();
8146                        }
8147                    }
8148                }
8149                if (perms.isEmpty()) {
8150                    mGrantedUriPermissions.remove(callingUid);
8151                }
8152                if (persistChanged) {
8153                    schedulePersistUriGrants();
8154                }
8155            }
8156            return;
8157        }
8158
8159        boolean persistChanged = false;
8160
8161        // Go through all of the permissions and remove any that match.
8162        int N = mGrantedUriPermissions.size();
8163        for (int i = 0; i < N; i++) {
8164            final int targetUid = mGrantedUriPermissions.keyAt(i);
8165            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8166
8167            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8168                final UriPermission perm = it.next();
8169                if (perm.uri.sourceUserId == grantUri.sourceUserId
8170                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8171                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8173                    persistChanged |= perm.revokeModes(
8174                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8175                    if (perm.modeFlags == 0) {
8176                        it.remove();
8177                    }
8178                }
8179            }
8180
8181            if (perms.isEmpty()) {
8182                mGrantedUriPermissions.remove(targetUid);
8183                N--;
8184                i--;
8185            }
8186        }
8187
8188        if (persistChanged) {
8189            schedulePersistUriGrants();
8190        }
8191    }
8192
8193    /**
8194     * @param uri This uri must NOT contain an embedded userId.
8195     * @param userId The userId in which the uri is to be resolved.
8196     */
8197    @Override
8198    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8199            int userId) {
8200        enforceNotIsolatedCaller("revokeUriPermission");
8201        synchronized(this) {
8202            final ProcessRecord r = getRecordForAppLocked(caller);
8203            if (r == null) {
8204                throw new SecurityException("Unable to find app for caller "
8205                        + caller
8206                        + " when revoking permission to uri " + uri);
8207            }
8208            if (uri == null) {
8209                Slog.w(TAG, "revokeUriPermission: null uri");
8210                return;
8211            }
8212
8213            if (!Intent.isAccessUriMode(modeFlags)) {
8214                return;
8215            }
8216
8217            final String authority = uri.getAuthority();
8218            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8219            if (pi == null) {
8220                Slog.w(TAG, "No content provider found for permission revoke: "
8221                        + uri.toSafeString());
8222                return;
8223            }
8224
8225            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8226        }
8227    }
8228
8229    /**
8230     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8231     * given package.
8232     *
8233     * @param packageName Package name to match, or {@code null} to apply to all
8234     *            packages.
8235     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8236     *            to all users.
8237     * @param persistable If persistable grants should be removed.
8238     */
8239    private void removeUriPermissionsForPackageLocked(
8240            String packageName, int userHandle, boolean persistable) {
8241        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8242            throw new IllegalArgumentException("Must narrow by either package or user");
8243        }
8244
8245        boolean persistChanged = false;
8246
8247        int N = mGrantedUriPermissions.size();
8248        for (int i = 0; i < N; i++) {
8249            final int targetUid = mGrantedUriPermissions.keyAt(i);
8250            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8251
8252            // Only inspect grants matching user
8253            if (userHandle == UserHandle.USER_ALL
8254                    || userHandle == UserHandle.getUserId(targetUid)) {
8255                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8256                    final UriPermission perm = it.next();
8257
8258                    // Only inspect grants matching package
8259                    if (packageName == null || perm.sourcePkg.equals(packageName)
8260                            || perm.targetPkg.equals(packageName)) {
8261                        persistChanged |= perm.revokeModes(persistable
8262                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8263
8264                        // Only remove when no modes remain; any persisted grants
8265                        // will keep this alive.
8266                        if (perm.modeFlags == 0) {
8267                            it.remove();
8268                        }
8269                    }
8270                }
8271
8272                if (perms.isEmpty()) {
8273                    mGrantedUriPermissions.remove(targetUid);
8274                    N--;
8275                    i--;
8276                }
8277            }
8278        }
8279
8280        if (persistChanged) {
8281            schedulePersistUriGrants();
8282        }
8283    }
8284
8285    @Override
8286    public IBinder newUriPermissionOwner(String name) {
8287        enforceNotIsolatedCaller("newUriPermissionOwner");
8288        synchronized(this) {
8289            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8290            return owner.getExternalTokenLocked();
8291        }
8292    }
8293
8294    @Override
8295    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8296        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8297        synchronized(this) {
8298            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8299            if (r == null) {
8300                throw new IllegalArgumentException("Activity does not exist; token="
8301                        + activityToken);
8302            }
8303            return r.getUriPermissionsLocked().getExternalTokenLocked();
8304        }
8305    }
8306    /**
8307     * @param uri This uri must NOT contain an embedded userId.
8308     * @param sourceUserId The userId in which the uri is to be resolved.
8309     * @param targetUserId The userId of the app that receives the grant.
8310     */
8311    @Override
8312    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8313            final int modeFlags, int sourceUserId, int targetUserId) {
8314        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8315                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8316                "grantUriPermissionFromOwner", null);
8317        synchronized(this) {
8318            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8319            if (owner == null) {
8320                throw new IllegalArgumentException("Unknown owner: " + token);
8321            }
8322            if (fromUid != Binder.getCallingUid()) {
8323                if (Binder.getCallingUid() != Process.myUid()) {
8324                    // Only system code can grant URI permissions on behalf
8325                    // of other users.
8326                    throw new SecurityException("nice try");
8327                }
8328            }
8329            if (targetPkg == null) {
8330                throw new IllegalArgumentException("null target");
8331            }
8332            if (uri == null) {
8333                throw new IllegalArgumentException("null uri");
8334            }
8335
8336            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8337                    modeFlags, owner, targetUserId);
8338        }
8339    }
8340
8341    /**
8342     * @param uri This uri must NOT contain an embedded userId.
8343     * @param userId The userId in which the uri is to be resolved.
8344     */
8345    @Override
8346    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8347        synchronized(this) {
8348            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8349            if (owner == null) {
8350                throw new IllegalArgumentException("Unknown owner: " + token);
8351            }
8352
8353            if (uri == null) {
8354                owner.removeUriPermissionsLocked(mode);
8355            } else {
8356                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8357            }
8358        }
8359    }
8360
8361    private void schedulePersistUriGrants() {
8362        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8363            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8364                    10 * DateUtils.SECOND_IN_MILLIS);
8365        }
8366    }
8367
8368    private void writeGrantedUriPermissions() {
8369        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8370
8371        // Snapshot permissions so we can persist without lock
8372        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8373        synchronized (this) {
8374            final int size = mGrantedUriPermissions.size();
8375            for (int i = 0; i < size; i++) {
8376                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8377                for (UriPermission perm : perms.values()) {
8378                    if (perm.persistedModeFlags != 0) {
8379                        persist.add(perm.snapshot());
8380                    }
8381                }
8382            }
8383        }
8384
8385        FileOutputStream fos = null;
8386        try {
8387            fos = mGrantFile.startWrite();
8388
8389            XmlSerializer out = new FastXmlSerializer();
8390            out.setOutput(fos, StandardCharsets.UTF_8.name());
8391            out.startDocument(null, true);
8392            out.startTag(null, TAG_URI_GRANTS);
8393            for (UriPermission.Snapshot perm : persist) {
8394                out.startTag(null, TAG_URI_GRANT);
8395                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8396                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8397                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8398                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8399                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8400                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8401                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8402                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8403                out.endTag(null, TAG_URI_GRANT);
8404            }
8405            out.endTag(null, TAG_URI_GRANTS);
8406            out.endDocument();
8407
8408            mGrantFile.finishWrite(fos);
8409        } catch (IOException e) {
8410            if (fos != null) {
8411                mGrantFile.failWrite(fos);
8412            }
8413        }
8414    }
8415
8416    private void readGrantedUriPermissionsLocked() {
8417        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8418
8419        final long now = System.currentTimeMillis();
8420
8421        FileInputStream fis = null;
8422        try {
8423            fis = mGrantFile.openRead();
8424            final XmlPullParser in = Xml.newPullParser();
8425            in.setInput(fis, StandardCharsets.UTF_8.name());
8426
8427            int type;
8428            while ((type = in.next()) != END_DOCUMENT) {
8429                final String tag = in.getName();
8430                if (type == START_TAG) {
8431                    if (TAG_URI_GRANT.equals(tag)) {
8432                        final int sourceUserId;
8433                        final int targetUserId;
8434                        final int userHandle = readIntAttribute(in,
8435                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8436                        if (userHandle != UserHandle.USER_NULL) {
8437                            // For backwards compatibility.
8438                            sourceUserId = userHandle;
8439                            targetUserId = userHandle;
8440                        } else {
8441                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8442                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8443                        }
8444                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8445                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8446                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8447                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8448                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8449                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8450
8451                        // Sanity check that provider still belongs to source package
8452                        final ProviderInfo pi = getProviderInfoLocked(
8453                                uri.getAuthority(), sourceUserId);
8454                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8455                            int targetUid = -1;
8456                            try {
8457                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8458                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8459                            } catch (RemoteException e) {
8460                            }
8461                            if (targetUid != -1) {
8462                                final UriPermission perm = findOrCreateUriPermissionLocked(
8463                                        sourcePkg, targetPkg, targetUid,
8464                                        new GrantUri(sourceUserId, uri, prefix));
8465                                perm.initPersistedModes(modeFlags, createdTime);
8466                            }
8467                        } else {
8468                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8469                                    + " but instead found " + pi);
8470                        }
8471                    }
8472                }
8473            }
8474        } catch (FileNotFoundException e) {
8475            // Missing grants is okay
8476        } catch (IOException e) {
8477            Slog.wtf(TAG, "Failed reading Uri grants", e);
8478        } catch (XmlPullParserException e) {
8479            Slog.wtf(TAG, "Failed reading Uri grants", e);
8480        } finally {
8481            IoUtils.closeQuietly(fis);
8482        }
8483    }
8484
8485    /**
8486     * @param uri This uri must NOT contain an embedded userId.
8487     * @param userId The userId in which the uri is to be resolved.
8488     */
8489    @Override
8490    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8491        enforceNotIsolatedCaller("takePersistableUriPermission");
8492
8493        Preconditions.checkFlagsArgument(modeFlags,
8494                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8495
8496        synchronized (this) {
8497            final int callingUid = Binder.getCallingUid();
8498            boolean persistChanged = false;
8499            GrantUri grantUri = new GrantUri(userId, uri, false);
8500
8501            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8502                    new GrantUri(userId, uri, false));
8503            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8504                    new GrantUri(userId, uri, true));
8505
8506            final boolean exactValid = (exactPerm != null)
8507                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8508            final boolean prefixValid = (prefixPerm != null)
8509                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8510
8511            if (!(exactValid || prefixValid)) {
8512                throw new SecurityException("No persistable permission grants found for UID "
8513                        + callingUid + " and Uri " + grantUri.toSafeString());
8514            }
8515
8516            if (exactValid) {
8517                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8518            }
8519            if (prefixValid) {
8520                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8521            }
8522
8523            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8524
8525            if (persistChanged) {
8526                schedulePersistUriGrants();
8527            }
8528        }
8529    }
8530
8531    /**
8532     * @param uri This uri must NOT contain an embedded userId.
8533     * @param userId The userId in which the uri is to be resolved.
8534     */
8535    @Override
8536    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8537        enforceNotIsolatedCaller("releasePersistableUriPermission");
8538
8539        Preconditions.checkFlagsArgument(modeFlags,
8540                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8541
8542        synchronized (this) {
8543            final int callingUid = Binder.getCallingUid();
8544            boolean persistChanged = false;
8545
8546            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8547                    new GrantUri(userId, uri, false));
8548            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8549                    new GrantUri(userId, uri, true));
8550            if (exactPerm == null && prefixPerm == null) {
8551                throw new SecurityException("No permission grants found for UID " + callingUid
8552                        + " and Uri " + uri.toSafeString());
8553            }
8554
8555            if (exactPerm != null) {
8556                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8557                removeUriPermissionIfNeededLocked(exactPerm);
8558            }
8559            if (prefixPerm != null) {
8560                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8561                removeUriPermissionIfNeededLocked(prefixPerm);
8562            }
8563
8564            if (persistChanged) {
8565                schedulePersistUriGrants();
8566            }
8567        }
8568    }
8569
8570    /**
8571     * Prune any older {@link UriPermission} for the given UID until outstanding
8572     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8573     *
8574     * @return if any mutations occured that require persisting.
8575     */
8576    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8577        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8578        if (perms == null) return false;
8579        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8580
8581        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8582        for (UriPermission perm : perms.values()) {
8583            if (perm.persistedModeFlags != 0) {
8584                persisted.add(perm);
8585            }
8586        }
8587
8588        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8589        if (trimCount <= 0) return false;
8590
8591        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8592        for (int i = 0; i < trimCount; i++) {
8593            final UriPermission perm = persisted.get(i);
8594
8595            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8596                    "Trimming grant created at " + perm.persistedCreateTime);
8597
8598            perm.releasePersistableModes(~0);
8599            removeUriPermissionIfNeededLocked(perm);
8600        }
8601
8602        return true;
8603    }
8604
8605    @Override
8606    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8607            String packageName, boolean incoming) {
8608        enforceNotIsolatedCaller("getPersistedUriPermissions");
8609        Preconditions.checkNotNull(packageName, "packageName");
8610
8611        final int callingUid = Binder.getCallingUid();
8612        final IPackageManager pm = AppGlobals.getPackageManager();
8613        try {
8614            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8615                    UserHandle.getUserId(callingUid));
8616            if (packageUid != callingUid) {
8617                throw new SecurityException(
8618                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8619            }
8620        } catch (RemoteException e) {
8621            throw new SecurityException("Failed to verify package name ownership");
8622        }
8623
8624        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8625        synchronized (this) {
8626            if (incoming) {
8627                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8628                        callingUid);
8629                if (perms == null) {
8630                    Slog.w(TAG, "No permission grants found for " + packageName);
8631                } else {
8632                    for (UriPermission perm : perms.values()) {
8633                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8634                            result.add(perm.buildPersistedPublicApiObject());
8635                        }
8636                    }
8637                }
8638            } else {
8639                final int size = mGrantedUriPermissions.size();
8640                for (int i = 0; i < size; i++) {
8641                    final ArrayMap<GrantUri, UriPermission> perms =
8642                            mGrantedUriPermissions.valueAt(i);
8643                    for (UriPermission perm : perms.values()) {
8644                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8645                            result.add(perm.buildPersistedPublicApiObject());
8646                        }
8647                    }
8648                }
8649            }
8650        }
8651        return new ParceledListSlice<android.content.UriPermission>(result);
8652    }
8653
8654    @Override
8655    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8656            String packageName, int userId) {
8657        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8658                "getGrantedUriPermissions");
8659
8660        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8661        synchronized (this) {
8662            final int size = mGrantedUriPermissions.size();
8663            for (int i = 0; i < size; i++) {
8664                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8665                for (UriPermission perm : perms.values()) {
8666                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8667                            && perm.persistedModeFlags != 0) {
8668                        result.add(perm.buildPersistedPublicApiObject());
8669                    }
8670                }
8671            }
8672        }
8673        return new ParceledListSlice<android.content.UriPermission>(result);
8674    }
8675
8676    @Override
8677    public void clearGrantedUriPermissions(String packageName, int userId) {
8678        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8679                "clearGrantedUriPermissions");
8680        removeUriPermissionsForPackageLocked(packageName, userId, true);
8681    }
8682
8683    @Override
8684    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8685        synchronized (this) {
8686            ProcessRecord app =
8687                who != null ? getRecordForAppLocked(who) : null;
8688            if (app == null) return;
8689
8690            Message msg = Message.obtain();
8691            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8692            msg.obj = app;
8693            msg.arg1 = waiting ? 1 : 0;
8694            mUiHandler.sendMessage(msg);
8695        }
8696    }
8697
8698    @Override
8699    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8700        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8701        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8702        outInfo.availMem = Process.getFreeMemory();
8703        outInfo.totalMem = Process.getTotalMemory();
8704        outInfo.threshold = homeAppMem;
8705        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8706        outInfo.hiddenAppThreshold = cachedAppMem;
8707        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8708                ProcessList.SERVICE_ADJ);
8709        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8710                ProcessList.VISIBLE_APP_ADJ);
8711        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8712                ProcessList.FOREGROUND_APP_ADJ);
8713    }
8714
8715    // =========================================================
8716    // TASK MANAGEMENT
8717    // =========================================================
8718
8719    @Override
8720    public List<IAppTask> getAppTasks(String callingPackage) {
8721        int callingUid = Binder.getCallingUid();
8722        long ident = Binder.clearCallingIdentity();
8723
8724        synchronized(this) {
8725            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8726            try {
8727                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8728
8729                final int N = mRecentTasks.size();
8730                for (int i = 0; i < N; i++) {
8731                    TaskRecord tr = mRecentTasks.get(i);
8732                    // Skip tasks that do not match the caller.  We don't need to verify
8733                    // callingPackage, because we are also limiting to callingUid and know
8734                    // that will limit to the correct security sandbox.
8735                    if (tr.effectiveUid != callingUid) {
8736                        continue;
8737                    }
8738                    Intent intent = tr.getBaseIntent();
8739                    if (intent == null ||
8740                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8741                        continue;
8742                    }
8743                    ActivityManager.RecentTaskInfo taskInfo =
8744                            createRecentTaskInfoFromTaskRecord(tr);
8745                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8746                    list.add(taskImpl);
8747                }
8748            } finally {
8749                Binder.restoreCallingIdentity(ident);
8750            }
8751            return list;
8752        }
8753    }
8754
8755    @Override
8756    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8757        final int callingUid = Binder.getCallingUid();
8758        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8759
8760        synchronized(this) {
8761            if (DEBUG_ALL) Slog.v(
8762                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8763
8764            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8765                    callingUid);
8766
8767            // TODO: Improve with MRU list from all ActivityStacks.
8768            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8769        }
8770
8771        return list;
8772    }
8773
8774    /**
8775     * Creates a new RecentTaskInfo from a TaskRecord.
8776     */
8777    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8778        // Update the task description to reflect any changes in the task stack
8779        tr.updateTaskDescription();
8780
8781        // Compose the recent task info
8782        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8783        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8784        rti.persistentId = tr.taskId;
8785        rti.baseIntent = new Intent(tr.getBaseIntent());
8786        rti.origActivity = tr.origActivity;
8787        rti.realActivity = tr.realActivity;
8788        rti.description = tr.lastDescription;
8789        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8790        rti.userId = tr.userId;
8791        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8792        rti.firstActiveTime = tr.firstActiveTime;
8793        rti.lastActiveTime = tr.lastActiveTime;
8794        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8795        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8796        rti.numActivities = 0;
8797        if (tr.mBounds != null) {
8798            rti.bounds = new Rect(tr.mBounds);
8799        }
8800
8801        ActivityRecord base = null;
8802        ActivityRecord top = null;
8803        ActivityRecord tmp;
8804
8805        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8806            tmp = tr.mActivities.get(i);
8807            if (tmp.finishing) {
8808                continue;
8809            }
8810            base = tmp;
8811            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8812                top = base;
8813            }
8814            rti.numActivities++;
8815        }
8816
8817        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8818        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8819
8820        return rti;
8821    }
8822
8823    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8824        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8825                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8826        if (!allowed) {
8827            if (checkPermission(android.Manifest.permission.GET_TASKS,
8828                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8829                // Temporary compatibility: some existing apps on the system image may
8830                // still be requesting the old permission and not switched to the new
8831                // one; if so, we'll still allow them full access.  This means we need
8832                // to see if they are holding the old permission and are a system app.
8833                try {
8834                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8835                        allowed = true;
8836                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8837                                + " is using old GET_TASKS but privileged; allowing");
8838                    }
8839                } catch (RemoteException e) {
8840                }
8841            }
8842        }
8843        if (!allowed) {
8844            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8845                    + " does not hold REAL_GET_TASKS; limiting output");
8846        }
8847        return allowed;
8848    }
8849
8850    @Override
8851    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8852        final int callingUid = Binder.getCallingUid();
8853        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8854                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8855
8856        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8857        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8858        synchronized (this) {
8859            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8860                    callingUid);
8861            final boolean detailed = checkCallingPermission(
8862                    android.Manifest.permission.GET_DETAILED_TASKS)
8863                    == PackageManager.PERMISSION_GRANTED;
8864
8865            final int recentsCount = mRecentTasks.size();
8866            ArrayList<ActivityManager.RecentTaskInfo> res =
8867                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8868
8869            final Set<Integer> includedUsers;
8870            if (includeProfiles) {
8871                includedUsers = mUserController.getProfileIds(userId);
8872            } else {
8873                includedUsers = new HashSet<>();
8874            }
8875            includedUsers.add(Integer.valueOf(userId));
8876
8877            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8878                TaskRecord tr = mRecentTasks.get(i);
8879                // Only add calling user or related users recent tasks
8880                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8881                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8882                    continue;
8883                }
8884
8885                // Return the entry if desired by the caller.  We always return
8886                // the first entry, because callers always expect this to be the
8887                // foreground app.  We may filter others if the caller has
8888                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8889                // we should exclude the entry.
8890
8891                if (i == 0
8892                        || withExcluded
8893                        || (tr.intent == null)
8894                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8895                                == 0)) {
8896                    if (!allowed) {
8897                        // If the caller doesn't have the GET_TASKS permission, then only
8898                        // allow them to see a small subset of tasks -- their own and home.
8899                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8900                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8901                            continue;
8902                        }
8903                    }
8904                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8905                        if (tr.stack != null && tr.stack.isHomeStack()) {
8906                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8907                                    "Skipping, home stack task: " + tr);
8908                            continue;
8909                        }
8910                    }
8911                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8912                        if (tr.stack != null && tr.stack.isDockedStack()) {
8913                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8914                                    "Skipping, docked stack task: " + tr);
8915                            continue;
8916                        }
8917                    }
8918                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8919                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8920                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8921                                    "Skipping, pinned stack task: " + tr);
8922                            continue;
8923                        }
8924                    }
8925                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8926                        // Don't include auto remove tasks that are finished or finishing.
8927                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8928                                "Skipping, auto-remove without activity: " + tr);
8929                        continue;
8930                    }
8931                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8932                            && !tr.isAvailable) {
8933                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8934                                "Skipping, unavail real act: " + tr);
8935                        continue;
8936                    }
8937
8938                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8939                    if (!detailed) {
8940                        rti.baseIntent.replaceExtras((Bundle)null);
8941                    }
8942
8943                    res.add(rti);
8944                    maxNum--;
8945                }
8946            }
8947            return res;
8948        }
8949    }
8950
8951    @Override
8952    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8953        synchronized (this) {
8954            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8955                    "getTaskThumbnail()");
8956            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8957                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8958            if (tr != null) {
8959                return tr.getTaskThumbnailLocked();
8960            }
8961        }
8962        return null;
8963    }
8964
8965    @Override
8966    public int addAppTask(IBinder activityToken, Intent intent,
8967            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8968        final int callingUid = Binder.getCallingUid();
8969        final long callingIdent = Binder.clearCallingIdentity();
8970
8971        try {
8972            synchronized (this) {
8973                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8974                if (r == null) {
8975                    throw new IllegalArgumentException("Activity does not exist; token="
8976                            + activityToken);
8977                }
8978                ComponentName comp = intent.getComponent();
8979                if (comp == null) {
8980                    throw new IllegalArgumentException("Intent " + intent
8981                            + " must specify explicit component");
8982                }
8983                if (thumbnail.getWidth() != mThumbnailWidth
8984                        || thumbnail.getHeight() != mThumbnailHeight) {
8985                    throw new IllegalArgumentException("Bad thumbnail size: got "
8986                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8987                            + mThumbnailWidth + "x" + mThumbnailHeight);
8988                }
8989                if (intent.getSelector() != null) {
8990                    intent.setSelector(null);
8991                }
8992                if (intent.getSourceBounds() != null) {
8993                    intent.setSourceBounds(null);
8994                }
8995                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8996                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8997                        // The caller has added this as an auto-remove task...  that makes no
8998                        // sense, so turn off auto-remove.
8999                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9000                    }
9001                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9002                    // Must be a new task.
9003                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9004                }
9005                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9006                    mLastAddedTaskActivity = null;
9007                }
9008                ActivityInfo ainfo = mLastAddedTaskActivity;
9009                if (ainfo == null) {
9010                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9011                            comp, 0, UserHandle.getUserId(callingUid));
9012                    if (ainfo.applicationInfo.uid != callingUid) {
9013                        throw new SecurityException(
9014                                "Can't add task for another application: target uid="
9015                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9016                    }
9017                }
9018
9019                // Use the full screen as the context for the task thumbnail
9020                final Point displaySize = new Point();
9021                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9022                r.task.stack.getDisplaySize(displaySize);
9023                thumbnailInfo.taskWidth = displaySize.x;
9024                thumbnailInfo.taskHeight = displaySize.y;
9025                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9026
9027                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
9028                        intent, description, thumbnailInfo);
9029
9030                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9031                if (trimIdx >= 0) {
9032                    // If this would have caused a trim, then we'll abort because that
9033                    // means it would be added at the end of the list but then just removed.
9034                    return INVALID_TASK_ID;
9035                }
9036
9037                final int N = mRecentTasks.size();
9038                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9039                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9040                    tr.removedFromRecents();
9041                }
9042
9043                task.inRecents = true;
9044                mRecentTasks.add(task);
9045                r.task.stack.addTask(task, false, "addAppTask");
9046
9047                task.setLastThumbnailLocked(thumbnail);
9048                task.freeLastThumbnail();
9049
9050                return task.taskId;
9051            }
9052        } finally {
9053            Binder.restoreCallingIdentity(callingIdent);
9054        }
9055    }
9056
9057    @Override
9058    public Point getAppTaskThumbnailSize() {
9059        synchronized (this) {
9060            return new Point(mThumbnailWidth,  mThumbnailHeight);
9061        }
9062    }
9063
9064    @Override
9065    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9066        synchronized (this) {
9067            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9068            if (r != null) {
9069                r.setTaskDescription(td);
9070                r.task.updateTaskDescription();
9071            }
9072        }
9073    }
9074
9075    @Override
9076    public void setTaskResizeable(int taskId, boolean resizeable) {
9077        synchronized (this) {
9078            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9079                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9080            if (task == null) {
9081                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9082                return;
9083            }
9084            if (task.mResizeable != resizeable) {
9085                task.mResizeable = resizeable;
9086                mWindowManager.setTaskResizeable(taskId, resizeable);
9087                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9088                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9089            }
9090        }
9091    }
9092
9093    @Override
9094    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9095        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9096        long ident = Binder.clearCallingIdentity();
9097        try {
9098            synchronized (this) {
9099                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9100                if (task == null) {
9101                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9102                    return;
9103                }
9104                int stackId = task.stack.mStackId;
9105                // First, check if this is a non-resizeble task in docked stack or if the task size
9106                // is affected by the docked stack changing size. If so, instead of resizing, we
9107                // can only scroll the task. No need to update configuration.
9108                if (bounds != null && !task.mResizeable
9109                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9110                    mWindowManager.scrollTask(task.taskId, bounds);
9111                    return;
9112                }
9113
9114                // Place the task in the right stack if it isn't there already based on
9115                // the requested bounds.
9116                // The stack transition logic is:
9117                // - a null bounds on a freeform task moves that task to fullscreen
9118                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9119                //   that task to freeform
9120                // - otherwise the task is not moved
9121                if (!StackId.isTaskResizeAllowed(stackId)) {
9122                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9123                }
9124                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9125                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9126                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9127                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9128                }
9129                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9130                if (stackId != task.stack.mStackId) {
9131                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9132                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9133                    preserveWindow = false;
9134                }
9135
9136                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
9137            }
9138        } finally {
9139            Binder.restoreCallingIdentity(ident);
9140        }
9141    }
9142
9143    @Override
9144    public Rect getTaskBounds(int taskId) {
9145        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9146        long ident = Binder.clearCallingIdentity();
9147        Rect rect = new Rect();
9148        try {
9149            synchronized (this) {
9150                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9151                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9152                if (task == null) {
9153                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9154                    return rect;
9155                }
9156                if (task.stack != null) {
9157                    // Return the bounds from window manager since it will be adjusted for various
9158                    // things like the presense of a docked stack for tasks that aren't resizeable.
9159                    mWindowManager.getTaskBounds(task.taskId, rect);
9160                } else {
9161                    // Task isn't in window manager yet since it isn't associated with a stack.
9162                    // Return the persist value from activity manager
9163                    if (task.mBounds != null) {
9164                        rect.set(task.mBounds);
9165                    } else if (task.mLastNonFullscreenBounds != null) {
9166                        rect.set(task.mLastNonFullscreenBounds);
9167                    }
9168                }
9169            }
9170        } finally {
9171            Binder.restoreCallingIdentity(ident);
9172        }
9173        return rect;
9174    }
9175
9176    @Override
9177    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9178        if (userId != UserHandle.getCallingUserId()) {
9179            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9180                    "getTaskDescriptionIcon");
9181        }
9182        final File passedIconFile = new File(filePath);
9183        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9184                passedIconFile.getName());
9185        if (!legitIconFile.getPath().equals(filePath)
9186                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9187            throw new IllegalArgumentException("Bad file path: " + filePath);
9188        }
9189        return mTaskPersister.getTaskDescriptionIcon(filePath);
9190    }
9191
9192    @Override
9193    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9194            throws RemoteException {
9195        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9196                opts.getCustomInPlaceResId() == 0) {
9197            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9198                    "with valid animation");
9199        }
9200        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9201        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9202                opts.getCustomInPlaceResId());
9203        mWindowManager.executeAppTransition();
9204    }
9205
9206    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9207            boolean removeFromRecents) {
9208        if (removeFromRecents) {
9209            mRecentTasks.remove(tr);
9210            tr.removedFromRecents();
9211        }
9212        ComponentName component = tr.getBaseIntent().getComponent();
9213        if (component == null) {
9214            Slog.w(TAG, "No component for base intent of task: " + tr);
9215            return;
9216        }
9217
9218        // Find any running services associated with this app and stop if needed.
9219        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9220
9221        if (!killProcess) {
9222            return;
9223        }
9224
9225        // Determine if the process(es) for this task should be killed.
9226        final String pkg = component.getPackageName();
9227        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9228        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9229        for (int i = 0; i < pmap.size(); i++) {
9230
9231            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9232            for (int j = 0; j < uids.size(); j++) {
9233                ProcessRecord proc = uids.valueAt(j);
9234                if (proc.userId != tr.userId) {
9235                    // Don't kill process for a different user.
9236                    continue;
9237                }
9238                if (proc == mHomeProcess) {
9239                    // Don't kill the home process along with tasks from the same package.
9240                    continue;
9241                }
9242                if (!proc.pkgList.containsKey(pkg)) {
9243                    // Don't kill process that is not associated with this task.
9244                    continue;
9245                }
9246
9247                for (int k = 0; k < proc.activities.size(); k++) {
9248                    TaskRecord otherTask = proc.activities.get(k).task;
9249                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9250                        // Don't kill process(es) that has an activity in a different task that is
9251                        // also in recents.
9252                        return;
9253                    }
9254                }
9255
9256                if (proc.foregroundServices) {
9257                    // Don't kill process(es) with foreground service.
9258                    return;
9259                }
9260
9261                // Add process to kill list.
9262                procsToKill.add(proc);
9263            }
9264        }
9265
9266        // Kill the running processes.
9267        for (int i = 0; i < procsToKill.size(); i++) {
9268            ProcessRecord pr = procsToKill.get(i);
9269            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9270                    && pr.curReceiver == null) {
9271                pr.kill("remove task", true);
9272            } else {
9273                // We delay killing processes that are not in the background or running a receiver.
9274                pr.waitingToKill = "remove task";
9275            }
9276        }
9277    }
9278
9279    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9280        // Remove all tasks with activities in the specified package from the list of recent tasks
9281        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9282            TaskRecord tr = mRecentTasks.get(i);
9283            if (tr.userId != userId) continue;
9284
9285            ComponentName cn = tr.intent.getComponent();
9286            if (cn != null && cn.getPackageName().equals(packageName)) {
9287                // If the package name matches, remove the task.
9288                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9289            }
9290        }
9291    }
9292
9293    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9294            int userId) {
9295
9296        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9297            TaskRecord tr = mRecentTasks.get(i);
9298            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9299                continue;
9300            }
9301
9302            ComponentName cn = tr.intent.getComponent();
9303            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9304                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9305            if (sameComponent) {
9306                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9307            }
9308        }
9309    }
9310
9311    /**
9312     * Removes the task with the specified task id.
9313     *
9314     * @param taskId Identifier of the task to be removed.
9315     * @param killProcess Kill any process associated with the task if possible.
9316     * @param removeFromRecents Whether to also remove the task from recents.
9317     * @return Returns true if the given task was found and removed.
9318     */
9319    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9320            boolean removeFromRecents) {
9321        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9322                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9323        if (tr != null) {
9324            tr.removeTaskActivitiesLocked();
9325            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9326            if (tr.isPersistable) {
9327                notifyTaskPersisterLocked(null, true);
9328            }
9329            return true;
9330        }
9331        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9332        return false;
9333    }
9334
9335    @Override
9336    public boolean removeTask(int taskId) {
9337        synchronized (this) {
9338            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9339                    "removeTask()");
9340            long ident = Binder.clearCallingIdentity();
9341            try {
9342                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9343            } finally {
9344                Binder.restoreCallingIdentity(ident);
9345            }
9346        }
9347    }
9348
9349    /**
9350     * TODO: Add mController hook
9351     */
9352    @Override
9353    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9354        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9355
9356        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9357        synchronized(this) {
9358            moveTaskToFrontLocked(taskId, flags, bOptions);
9359        }
9360    }
9361
9362    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9363        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9364
9365        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9366                Binder.getCallingUid(), -1, -1, "Task to front")) {
9367            ActivityOptions.abort(options);
9368            return;
9369        }
9370        final long origId = Binder.clearCallingIdentity();
9371        try {
9372            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9373            if (task == null) {
9374                Slog.d(TAG, "Could not find task for id: "+ taskId);
9375                return;
9376            }
9377            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9378                mStackSupervisor.showLockTaskToast();
9379                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9380                return;
9381            }
9382            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9383            if (prev != null && prev.isRecentsActivity()) {
9384                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9385            }
9386            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9387        } finally {
9388            Binder.restoreCallingIdentity(origId);
9389        }
9390        ActivityOptions.abort(options);
9391    }
9392
9393    /**
9394     * Moves an activity, and all of the other activities within the same task, to the bottom
9395     * of the history stack.  The activity's order within the task is unchanged.
9396     *
9397     * @param token A reference to the activity we wish to move
9398     * @param nonRoot If false then this only works if the activity is the root
9399     *                of a task; if true it will work for any activity in a task.
9400     * @return Returns true if the move completed, false if not.
9401     */
9402    @Override
9403    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9404        enforceNotIsolatedCaller("moveActivityTaskToBack");
9405        synchronized(this) {
9406            final long origId = Binder.clearCallingIdentity();
9407            try {
9408                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9409                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9410                if (task != null) {
9411                    if (mStackSupervisor.isLockedTask(task)) {
9412                        mStackSupervisor.showLockTaskToast();
9413                        return false;
9414                    }
9415                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9416                }
9417            } finally {
9418                Binder.restoreCallingIdentity(origId);
9419            }
9420        }
9421        return false;
9422    }
9423
9424    @Override
9425    public void moveTaskBackwards(int task) {
9426        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9427                "moveTaskBackwards()");
9428
9429        synchronized(this) {
9430            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9431                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9432                return;
9433            }
9434            final long origId = Binder.clearCallingIdentity();
9435            moveTaskBackwardsLocked(task);
9436            Binder.restoreCallingIdentity(origId);
9437        }
9438    }
9439
9440    private final void moveTaskBackwardsLocked(int task) {
9441        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9442    }
9443
9444    @Override
9445    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9446            IActivityContainerCallback callback) throws RemoteException {
9447        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9448        synchronized (this) {
9449            if (parentActivityToken == null) {
9450                throw new IllegalArgumentException("parent token must not be null");
9451            }
9452            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9453            if (r == null) {
9454                return null;
9455            }
9456            if (callback == null) {
9457                throw new IllegalArgumentException("callback must not be null");
9458            }
9459            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9460        }
9461    }
9462
9463    @Override
9464    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9465        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9466        synchronized (this) {
9467            mStackSupervisor.deleteActivityContainer(container);
9468        }
9469    }
9470
9471    @Override
9472    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9473        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9474        synchronized (this) {
9475            final int stackId = mStackSupervisor.getNextStackId();
9476            final ActivityStack stack =
9477                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9478            if (stack == null) {
9479                return null;
9480            }
9481            return stack.mActivityContainer;
9482        }
9483    }
9484
9485    @Override
9486    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9487        synchronized (this) {
9488            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9489            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9490                return stack.mActivityContainer.getDisplayId();
9491            }
9492            return Display.DEFAULT_DISPLAY;
9493        }
9494    }
9495
9496    @Override
9497    public int getActivityStackId(IBinder token) throws RemoteException {
9498        synchronized (this) {
9499            ActivityStack stack = ActivityRecord.getStackLocked(token);
9500            if (stack == null) {
9501                return INVALID_STACK_ID;
9502            }
9503            return stack.mStackId;
9504        }
9505    }
9506
9507    @Override
9508    public void exitFreeformMode(IBinder token) throws RemoteException {
9509        synchronized (this) {
9510            long ident = Binder.clearCallingIdentity();
9511            try {
9512                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9513                if (r == null) {
9514                    throw new IllegalArgumentException(
9515                            "exitFreeformMode: No activity record matching token=" + token);
9516                }
9517                final ActivityStack stack = r.getStackLocked(token);
9518                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9519                    throw new IllegalStateException(
9520                            "exitFreeformMode: You can only go fullscreen from freeform.");
9521                }
9522                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9523                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9524                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9525            } finally {
9526                Binder.restoreCallingIdentity(ident);
9527            }
9528        }
9529    }
9530
9531    @Override
9532    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9533        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9534        if (stackId == HOME_STACK_ID) {
9535            throw new IllegalArgumentException(
9536                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9537        }
9538        synchronized (this) {
9539            long ident = Binder.clearCallingIdentity();
9540            try {
9541                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9542                        + " to stackId=" + stackId + " toTop=" + toTop);
9543                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9544                        "moveTaskToStack", ANIMATE);
9545            } finally {
9546                Binder.restoreCallingIdentity(ident);
9547            }
9548        }
9549    }
9550
9551    /**
9552     * Moves the input task to the docked stack.
9553     *
9554     * @param taskId Id of task to move.
9555     * @param createMode The mode the docked stack should be created in if it doesn't exist
9556     *                   already. See
9557     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9558     *                   and
9559     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9560     * @param toTop If the task and stack should be moved to the top.
9561     * @param animate Whether we should play an animation for the moving the task
9562     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9563     *                      docked stack. Pass {@code null} to use default bounds.
9564     */
9565    @Override
9566    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9567            Rect initialBounds) {
9568        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9569        synchronized (this) {
9570            long ident = Binder.clearCallingIdentity();
9571            try {
9572                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9573                        + " to createMode=" + createMode + " toTop=" + toTop);
9574                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9575                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9576                        "moveTaskToDockedStack", animate);
9577            } finally {
9578                Binder.restoreCallingIdentity(ident);
9579            }
9580        }
9581    }
9582
9583    /**
9584     * Moves the top activity in the input stackId to the pinned stack.
9585     *
9586     * @param stackId Id of stack to move the top activity to pinned stack.
9587     * @param bounds Bounds to use for pinned stack.
9588     *
9589     * @return True if the top activity of the input stack was successfully moved to the pinned
9590     *          stack.
9591     */
9592    @Override
9593    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9594        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9595        synchronized (this) {
9596            if (!mSupportsPictureInPicture) {
9597                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9598                        + "Device doesn't support picture-in-pciture mode");
9599            }
9600
9601            long ident = Binder.clearCallingIdentity();
9602            try {
9603                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9604            } finally {
9605                Binder.restoreCallingIdentity(ident);
9606            }
9607        }
9608    }
9609
9610    @Override
9611    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9613        long ident = Binder.clearCallingIdentity();
9614        try {
9615            synchronized (this) {
9616                mStackSupervisor.resizeStackLocked(
9617                        stackId, bounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
9618                        !PRESERVE_WINDOWS, allowResizeInDockedMode);
9619            }
9620        } finally {
9621            Binder.restoreCallingIdentity(ident);
9622        }
9623    }
9624
9625    @Override
9626    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9627            Rect tempDockedTaskInsetBounds,
9628            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9629        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9630                "resizeDockedStack()");
9631        long ident = Binder.clearCallingIdentity();
9632        try {
9633            synchronized (this) {
9634                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9635                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9636                        PRESERVE_WINDOWS);
9637            }
9638        } finally {
9639            Binder.restoreCallingIdentity(ident);
9640        }
9641    }
9642
9643    @Override
9644    public void positionTaskInStack(int taskId, int stackId, int position) {
9645        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9646        if (stackId == HOME_STACK_ID) {
9647            throw new IllegalArgumentException(
9648                    "positionTaskInStack: Attempt to change the position of task "
9649                    + taskId + " in/to home stack");
9650        }
9651        synchronized (this) {
9652            long ident = Binder.clearCallingIdentity();
9653            try {
9654                if (DEBUG_STACK) Slog.d(TAG_STACK,
9655                        "positionTaskInStack: positioning task=" + taskId
9656                        + " in stackId=" + stackId + " at position=" + position);
9657                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9658            } finally {
9659                Binder.restoreCallingIdentity(ident);
9660            }
9661        }
9662    }
9663
9664    @Override
9665    public List<StackInfo> getAllStackInfos() {
9666        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9667        long ident = Binder.clearCallingIdentity();
9668        try {
9669            synchronized (this) {
9670                return mStackSupervisor.getAllStackInfosLocked();
9671            }
9672        } finally {
9673            Binder.restoreCallingIdentity(ident);
9674        }
9675    }
9676
9677    @Override
9678    public StackInfo getStackInfo(int stackId) {
9679        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9680        long ident = Binder.clearCallingIdentity();
9681        try {
9682            synchronized (this) {
9683                return mStackSupervisor.getStackInfoLocked(stackId);
9684            }
9685        } finally {
9686            Binder.restoreCallingIdentity(ident);
9687        }
9688    }
9689
9690    @Override
9691    public boolean isInHomeStack(int taskId) {
9692        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9693        long ident = Binder.clearCallingIdentity();
9694        try {
9695            synchronized (this) {
9696                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9697                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9698                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9699            }
9700        } finally {
9701            Binder.restoreCallingIdentity(ident);
9702        }
9703    }
9704
9705    @Override
9706    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9707        synchronized(this) {
9708            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9709        }
9710    }
9711
9712    @Override
9713    public void updateDeviceOwner(String packageName) {
9714        final int callingUid = Binder.getCallingUid();
9715        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9716            throw new SecurityException("updateDeviceOwner called from non-system process");
9717        }
9718        synchronized (this) {
9719            mDeviceOwnerName = packageName;
9720        }
9721    }
9722
9723    @Override
9724    public void updateLockTaskPackages(int userId, String[] packages) {
9725        final int callingUid = Binder.getCallingUid();
9726        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9727            throw new SecurityException("updateLockTaskPackage called from non-system process");
9728        }
9729        synchronized (this) {
9730            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9731                    Arrays.toString(packages));
9732            mLockTaskPackages.put(userId, packages);
9733            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9734        }
9735    }
9736
9737
9738    void startLockTaskModeLocked(TaskRecord task) {
9739        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9740        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9741            return;
9742        }
9743
9744        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9745        // is initiated by system after the pinning request was shown and locked mode is initiated
9746        // by an authorized app directly
9747        final int callingUid = Binder.getCallingUid();
9748        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9749        long ident = Binder.clearCallingIdentity();
9750        try {
9751            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9752            if (!isSystemInitiated) {
9753                task.mLockTaskUid = callingUid;
9754                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9755                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9756                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9757                    StatusBarManagerInternal statusBarManager =
9758                            LocalServices.getService(StatusBarManagerInternal.class);
9759                    if (statusBarManager != null) {
9760                        statusBarManager.showScreenPinningRequest();
9761                    }
9762                    return;
9763                }
9764
9765                if (stack == null || task != stack.topTask()) {
9766                    throw new IllegalArgumentException("Invalid task, not in foreground");
9767                }
9768            }
9769            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9770                    "Locking fully");
9771            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9772                    ActivityManager.LOCK_TASK_MODE_PINNED :
9773                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9774                    "startLockTask", true);
9775        } finally {
9776            Binder.restoreCallingIdentity(ident);
9777        }
9778    }
9779
9780    @Override
9781    public void startLockTaskMode(int taskId) {
9782        synchronized (this) {
9783            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9784            if (task != null) {
9785                startLockTaskModeLocked(task);
9786            }
9787        }
9788    }
9789
9790    @Override
9791    public void startLockTaskMode(IBinder token) {
9792        synchronized (this) {
9793            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9794            if (r == null) {
9795                return;
9796            }
9797            final TaskRecord task = r.task;
9798            if (task != null) {
9799                startLockTaskModeLocked(task);
9800            }
9801        }
9802    }
9803
9804    @Override
9805    public void startLockTaskModeOnCurrent() throws RemoteException {
9806        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9807        long ident = Binder.clearCallingIdentity();
9808        try {
9809            synchronized (this) {
9810                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9811                if (r != null) {
9812                    startLockTaskModeLocked(r.task);
9813                }
9814            }
9815        } finally {
9816            Binder.restoreCallingIdentity(ident);
9817        }
9818    }
9819
9820    @Override
9821    public void stopLockTaskMode() {
9822        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9823        if (lockTask == null) {
9824            // Our work here is done.
9825            return;
9826        }
9827
9828        final int callingUid = Binder.getCallingUid();
9829        final int lockTaskUid = lockTask.mLockTaskUid;
9830        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9831        // It is possible lockTaskMode was started by the system process because
9832        // android:lockTaskMode is set to a locking value in the application manifest instead of
9833        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9834        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9835        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9836                callingUid != lockTaskUid
9837                && (lockTaskUid != 0
9838                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9839            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9840                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9841        }
9842
9843        long ident = Binder.clearCallingIdentity();
9844        try {
9845            Log.d(TAG, "stopLockTaskMode");
9846            // Stop lock task
9847            synchronized (this) {
9848                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9849                        "stopLockTask", true);
9850            }
9851        } finally {
9852            Binder.restoreCallingIdentity(ident);
9853        }
9854    }
9855
9856    @Override
9857    public void stopLockTaskModeOnCurrent() throws RemoteException {
9858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9859        long ident = Binder.clearCallingIdentity();
9860        try {
9861            stopLockTaskMode();
9862        } finally {
9863            Binder.restoreCallingIdentity(ident);
9864        }
9865    }
9866
9867    @Override
9868    public boolean isInLockTaskMode() {
9869        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9870    }
9871
9872    @Override
9873    public int getLockTaskModeState() {
9874        synchronized (this) {
9875            return mStackSupervisor.getLockTaskModeState();
9876        }
9877    }
9878
9879    @Override
9880    public void showLockTaskEscapeMessage(IBinder token) {
9881        synchronized (this) {
9882            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9883            if (r == null) {
9884                return;
9885            }
9886            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9887        }
9888    }
9889
9890    // =========================================================
9891    // CONTENT PROVIDERS
9892    // =========================================================
9893
9894    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9895        List<ProviderInfo> providers = null;
9896        try {
9897            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9898                    .queryContentProviders(app.processName, app.uid,
9899                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9900                                    | MATCH_DEBUG_TRIAGED_MISSING);
9901            providers = slice != null ? slice.getList() : null;
9902        } catch (RemoteException ex) {
9903        }
9904        if (DEBUG_MU) Slog.v(TAG_MU,
9905                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9906        int userId = app.userId;
9907        if (providers != null) {
9908            int N = providers.size();
9909            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9910            for (int i=0; i<N; i++) {
9911                ProviderInfo cpi =
9912                    (ProviderInfo)providers.get(i);
9913                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9914                        cpi.name, cpi.flags);
9915                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9916                    // This is a singleton provider, but a user besides the
9917                    // default user is asking to initialize a process it runs
9918                    // in...  well, no, it doesn't actually run in this process,
9919                    // it runs in the process of the default user.  Get rid of it.
9920                    providers.remove(i);
9921                    N--;
9922                    i--;
9923                    continue;
9924                }
9925
9926                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9927                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9928                if (cpr == null) {
9929                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9930                    mProviderMap.putProviderByClass(comp, cpr);
9931                }
9932                if (DEBUG_MU) Slog.v(TAG_MU,
9933                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9934                app.pubProviders.put(cpi.name, cpr);
9935                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9936                    // Don't add this if it is a platform component that is marked
9937                    // to run in multiple processes, because this is actually
9938                    // part of the framework so doesn't make sense to track as a
9939                    // separate apk in the process.
9940                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9941                            mProcessStats);
9942                }
9943                notifyPackageUse(cpi.applicationInfo.packageName);
9944            }
9945        }
9946        return providers;
9947    }
9948
9949    /**
9950     * Check if {@link ProcessRecord} has a possible chance at accessing the
9951     * given {@link ProviderInfo}. Final permission checking is always done
9952     * in {@link ContentProvider}.
9953     */
9954    private final String checkContentProviderPermissionLocked(
9955            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9956        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9957        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9958        boolean checkedGrants = false;
9959        if (checkUser) {
9960            // Looking for cross-user grants before enforcing the typical cross-users permissions
9961            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9962            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9963                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9964                    return null;
9965                }
9966                checkedGrants = true;
9967            }
9968            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9969                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9970            if (userId != tmpTargetUserId) {
9971                // When we actually went to determine the final targer user ID, this ended
9972                // up different than our initial check for the authority.  This is because
9973                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9974                // SELF.  So we need to re-check the grants again.
9975                checkedGrants = false;
9976            }
9977        }
9978        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9979                cpi.applicationInfo.uid, cpi.exported)
9980                == PackageManager.PERMISSION_GRANTED) {
9981            return null;
9982        }
9983        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9984                cpi.applicationInfo.uid, cpi.exported)
9985                == PackageManager.PERMISSION_GRANTED) {
9986            return null;
9987        }
9988
9989        PathPermission[] pps = cpi.pathPermissions;
9990        if (pps != null) {
9991            int i = pps.length;
9992            while (i > 0) {
9993                i--;
9994                PathPermission pp = pps[i];
9995                String pprperm = pp.getReadPermission();
9996                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9997                        cpi.applicationInfo.uid, cpi.exported)
9998                        == PackageManager.PERMISSION_GRANTED) {
9999                    return null;
10000                }
10001                String ppwperm = pp.getWritePermission();
10002                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10003                        cpi.applicationInfo.uid, cpi.exported)
10004                        == PackageManager.PERMISSION_GRANTED) {
10005                    return null;
10006                }
10007            }
10008        }
10009        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10010            return null;
10011        }
10012
10013        String msg;
10014        if (!cpi.exported) {
10015            msg = "Permission Denial: opening provider " + cpi.name
10016                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10017                    + ", uid=" + callingUid + ") that is not exported from uid "
10018                    + cpi.applicationInfo.uid;
10019        } else {
10020            msg = "Permission Denial: opening provider " + cpi.name
10021                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10022                    + ", uid=" + callingUid + ") requires "
10023                    + cpi.readPermission + " or " + cpi.writePermission;
10024        }
10025        Slog.w(TAG, msg);
10026        return msg;
10027    }
10028
10029    /**
10030     * Returns if the ContentProvider has granted a uri to callingUid
10031     */
10032    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10033        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10034        if (perms != null) {
10035            for (int i=perms.size()-1; i>=0; i--) {
10036                GrantUri grantUri = perms.keyAt(i);
10037                if (grantUri.sourceUserId == userId || !checkUser) {
10038                    if (matchesProvider(grantUri.uri, cpi)) {
10039                        return true;
10040                    }
10041                }
10042            }
10043        }
10044        return false;
10045    }
10046
10047    /**
10048     * Returns true if the uri authority is one of the authorities specified in the provider.
10049     */
10050    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10051        String uriAuth = uri.getAuthority();
10052        String cpiAuth = cpi.authority;
10053        if (cpiAuth.indexOf(';') == -1) {
10054            return cpiAuth.equals(uriAuth);
10055        }
10056        String[] cpiAuths = cpiAuth.split(";");
10057        int length = cpiAuths.length;
10058        for (int i = 0; i < length; i++) {
10059            if (cpiAuths[i].equals(uriAuth)) return true;
10060        }
10061        return false;
10062    }
10063
10064    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10065            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10066        if (r != null) {
10067            for (int i=0; i<r.conProviders.size(); i++) {
10068                ContentProviderConnection conn = r.conProviders.get(i);
10069                if (conn.provider == cpr) {
10070                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10071                            "Adding provider requested by "
10072                            + r.processName + " from process "
10073                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10074                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10075                    if (stable) {
10076                        conn.stableCount++;
10077                        conn.numStableIncs++;
10078                    } else {
10079                        conn.unstableCount++;
10080                        conn.numUnstableIncs++;
10081                    }
10082                    return conn;
10083                }
10084            }
10085            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10086            if (stable) {
10087                conn.stableCount = 1;
10088                conn.numStableIncs = 1;
10089            } else {
10090                conn.unstableCount = 1;
10091                conn.numUnstableIncs = 1;
10092            }
10093            cpr.connections.add(conn);
10094            r.conProviders.add(conn);
10095            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10096            return conn;
10097        }
10098        cpr.addExternalProcessHandleLocked(externalProcessToken);
10099        return null;
10100    }
10101
10102    boolean decProviderCountLocked(ContentProviderConnection conn,
10103            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10104        if (conn != null) {
10105            cpr = conn.provider;
10106            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10107                    "Removing provider requested by "
10108                    + conn.client.processName + " from process "
10109                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10110                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10111            if (stable) {
10112                conn.stableCount--;
10113            } else {
10114                conn.unstableCount--;
10115            }
10116            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10117                cpr.connections.remove(conn);
10118                conn.client.conProviders.remove(conn);
10119                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10120                    // The client is more important than last activity -- note the time this
10121                    // is happening, so we keep the old provider process around a bit as last
10122                    // activity to avoid thrashing it.
10123                    if (cpr.proc != null) {
10124                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10125                    }
10126                }
10127                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10128                return true;
10129            }
10130            return false;
10131        }
10132        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10133        return false;
10134    }
10135
10136    private void checkTime(long startTime, String where) {
10137        long now = SystemClock.elapsedRealtime();
10138        if ((now-startTime) > 1000) {
10139            // If we are taking more than a second, log about it.
10140            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10141        }
10142    }
10143
10144    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10145            String name, IBinder token, boolean stable, int userId) {
10146        ContentProviderRecord cpr;
10147        ContentProviderConnection conn = null;
10148        ProviderInfo cpi = null;
10149
10150        synchronized(this) {
10151            long startTime = SystemClock.elapsedRealtime();
10152
10153            ProcessRecord r = null;
10154            if (caller != null) {
10155                r = getRecordForAppLocked(caller);
10156                if (r == null) {
10157                    throw new SecurityException(
10158                            "Unable to find app for caller " + caller
10159                          + " (pid=" + Binder.getCallingPid()
10160                          + ") when getting content provider " + name);
10161                }
10162            }
10163
10164            boolean checkCrossUser = true;
10165
10166            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10167
10168            // First check if this content provider has been published...
10169            cpr = mProviderMap.getProviderByName(name, userId);
10170            // If that didn't work, check if it exists for user 0 and then
10171            // verify that it's a singleton provider before using it.
10172            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10173                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10174                if (cpr != null) {
10175                    cpi = cpr.info;
10176                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10177                            cpi.name, cpi.flags)
10178                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10179                        userId = UserHandle.USER_SYSTEM;
10180                        checkCrossUser = false;
10181                    } else {
10182                        cpr = null;
10183                        cpi = null;
10184                    }
10185                }
10186            }
10187
10188            boolean providerRunning = cpr != null;
10189            if (providerRunning) {
10190                cpi = cpr.info;
10191                String msg;
10192                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10193                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10194                        != null) {
10195                    throw new SecurityException(msg);
10196                }
10197                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10198
10199                if (r != null && cpr.canRunHere(r)) {
10200                    // This provider has been published or is in the process
10201                    // of being published...  but it is also allowed to run
10202                    // in the caller's process, so don't make a connection
10203                    // and just let the caller instantiate its own instance.
10204                    ContentProviderHolder holder = cpr.newHolder(null);
10205                    // don't give caller the provider object, it needs
10206                    // to make its own.
10207                    holder.provider = null;
10208                    return holder;
10209                }
10210
10211                final long origId = Binder.clearCallingIdentity();
10212
10213                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10214
10215                // In this case the provider instance already exists, so we can
10216                // return it right away.
10217                conn = incProviderCountLocked(r, cpr, token, stable);
10218                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10219                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10220                        // If this is a perceptible app accessing the provider,
10221                        // make sure to count it as being accessed and thus
10222                        // back up on the LRU list.  This is good because
10223                        // content providers are often expensive to start.
10224                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10225                        updateLruProcessLocked(cpr.proc, false, null);
10226                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10227                    }
10228                }
10229
10230                if (cpr.proc != null) {
10231                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10232                    boolean success = updateOomAdjLocked(cpr.proc);
10233                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10234                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10235                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10236                    // NOTE: there is still a race here where a signal could be
10237                    // pending on the process even though we managed to update its
10238                    // adj level.  Not sure what to do about this, but at least
10239                    // the race is now smaller.
10240                    if (!success) {
10241                        // Uh oh...  it looks like the provider's process
10242                        // has been killed on us.  We need to wait for a new
10243                        // process to be started, and make sure its death
10244                        // doesn't kill our process.
10245                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10246                                + " is crashing; detaching " + r);
10247                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10248                        checkTime(startTime, "getContentProviderImpl: before appDied");
10249                        appDiedLocked(cpr.proc);
10250                        checkTime(startTime, "getContentProviderImpl: after appDied");
10251                        if (!lastRef) {
10252                            // This wasn't the last ref our process had on
10253                            // the provider...  we have now been killed, bail.
10254                            return null;
10255                        }
10256                        providerRunning = false;
10257                        conn = null;
10258                    }
10259                }
10260
10261                Binder.restoreCallingIdentity(origId);
10262            }
10263
10264            if (!providerRunning) {
10265                try {
10266                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10267                    cpi = AppGlobals.getPackageManager().
10268                        resolveContentProvider(name,
10269                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10270                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10271                } catch (RemoteException ex) {
10272                }
10273                if (cpi == null) {
10274                    return null;
10275                }
10276                // If the provider is a singleton AND
10277                // (it's a call within the same user || the provider is a
10278                // privileged app)
10279                // Then allow connecting to the singleton provider
10280                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10281                        cpi.name, cpi.flags)
10282                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10283                if (singleton) {
10284                    userId = UserHandle.USER_SYSTEM;
10285                }
10286                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10287                checkTime(startTime, "getContentProviderImpl: got app info for user");
10288
10289                String msg;
10290                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10291                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10292                        != null) {
10293                    throw new SecurityException(msg);
10294                }
10295                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10296
10297                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10298                        && !cpi.processName.equals("system")) {
10299                    // If this content provider does not run in the system
10300                    // process, and the system is not yet ready to run other
10301                    // processes, then fail fast instead of hanging.
10302                    throw new IllegalArgumentException(
10303                            "Attempt to launch content provider before system ready");
10304                }
10305
10306                // Make sure that the user who owns this provider is running.  If not,
10307                // we don't want to allow it to run.
10308                if (!mUserController.isUserRunningLocked(userId, 0)) {
10309                    Slog.w(TAG, "Unable to launch app "
10310                            + cpi.applicationInfo.packageName + "/"
10311                            + cpi.applicationInfo.uid + " for provider "
10312                            + name + ": user " + userId + " is stopped");
10313                    return null;
10314                }
10315
10316                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10317                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10318                cpr = mProviderMap.getProviderByClass(comp, userId);
10319                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10320                final boolean firstClass = cpr == null;
10321                if (firstClass) {
10322                    final long ident = Binder.clearCallingIdentity();
10323
10324                    // If permissions need a review before any of the app components can run,
10325                    // we return no provider and launch a review activity if the calling app
10326                    // is in the foreground.
10327                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10328                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10329                            return null;
10330                        }
10331                    }
10332
10333                    try {
10334                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10335                        ApplicationInfo ai =
10336                            AppGlobals.getPackageManager().
10337                                getApplicationInfo(
10338                                        cpi.applicationInfo.packageName,
10339                                        STOCK_PM_FLAGS, userId);
10340                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10341                        if (ai == null) {
10342                            Slog.w(TAG, "No package info for content provider "
10343                                    + cpi.name);
10344                            return null;
10345                        }
10346                        ai = getAppInfoForUser(ai, userId);
10347                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10348                    } catch (RemoteException ex) {
10349                        // pm is in same process, this will never happen.
10350                    } finally {
10351                        Binder.restoreCallingIdentity(ident);
10352                    }
10353                }
10354
10355                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10356
10357                if (r != null && cpr.canRunHere(r)) {
10358                    // If this is a multiprocess provider, then just return its
10359                    // info and allow the caller to instantiate it.  Only do
10360                    // this if the provider is the same user as the caller's
10361                    // process, or can run as root (so can be in any process).
10362                    return cpr.newHolder(null);
10363                }
10364
10365                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10366                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10367                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10368
10369                // This is single process, and our app is now connecting to it.
10370                // See if we are already in the process of launching this
10371                // provider.
10372                final int N = mLaunchingProviders.size();
10373                int i;
10374                for (i = 0; i < N; i++) {
10375                    if (mLaunchingProviders.get(i) == cpr) {
10376                        break;
10377                    }
10378                }
10379
10380                // If the provider is not already being launched, then get it
10381                // started.
10382                if (i >= N) {
10383                    final long origId = Binder.clearCallingIdentity();
10384
10385                    try {
10386                        // Content provider is now in use, its package can't be stopped.
10387                        try {
10388                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10389                            AppGlobals.getPackageManager().setPackageStoppedState(
10390                                    cpr.appInfo.packageName, false, userId);
10391                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10392                        } catch (RemoteException e) {
10393                        } catch (IllegalArgumentException e) {
10394                            Slog.w(TAG, "Failed trying to unstop package "
10395                                    + cpr.appInfo.packageName + ": " + e);
10396                        }
10397
10398                        // Use existing process if already started
10399                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10400                        ProcessRecord proc = getProcessRecordLocked(
10401                                cpi.processName, cpr.appInfo.uid, false);
10402                        if (proc != null && proc.thread != null) {
10403                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10404                                    "Installing in existing process " + proc);
10405                            if (!proc.pubProviders.containsKey(cpi.name)) {
10406                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10407                                proc.pubProviders.put(cpi.name, cpr);
10408                                try {
10409                                    proc.thread.scheduleInstallProvider(cpi);
10410                                } catch (RemoteException e) {
10411                                }
10412                            }
10413                        } else {
10414                            checkTime(startTime, "getContentProviderImpl: before start process");
10415                            proc = startProcessLocked(cpi.processName,
10416                                    cpr.appInfo, false, 0, "content provider",
10417                                    new ComponentName(cpi.applicationInfo.packageName,
10418                                            cpi.name), false, false, false);
10419                            checkTime(startTime, "getContentProviderImpl: after start process");
10420                            if (proc == null) {
10421                                Slog.w(TAG, "Unable to launch app "
10422                                        + cpi.applicationInfo.packageName + "/"
10423                                        + cpi.applicationInfo.uid + " for provider "
10424                                        + name + ": process is bad");
10425                                return null;
10426                            }
10427                        }
10428                        cpr.launchingApp = proc;
10429                        mLaunchingProviders.add(cpr);
10430                    } finally {
10431                        Binder.restoreCallingIdentity(origId);
10432                    }
10433                }
10434
10435                checkTime(startTime, "getContentProviderImpl: updating data structures");
10436
10437                // Make sure the provider is published (the same provider class
10438                // may be published under multiple names).
10439                if (firstClass) {
10440                    mProviderMap.putProviderByClass(comp, cpr);
10441                }
10442
10443                mProviderMap.putProviderByName(name, cpr);
10444                conn = incProviderCountLocked(r, cpr, token, stable);
10445                if (conn != null) {
10446                    conn.waiting = true;
10447                }
10448            }
10449            checkTime(startTime, "getContentProviderImpl: done!");
10450        }
10451
10452        // Wait for the provider to be published...
10453        synchronized (cpr) {
10454            while (cpr.provider == null) {
10455                if (cpr.launchingApp == null) {
10456                    Slog.w(TAG, "Unable to launch app "
10457                            + cpi.applicationInfo.packageName + "/"
10458                            + cpi.applicationInfo.uid + " for provider "
10459                            + name + ": launching app became null");
10460                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10461                            UserHandle.getUserId(cpi.applicationInfo.uid),
10462                            cpi.applicationInfo.packageName,
10463                            cpi.applicationInfo.uid, name);
10464                    return null;
10465                }
10466                try {
10467                    if (DEBUG_MU) Slog.v(TAG_MU,
10468                            "Waiting to start provider " + cpr
10469                            + " launchingApp=" + cpr.launchingApp);
10470                    if (conn != null) {
10471                        conn.waiting = true;
10472                    }
10473                    cpr.wait();
10474                } catch (InterruptedException ex) {
10475                } finally {
10476                    if (conn != null) {
10477                        conn.waiting = false;
10478                    }
10479                }
10480            }
10481        }
10482        return cpr != null ? cpr.newHolder(conn) : null;
10483    }
10484
10485    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10486            ProcessRecord r, final int userId) {
10487        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10488                cpi.packageName, r.userId)) {
10489
10490            final boolean callerForeground = r != null ? r.setSchedGroup
10491                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10492
10493            // Show a permission review UI only for starting from a foreground app
10494            if (!callerForeground) {
10495                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10496                        + cpi.packageName + " requires a permissions review");
10497                return false;
10498            }
10499
10500            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10501            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10502                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10503            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10504
10505            if (DEBUG_PERMISSIONS_REVIEW) {
10506                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10507                        + "for package " + cpi.packageName);
10508            }
10509
10510            final UserHandle userHandle = new UserHandle(userId);
10511            mHandler.post(new Runnable() {
10512                @Override
10513                public void run() {
10514                    mContext.startActivityAsUser(intent, userHandle);
10515                }
10516            });
10517
10518            return false;
10519        }
10520
10521        return true;
10522    }
10523
10524    PackageManagerInternal getPackageManagerInternalLocked() {
10525        if (mPackageManagerInt == null) {
10526            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10527        }
10528        return mPackageManagerInt;
10529    }
10530
10531    @Override
10532    public final ContentProviderHolder getContentProvider(
10533            IApplicationThread caller, String name, int userId, boolean stable) {
10534        enforceNotIsolatedCaller("getContentProvider");
10535        if (caller == null) {
10536            String msg = "null IApplicationThread when getting content provider "
10537                    + name;
10538            Slog.w(TAG, msg);
10539            throw new SecurityException(msg);
10540        }
10541        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10542        // with cross-user grant.
10543        return getContentProviderImpl(caller, name, null, stable, userId);
10544    }
10545
10546    public ContentProviderHolder getContentProviderExternal(
10547            String name, int userId, IBinder token) {
10548        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10549            "Do not have permission in call getContentProviderExternal()");
10550        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10551                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10552        return getContentProviderExternalUnchecked(name, token, userId);
10553    }
10554
10555    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10556            IBinder token, int userId) {
10557        return getContentProviderImpl(null, name, token, true, userId);
10558    }
10559
10560    /**
10561     * Drop a content provider from a ProcessRecord's bookkeeping
10562     */
10563    public void removeContentProvider(IBinder connection, boolean stable) {
10564        enforceNotIsolatedCaller("removeContentProvider");
10565        long ident = Binder.clearCallingIdentity();
10566        try {
10567            synchronized (this) {
10568                ContentProviderConnection conn;
10569                try {
10570                    conn = (ContentProviderConnection)connection;
10571                } catch (ClassCastException e) {
10572                    String msg ="removeContentProvider: " + connection
10573                            + " not a ContentProviderConnection";
10574                    Slog.w(TAG, msg);
10575                    throw new IllegalArgumentException(msg);
10576                }
10577                if (conn == null) {
10578                    throw new NullPointerException("connection is null");
10579                }
10580                if (decProviderCountLocked(conn, null, null, stable)) {
10581                    updateOomAdjLocked();
10582                }
10583            }
10584        } finally {
10585            Binder.restoreCallingIdentity(ident);
10586        }
10587    }
10588
10589    public void removeContentProviderExternal(String name, IBinder token) {
10590        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10591            "Do not have permission in call removeContentProviderExternal()");
10592        int userId = UserHandle.getCallingUserId();
10593        long ident = Binder.clearCallingIdentity();
10594        try {
10595            removeContentProviderExternalUnchecked(name, token, userId);
10596        } finally {
10597            Binder.restoreCallingIdentity(ident);
10598        }
10599    }
10600
10601    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10602        synchronized (this) {
10603            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10604            if(cpr == null) {
10605                //remove from mProvidersByClass
10606                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10607                return;
10608            }
10609
10610            //update content provider record entry info
10611            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10612            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10613            if (localCpr.hasExternalProcessHandles()) {
10614                if (localCpr.removeExternalProcessHandleLocked(token)) {
10615                    updateOomAdjLocked();
10616                } else {
10617                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10618                            + " with no external reference for token: "
10619                            + token + ".");
10620                }
10621            } else {
10622                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10623                        + " with no external references.");
10624            }
10625        }
10626    }
10627
10628    public final void publishContentProviders(IApplicationThread caller,
10629            List<ContentProviderHolder> providers) {
10630        if (providers == null) {
10631            return;
10632        }
10633
10634        enforceNotIsolatedCaller("publishContentProviders");
10635        synchronized (this) {
10636            final ProcessRecord r = getRecordForAppLocked(caller);
10637            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10638            if (r == null) {
10639                throw new SecurityException(
10640                        "Unable to find app for caller " + caller
10641                      + " (pid=" + Binder.getCallingPid()
10642                      + ") when publishing content providers");
10643            }
10644
10645            final long origId = Binder.clearCallingIdentity();
10646
10647            final int N = providers.size();
10648            for (int i = 0; i < N; i++) {
10649                ContentProviderHolder src = providers.get(i);
10650                if (src == null || src.info == null || src.provider == null) {
10651                    continue;
10652                }
10653                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10654                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10655                if (dst != null) {
10656                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10657                    mProviderMap.putProviderByClass(comp, dst);
10658                    String names[] = dst.info.authority.split(";");
10659                    for (int j = 0; j < names.length; j++) {
10660                        mProviderMap.putProviderByName(names[j], dst);
10661                    }
10662
10663                    int launchingCount = mLaunchingProviders.size();
10664                    int j;
10665                    boolean wasInLaunchingProviders = false;
10666                    for (j = 0; j < launchingCount; j++) {
10667                        if (mLaunchingProviders.get(j) == dst) {
10668                            mLaunchingProviders.remove(j);
10669                            wasInLaunchingProviders = true;
10670                            j--;
10671                            launchingCount--;
10672                        }
10673                    }
10674                    if (wasInLaunchingProviders) {
10675                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10676                    }
10677                    synchronized (dst) {
10678                        dst.provider = src.provider;
10679                        dst.proc = r;
10680                        dst.notifyAll();
10681                    }
10682                    updateOomAdjLocked(r);
10683                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10684                            src.info.authority);
10685                }
10686            }
10687
10688            Binder.restoreCallingIdentity(origId);
10689        }
10690    }
10691
10692    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10693        ContentProviderConnection conn;
10694        try {
10695            conn = (ContentProviderConnection)connection;
10696        } catch (ClassCastException e) {
10697            String msg ="refContentProvider: " + connection
10698                    + " not a ContentProviderConnection";
10699            Slog.w(TAG, msg);
10700            throw new IllegalArgumentException(msg);
10701        }
10702        if (conn == null) {
10703            throw new NullPointerException("connection is null");
10704        }
10705
10706        synchronized (this) {
10707            if (stable > 0) {
10708                conn.numStableIncs += stable;
10709            }
10710            stable = conn.stableCount + stable;
10711            if (stable < 0) {
10712                throw new IllegalStateException("stableCount < 0: " + stable);
10713            }
10714
10715            if (unstable > 0) {
10716                conn.numUnstableIncs += unstable;
10717            }
10718            unstable = conn.unstableCount + unstable;
10719            if (unstable < 0) {
10720                throw new IllegalStateException("unstableCount < 0: " + unstable);
10721            }
10722
10723            if ((stable+unstable) <= 0) {
10724                throw new IllegalStateException("ref counts can't go to zero here: stable="
10725                        + stable + " unstable=" + unstable);
10726            }
10727            conn.stableCount = stable;
10728            conn.unstableCount = unstable;
10729            return !conn.dead;
10730        }
10731    }
10732
10733    public void unstableProviderDied(IBinder connection) {
10734        ContentProviderConnection conn;
10735        try {
10736            conn = (ContentProviderConnection)connection;
10737        } catch (ClassCastException e) {
10738            String msg ="refContentProvider: " + connection
10739                    + " not a ContentProviderConnection";
10740            Slog.w(TAG, msg);
10741            throw new IllegalArgumentException(msg);
10742        }
10743        if (conn == null) {
10744            throw new NullPointerException("connection is null");
10745        }
10746
10747        // Safely retrieve the content provider associated with the connection.
10748        IContentProvider provider;
10749        synchronized (this) {
10750            provider = conn.provider.provider;
10751        }
10752
10753        if (provider == null) {
10754            // Um, yeah, we're way ahead of you.
10755            return;
10756        }
10757
10758        // Make sure the caller is being honest with us.
10759        if (provider.asBinder().pingBinder()) {
10760            // Er, no, still looks good to us.
10761            synchronized (this) {
10762                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10763                        + " says " + conn + " died, but we don't agree");
10764                return;
10765            }
10766        }
10767
10768        // Well look at that!  It's dead!
10769        synchronized (this) {
10770            if (conn.provider.provider != provider) {
10771                // But something changed...  good enough.
10772                return;
10773            }
10774
10775            ProcessRecord proc = conn.provider.proc;
10776            if (proc == null || proc.thread == null) {
10777                // Seems like the process is already cleaned up.
10778                return;
10779            }
10780
10781            // As far as we're concerned, this is just like receiving a
10782            // death notification...  just a bit prematurely.
10783            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10784                    + ") early provider death");
10785            final long ident = Binder.clearCallingIdentity();
10786            try {
10787                appDiedLocked(proc);
10788            } finally {
10789                Binder.restoreCallingIdentity(ident);
10790            }
10791        }
10792    }
10793
10794    @Override
10795    public void appNotRespondingViaProvider(IBinder connection) {
10796        enforceCallingPermission(
10797                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10798
10799        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10800        if (conn == null) {
10801            Slog.w(TAG, "ContentProviderConnection is null");
10802            return;
10803        }
10804
10805        final ProcessRecord host = conn.provider.proc;
10806        if (host == null) {
10807            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10808            return;
10809        }
10810
10811        final long token = Binder.clearCallingIdentity();
10812        try {
10813            appNotResponding(host, null, null, false, "ContentProvider not responding");
10814        } finally {
10815            Binder.restoreCallingIdentity(token);
10816        }
10817    }
10818
10819    public final void installSystemProviders() {
10820        List<ProviderInfo> providers;
10821        synchronized (this) {
10822            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10823            providers = generateApplicationProvidersLocked(app);
10824            if (providers != null) {
10825                for (int i=providers.size()-1; i>=0; i--) {
10826                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10827                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10828                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10829                                + ": not system .apk");
10830                        providers.remove(i);
10831                    }
10832                }
10833            }
10834        }
10835        if (providers != null) {
10836            mSystemThread.installSystemProviders(providers);
10837        }
10838
10839        mCoreSettingsObserver = new CoreSettingsObserver(this);
10840
10841        //mUsageStatsService.monitorPackages();
10842    }
10843
10844    /**
10845     * When a user is unlocked, we need to install encryption-unaware providers
10846     * belonging to any running apps.
10847     */
10848    private void installEncryptionUnawareProviders(int userId) {
10849        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10850            // TODO: eventually pivot this back to look at current user state,
10851            // similar to the comment in UserManager.isUserUnlocked(), but for
10852            // now, if we started apps when "unlocked" then unaware providers
10853            // have already been spun up.
10854            return;
10855        }
10856
10857        synchronized (this) {
10858            final int NP = mProcessNames.getMap().size();
10859            for (int ip = 0; ip < NP; ip++) {
10860                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10861                final int NA = apps.size();
10862                for (int ia = 0; ia < NA; ia++) {
10863                    final ProcessRecord app = apps.valueAt(ia);
10864                    if (app.userId != userId || app.thread == null) continue;
10865
10866                    final int NG = app.pkgList.size();
10867                    for (int ig = 0; ig < NG; ig++) {
10868                        try {
10869                            final String pkgName = app.pkgList.keyAt(ig);
10870                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10871                                    .getPackageInfo(pkgName,
10872                                            GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE, userId);
10873                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10874                                for (ProviderInfo provInfo : pkgInfo.providers) {
10875                                    Log.v(TAG, "Installing " + provInfo);
10876                                    app.thread.scheduleInstallProvider(provInfo);
10877                                }
10878                            }
10879                        } catch (RemoteException ignored) {
10880                        }
10881                    }
10882                }
10883            }
10884        }
10885    }
10886
10887    /**
10888     * Allows apps to retrieve the MIME type of a URI.
10889     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10890     * users, then it does not need permission to access the ContentProvider.
10891     * Either, it needs cross-user uri grants.
10892     *
10893     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10894     *
10895     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10896     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10897     */
10898    public String getProviderMimeType(Uri uri, int userId) {
10899        enforceNotIsolatedCaller("getProviderMimeType");
10900        final String name = uri.getAuthority();
10901        int callingUid = Binder.getCallingUid();
10902        int callingPid = Binder.getCallingPid();
10903        long ident = 0;
10904        boolean clearedIdentity = false;
10905        synchronized (this) {
10906            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10907        }
10908        if (canClearIdentity(callingPid, callingUid, userId)) {
10909            clearedIdentity = true;
10910            ident = Binder.clearCallingIdentity();
10911        }
10912        ContentProviderHolder holder = null;
10913        try {
10914            holder = getContentProviderExternalUnchecked(name, null, userId);
10915            if (holder != null) {
10916                return holder.provider.getType(uri);
10917            }
10918        } catch (RemoteException e) {
10919            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10920            return null;
10921        } finally {
10922            // We need to clear the identity to call removeContentProviderExternalUnchecked
10923            if (!clearedIdentity) {
10924                ident = Binder.clearCallingIdentity();
10925            }
10926            try {
10927                if (holder != null) {
10928                    removeContentProviderExternalUnchecked(name, null, userId);
10929                }
10930            } finally {
10931                Binder.restoreCallingIdentity(ident);
10932            }
10933        }
10934
10935        return null;
10936    }
10937
10938    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10939        if (UserHandle.getUserId(callingUid) == userId) {
10940            return true;
10941        }
10942        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10943                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10944                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10945                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10946                return true;
10947        }
10948        return false;
10949    }
10950
10951    // =========================================================
10952    // GLOBAL MANAGEMENT
10953    // =========================================================
10954
10955    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10956            boolean isolated, int isolatedUid) {
10957        String proc = customProcess != null ? customProcess : info.processName;
10958        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10959        final int userId = UserHandle.getUserId(info.uid);
10960        int uid = info.uid;
10961        if (isolated) {
10962            if (isolatedUid == 0) {
10963                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10964                while (true) {
10965                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10966                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10967                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10968                    }
10969                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10970                    mNextIsolatedProcessUid++;
10971                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10972                        // No process for this uid, use it.
10973                        break;
10974                    }
10975                    stepsLeft--;
10976                    if (stepsLeft <= 0) {
10977                        return null;
10978                    }
10979                }
10980            } else {
10981                // Special case for startIsolatedProcess (internal only), where
10982                // the uid of the isolated process is specified by the caller.
10983                uid = isolatedUid;
10984            }
10985        }
10986        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10987        if (!mBooted && !mBooting
10988                && userId == UserHandle.USER_SYSTEM
10989                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10990            r.persistent = true;
10991        }
10992        addProcessNameLocked(r);
10993        return r;
10994    }
10995
10996    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10997            String abiOverride) {
10998        ProcessRecord app;
10999        if (!isolated) {
11000            app = getProcessRecordLocked(info.processName, info.uid, true);
11001        } else {
11002            app = null;
11003        }
11004
11005        if (app == null) {
11006            app = newProcessRecordLocked(info, null, isolated, 0);
11007            updateLruProcessLocked(app, false, null);
11008            updateOomAdjLocked();
11009        }
11010
11011        // This package really, really can not be stopped.
11012        try {
11013            AppGlobals.getPackageManager().setPackageStoppedState(
11014                    info.packageName, false, UserHandle.getUserId(app.uid));
11015        } catch (RemoteException e) {
11016        } catch (IllegalArgumentException e) {
11017            Slog.w(TAG, "Failed trying to unstop package "
11018                    + info.packageName + ": " + e);
11019        }
11020
11021        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11022            app.persistent = true;
11023            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11024        }
11025        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11026            mPersistentStartingProcesses.add(app);
11027            startProcessLocked(app, "added application", app.processName, abiOverride,
11028                    null /* entryPoint */, null /* entryPointArgs */);
11029        }
11030
11031        return app;
11032    }
11033
11034    public void unhandledBack() {
11035        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11036                "unhandledBack()");
11037
11038        synchronized(this) {
11039            final long origId = Binder.clearCallingIdentity();
11040            try {
11041                getFocusedStack().unhandledBackLocked();
11042            } finally {
11043                Binder.restoreCallingIdentity(origId);
11044            }
11045        }
11046    }
11047
11048    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11049        enforceNotIsolatedCaller("openContentUri");
11050        final int userId = UserHandle.getCallingUserId();
11051        String name = uri.getAuthority();
11052        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11053        ParcelFileDescriptor pfd = null;
11054        if (cph != null) {
11055            // We record the binder invoker's uid in thread-local storage before
11056            // going to the content provider to open the file.  Later, in the code
11057            // that handles all permissions checks, we look for this uid and use
11058            // that rather than the Activity Manager's own uid.  The effect is that
11059            // we do the check against the caller's permissions even though it looks
11060            // to the content provider like the Activity Manager itself is making
11061            // the request.
11062            Binder token = new Binder();
11063            sCallerIdentity.set(new Identity(
11064                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11065            try {
11066                pfd = cph.provider.openFile(null, uri, "r", null, token);
11067            } catch (FileNotFoundException e) {
11068                // do nothing; pfd will be returned null
11069            } finally {
11070                // Ensure that whatever happens, we clean up the identity state
11071                sCallerIdentity.remove();
11072                // Ensure we're done with the provider.
11073                removeContentProviderExternalUnchecked(name, null, userId);
11074            }
11075        } else {
11076            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11077        }
11078        return pfd;
11079    }
11080
11081    // Actually is sleeping or shutting down or whatever else in the future
11082    // is an inactive state.
11083    public boolean isSleepingOrShuttingDown() {
11084        return isSleeping() || mShuttingDown;
11085    }
11086
11087    public boolean isSleeping() {
11088        return mSleeping;
11089    }
11090
11091    void onWakefulnessChanged(int wakefulness) {
11092        synchronized(this) {
11093            mWakefulness = wakefulness;
11094            updateSleepIfNeededLocked();
11095        }
11096    }
11097
11098    void finishRunningVoiceLocked() {
11099        if (mRunningVoice != null) {
11100            mRunningVoice = null;
11101            mVoiceWakeLock.release();
11102            updateSleepIfNeededLocked();
11103        }
11104    }
11105
11106    void startTimeTrackingFocusedActivityLocked() {
11107        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11108            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11109        }
11110    }
11111
11112    void updateSleepIfNeededLocked() {
11113        if (mSleeping && !shouldSleepLocked()) {
11114            mSleeping = false;
11115            startTimeTrackingFocusedActivityLocked();
11116            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11117            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11118            updateOomAdjLocked();
11119        } else if (!mSleeping && shouldSleepLocked()) {
11120            mSleeping = true;
11121            if (mCurAppTimeTracker != null) {
11122                mCurAppTimeTracker.stop();
11123            }
11124            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11125            mStackSupervisor.goingToSleepLocked();
11126            updateOomAdjLocked();
11127
11128            // Initialize the wake times of all processes.
11129            checkExcessivePowerUsageLocked(false);
11130            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11131            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11132            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11133        }
11134    }
11135
11136    private boolean shouldSleepLocked() {
11137        // Resume applications while running a voice interactor.
11138        if (mRunningVoice != null) {
11139            return false;
11140        }
11141
11142        // TODO: Transform the lock screen state into a sleep token instead.
11143        switch (mWakefulness) {
11144            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11145            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11146            case PowerManagerInternal.WAKEFULNESS_DOZING:
11147                // Pause applications whenever the lock screen is shown or any sleep
11148                // tokens have been acquired.
11149                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11150            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11151            default:
11152                // If we're asleep then pause applications unconditionally.
11153                return true;
11154        }
11155    }
11156
11157    /** Pokes the task persister. */
11158    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11159        if (task != null && task.stack != null && task.stack.isHomeStack()) {
11160            // Never persist the home stack.
11161            return;
11162        }
11163        mTaskPersister.wakeup(task, flush);
11164    }
11165
11166    /** Notifies all listeners when the task stack has changed. */
11167    void notifyTaskStackChangedLocked() {
11168        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11169        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11170        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11171        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11172    }
11173
11174    /** Notifies all listeners when an Activity is pinned. */
11175    void notifyActivityPinnedLocked() {
11176        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11177        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11178    }
11179
11180    @Override
11181    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11182        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11183    }
11184
11185    @Override
11186    public boolean shutdown(int timeout) {
11187        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11188                != PackageManager.PERMISSION_GRANTED) {
11189            throw new SecurityException("Requires permission "
11190                    + android.Manifest.permission.SHUTDOWN);
11191        }
11192
11193        boolean timedout = false;
11194
11195        synchronized(this) {
11196            mShuttingDown = true;
11197            updateEventDispatchingLocked();
11198            timedout = mStackSupervisor.shutdownLocked(timeout);
11199        }
11200
11201        mAppOpsService.shutdown();
11202        if (mUsageStatsService != null) {
11203            mUsageStatsService.prepareShutdown();
11204        }
11205        mBatteryStatsService.shutdown();
11206        synchronized (this) {
11207            mProcessStats.shutdownLocked();
11208            notifyTaskPersisterLocked(null, true);
11209        }
11210
11211        return timedout;
11212    }
11213
11214    public final void activitySlept(IBinder token) {
11215        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11216
11217        final long origId = Binder.clearCallingIdentity();
11218
11219        synchronized (this) {
11220            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11221            if (r != null) {
11222                mStackSupervisor.activitySleptLocked(r);
11223            }
11224        }
11225
11226        Binder.restoreCallingIdentity(origId);
11227    }
11228
11229    private String lockScreenShownToString() {
11230        switch (mLockScreenShown) {
11231            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11232            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11233            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11234            default: return "Unknown=" + mLockScreenShown;
11235        }
11236    }
11237
11238    void logLockScreen(String msg) {
11239        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11240                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11241                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11242                + " mSleeping=" + mSleeping);
11243    }
11244
11245    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11246        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11247        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11248            boolean wasRunningVoice = mRunningVoice != null;
11249            mRunningVoice = session;
11250            if (!wasRunningVoice) {
11251                mVoiceWakeLock.acquire();
11252                updateSleepIfNeededLocked();
11253            }
11254        }
11255    }
11256
11257    private void updateEventDispatchingLocked() {
11258        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11259    }
11260
11261    public void setLockScreenShown(boolean shown) {
11262        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11263                != PackageManager.PERMISSION_GRANTED) {
11264            throw new SecurityException("Requires permission "
11265                    + android.Manifest.permission.DEVICE_POWER);
11266        }
11267
11268        synchronized(this) {
11269            long ident = Binder.clearCallingIdentity();
11270            try {
11271                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11272                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11273                updateSleepIfNeededLocked();
11274            } finally {
11275                Binder.restoreCallingIdentity(ident);
11276            }
11277        }
11278    }
11279
11280    @Override
11281    public void stopAppSwitches() {
11282        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11283                != PackageManager.PERMISSION_GRANTED) {
11284            throw new SecurityException("viewquires permission "
11285                    + android.Manifest.permission.STOP_APP_SWITCHES);
11286        }
11287
11288        synchronized(this) {
11289            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11290                    + APP_SWITCH_DELAY_TIME;
11291            mDidAppSwitch = false;
11292            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11293            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11294            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11295        }
11296    }
11297
11298    public void resumeAppSwitches() {
11299        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11300                != PackageManager.PERMISSION_GRANTED) {
11301            throw new SecurityException("Requires permission "
11302                    + android.Manifest.permission.STOP_APP_SWITCHES);
11303        }
11304
11305        synchronized(this) {
11306            // Note that we don't execute any pending app switches... we will
11307            // let those wait until either the timeout, or the next start
11308            // activity request.
11309            mAppSwitchesAllowedTime = 0;
11310        }
11311    }
11312
11313    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11314            int callingPid, int callingUid, String name) {
11315        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11316            return true;
11317        }
11318
11319        int perm = checkComponentPermission(
11320                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11321                sourceUid, -1, true);
11322        if (perm == PackageManager.PERMISSION_GRANTED) {
11323            return true;
11324        }
11325
11326        // If the actual IPC caller is different from the logical source, then
11327        // also see if they are allowed to control app switches.
11328        if (callingUid != -1 && callingUid != sourceUid) {
11329            perm = checkComponentPermission(
11330                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11331                    callingUid, -1, true);
11332            if (perm == PackageManager.PERMISSION_GRANTED) {
11333                return true;
11334            }
11335        }
11336
11337        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11338        return false;
11339    }
11340
11341    public void setDebugApp(String packageName, boolean waitForDebugger,
11342            boolean persistent) {
11343        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11344                "setDebugApp()");
11345
11346        long ident = Binder.clearCallingIdentity();
11347        try {
11348            // Note that this is not really thread safe if there are multiple
11349            // callers into it at the same time, but that's not a situation we
11350            // care about.
11351            if (persistent) {
11352                final ContentResolver resolver = mContext.getContentResolver();
11353                Settings.Global.putString(
11354                    resolver, Settings.Global.DEBUG_APP,
11355                    packageName);
11356                Settings.Global.putInt(
11357                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11358                    waitForDebugger ? 1 : 0);
11359            }
11360
11361            synchronized (this) {
11362                if (!persistent) {
11363                    mOrigDebugApp = mDebugApp;
11364                    mOrigWaitForDebugger = mWaitForDebugger;
11365                }
11366                mDebugApp = packageName;
11367                mWaitForDebugger = waitForDebugger;
11368                mDebugTransient = !persistent;
11369                if (packageName != null) {
11370                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11371                            false, UserHandle.USER_ALL, "set debug app");
11372                }
11373            }
11374        } finally {
11375            Binder.restoreCallingIdentity(ident);
11376        }
11377    }
11378
11379    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11380        synchronized (this) {
11381            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11382            if (!isDebuggable) {
11383                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11384                    throw new SecurityException("Process not debuggable: " + app.packageName);
11385                }
11386            }
11387
11388            mTrackAllocationApp = processName;
11389        }
11390    }
11391
11392    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11393        synchronized (this) {
11394            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11395            if (!isDebuggable) {
11396                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11397                    throw new SecurityException("Process not debuggable: " + app.packageName);
11398                }
11399            }
11400            mProfileApp = processName;
11401            mProfileFile = profilerInfo.profileFile;
11402            if (mProfileFd != null) {
11403                try {
11404                    mProfileFd.close();
11405                } catch (IOException e) {
11406                }
11407                mProfileFd = null;
11408            }
11409            mProfileFd = profilerInfo.profileFd;
11410            mSamplingInterval = profilerInfo.samplingInterval;
11411            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11412            mProfileType = 0;
11413        }
11414    }
11415
11416    @Override
11417    public void setAlwaysFinish(boolean enabled) {
11418        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11419                "setAlwaysFinish()");
11420
11421        Settings.Global.putInt(
11422                mContext.getContentResolver(),
11423                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11424
11425        synchronized (this) {
11426            mAlwaysFinishActivities = enabled;
11427        }
11428    }
11429
11430    @Override
11431    public void setActivityController(IActivityController controller) {
11432        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11433                "setActivityController()");
11434        synchronized (this) {
11435            mController = controller;
11436            Watchdog.getInstance().setActivityController(controller);
11437        }
11438    }
11439
11440    @Override
11441    public void setUserIsMonkey(boolean userIsMonkey) {
11442        synchronized (this) {
11443            synchronized (mPidsSelfLocked) {
11444                final int callingPid = Binder.getCallingPid();
11445                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11446                if (precessRecord == null) {
11447                    throw new SecurityException("Unknown process: " + callingPid);
11448                }
11449                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11450                    throw new SecurityException("Only an instrumentation process "
11451                            + "with a UiAutomation can call setUserIsMonkey");
11452                }
11453            }
11454            mUserIsMonkey = userIsMonkey;
11455        }
11456    }
11457
11458    @Override
11459    public boolean isUserAMonkey() {
11460        synchronized (this) {
11461            // If there is a controller also implies the user is a monkey.
11462            return (mUserIsMonkey || mController != null);
11463        }
11464    }
11465
11466    public void requestBugReport(int bugreportType) {
11467        String service = null;
11468        switch (bugreportType) {
11469            case ActivityManager.BUGREPORT_OPTION_FULL:
11470                service = "bugreport";
11471                break;
11472            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11473                service = "bugreportplus";
11474                break;
11475            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11476                service = "bugreportremote";
11477                break;
11478        }
11479        if (service == null) {
11480            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11481                    + bugreportType);
11482        }
11483        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11484        SystemProperties.set("ctl.start", service);
11485    }
11486
11487    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11488        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11489    }
11490
11491    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11492        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11493            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11494        }
11495        return KEY_DISPATCHING_TIMEOUT;
11496    }
11497
11498    @Override
11499    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11500        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11501                != PackageManager.PERMISSION_GRANTED) {
11502            throw new SecurityException("Requires permission "
11503                    + android.Manifest.permission.FILTER_EVENTS);
11504        }
11505        ProcessRecord proc;
11506        long timeout;
11507        synchronized (this) {
11508            synchronized (mPidsSelfLocked) {
11509                proc = mPidsSelfLocked.get(pid);
11510            }
11511            timeout = getInputDispatchingTimeoutLocked(proc);
11512        }
11513
11514        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11515            return -1;
11516        }
11517
11518        return timeout;
11519    }
11520
11521    /**
11522     * Handle input dispatching timeouts.
11523     * Returns whether input dispatching should be aborted or not.
11524     */
11525    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11526            final ActivityRecord activity, final ActivityRecord parent,
11527            final boolean aboveSystem, String reason) {
11528        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11529                != PackageManager.PERMISSION_GRANTED) {
11530            throw new SecurityException("Requires permission "
11531                    + android.Manifest.permission.FILTER_EVENTS);
11532        }
11533
11534        final String annotation;
11535        if (reason == null) {
11536            annotation = "Input dispatching timed out";
11537        } else {
11538            annotation = "Input dispatching timed out (" + reason + ")";
11539        }
11540
11541        if (proc != null) {
11542            synchronized (this) {
11543                if (proc.debugging) {
11544                    return false;
11545                }
11546
11547                if (mDidDexOpt) {
11548                    // Give more time since we were dexopting.
11549                    mDidDexOpt = false;
11550                    return false;
11551                }
11552
11553                if (proc.instrumentationClass != null) {
11554                    Bundle info = new Bundle();
11555                    info.putString("shortMsg", "keyDispatchingTimedOut");
11556                    info.putString("longMsg", annotation);
11557                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11558                    return true;
11559                }
11560            }
11561            mHandler.post(new Runnable() {
11562                @Override
11563                public void run() {
11564                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
11565                }
11566            });
11567        }
11568
11569        return true;
11570    }
11571
11572    @Override
11573    public Bundle getAssistContextExtras(int requestType) {
11574        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11575                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11576        if (pae == null) {
11577            return null;
11578        }
11579        synchronized (pae) {
11580            while (!pae.haveResult) {
11581                try {
11582                    pae.wait();
11583                } catch (InterruptedException e) {
11584                }
11585            }
11586        }
11587        synchronized (this) {
11588            buildAssistBundleLocked(pae, pae.result);
11589            mPendingAssistExtras.remove(pae);
11590            mUiHandler.removeCallbacks(pae);
11591        }
11592        return pae.extras;
11593    }
11594
11595    @Override
11596    public boolean isAssistDataAllowedOnCurrentActivity() {
11597        int userId;
11598        synchronized (this) {
11599            userId = mUserController.getCurrentUserIdLocked();
11600            ActivityRecord activity = getFocusedStack().topActivity();
11601            if (activity == null) {
11602                return false;
11603            }
11604            userId = activity.userId;
11605        }
11606        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11607                Context.DEVICE_POLICY_SERVICE);
11608        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11609    }
11610
11611    @Override
11612    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11613        long ident = Binder.clearCallingIdentity();
11614        try {
11615            synchronized (this) {
11616                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11617                ActivityRecord top = getFocusedStack().topActivity();
11618                if (top != caller) {
11619                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11620                            + " is not current top " + top);
11621                    return false;
11622                }
11623                if (!top.nowVisible) {
11624                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11625                            + " is not visible");
11626                    return false;
11627                }
11628            }
11629            AssistUtils utils = new AssistUtils(mContext);
11630            return utils.showSessionForActiveService(args,
11631                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11632        } finally {
11633            Binder.restoreCallingIdentity(ident);
11634        }
11635    }
11636
11637    @Override
11638    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11639            IBinder activityToken) {
11640        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11641                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11642    }
11643
11644    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11645            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11646            long timeout) {
11647        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11648                "enqueueAssistContext()");
11649        synchronized (this) {
11650            ActivityRecord activity = getFocusedStack().topActivity();
11651            if (activity == null) {
11652                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11653                return null;
11654            }
11655            if (activity.app == null || activity.app.thread == null) {
11656                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11657                return null;
11658            }
11659            if (activityToken != null) {
11660                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11661                if (activity != caller) {
11662                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11663                            + " is not current top " + activity);
11664                    return null;
11665                }
11666            }
11667            PendingAssistExtras pae;
11668            Bundle extras = new Bundle();
11669            if (args != null) {
11670                extras.putAll(args);
11671            }
11672            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11673            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11674            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11675            try {
11676                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11677                        requestType);
11678                mPendingAssistExtras.add(pae);
11679                mUiHandler.postDelayed(pae, timeout);
11680            } catch (RemoteException e) {
11681                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11682                return null;
11683            }
11684            return pae;
11685        }
11686    }
11687
11688    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11689        IResultReceiver receiver;
11690        synchronized (this) {
11691            mPendingAssistExtras.remove(pae);
11692            receiver = pae.receiver;
11693        }
11694        if (receiver != null) {
11695            // Caller wants result sent back to them.
11696            try {
11697                pae.receiver.send(0, null);
11698            } catch (RemoteException e) {
11699            }
11700        }
11701    }
11702
11703    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11704        if (result != null) {
11705            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11706        }
11707        if (pae.hint != null) {
11708            pae.extras.putBoolean(pae.hint, true);
11709        }
11710    }
11711
11712    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11713            AssistContent content, Uri referrer) {
11714        PendingAssistExtras pae = (PendingAssistExtras)token;
11715        synchronized (pae) {
11716            pae.result = extras;
11717            pae.structure = structure;
11718            pae.content = content;
11719            if (referrer != null) {
11720                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11721            }
11722            pae.haveResult = true;
11723            pae.notifyAll();
11724            if (pae.intent == null && pae.receiver == null) {
11725                // Caller is just waiting for the result.
11726                return;
11727            }
11728        }
11729
11730        // We are now ready to launch the assist activity.
11731        IResultReceiver sendReceiver = null;
11732        Bundle sendBundle = null;
11733        synchronized (this) {
11734            buildAssistBundleLocked(pae, extras);
11735            boolean exists = mPendingAssistExtras.remove(pae);
11736            mUiHandler.removeCallbacks(pae);
11737            if (!exists) {
11738                // Timed out.
11739                return;
11740            }
11741            if ((sendReceiver=pae.receiver) != null) {
11742                // Caller wants result sent back to them.
11743                sendBundle = new Bundle();
11744                sendBundle.putBundle("data", pae.extras);
11745                sendBundle.putParcelable("structure", pae.structure);
11746                sendBundle.putParcelable("content", pae.content);
11747            }
11748        }
11749        if (sendReceiver != null) {
11750            try {
11751                sendReceiver.send(0, sendBundle);
11752            } catch (RemoteException e) {
11753            }
11754            return;
11755        }
11756
11757        long ident = Binder.clearCallingIdentity();
11758        try {
11759            pae.intent.replaceExtras(pae.extras);
11760            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11761                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11762                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11763            closeSystemDialogs("assist");
11764            try {
11765                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11766            } catch (ActivityNotFoundException e) {
11767                Slog.w(TAG, "No activity to handle assist action.", e);
11768            }
11769        } finally {
11770            Binder.restoreCallingIdentity(ident);
11771        }
11772    }
11773
11774    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11775            Bundle args) {
11776        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11777                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11778    }
11779
11780    public void registerProcessObserver(IProcessObserver observer) {
11781        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11782                "registerProcessObserver()");
11783        synchronized (this) {
11784            mProcessObservers.register(observer);
11785        }
11786    }
11787
11788    @Override
11789    public void unregisterProcessObserver(IProcessObserver observer) {
11790        synchronized (this) {
11791            mProcessObservers.unregister(observer);
11792        }
11793    }
11794
11795    @Override
11796    public void registerUidObserver(IUidObserver observer, int which) {
11797        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11798                "registerUidObserver()");
11799        synchronized (this) {
11800            mUidObservers.register(observer, which);
11801        }
11802    }
11803
11804    @Override
11805    public void unregisterUidObserver(IUidObserver observer) {
11806        synchronized (this) {
11807            mUidObservers.unregister(observer);
11808        }
11809    }
11810
11811    @Override
11812    public boolean convertFromTranslucent(IBinder token) {
11813        final long origId = Binder.clearCallingIdentity();
11814        try {
11815            synchronized (this) {
11816                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11817                if (r == null) {
11818                    return false;
11819                }
11820                final boolean translucentChanged = r.changeWindowTranslucency(true);
11821                if (translucentChanged) {
11822                    r.task.stack.releaseBackgroundResources(r);
11823                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11824                }
11825                mWindowManager.setAppFullscreen(token, true);
11826                return translucentChanged;
11827            }
11828        } finally {
11829            Binder.restoreCallingIdentity(origId);
11830        }
11831    }
11832
11833    @Override
11834    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11835        final long origId = Binder.clearCallingIdentity();
11836        try {
11837            synchronized (this) {
11838                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11839                if (r == null) {
11840                    return false;
11841                }
11842                int index = r.task.mActivities.lastIndexOf(r);
11843                if (index > 0) {
11844                    ActivityRecord under = r.task.mActivities.get(index - 1);
11845                    under.returningOptions = options;
11846                }
11847                final boolean translucentChanged = r.changeWindowTranslucency(false);
11848                if (translucentChanged) {
11849                    r.task.stack.convertActivityToTranslucent(r);
11850                }
11851                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11852                mWindowManager.setAppFullscreen(token, false);
11853                return translucentChanged;
11854            }
11855        } finally {
11856            Binder.restoreCallingIdentity(origId);
11857        }
11858    }
11859
11860    @Override
11861    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11862        final long origId = Binder.clearCallingIdentity();
11863        try {
11864            synchronized (this) {
11865                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11866                if (r != null) {
11867                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11868                }
11869            }
11870            return false;
11871        } finally {
11872            Binder.restoreCallingIdentity(origId);
11873        }
11874    }
11875
11876    @Override
11877    public boolean isBackgroundVisibleBehind(IBinder token) {
11878        final long origId = Binder.clearCallingIdentity();
11879        try {
11880            synchronized (this) {
11881                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11882                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11883                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11884                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11885                return visible;
11886            }
11887        } finally {
11888            Binder.restoreCallingIdentity(origId);
11889        }
11890    }
11891
11892    @Override
11893    public ActivityOptions getActivityOptions(IBinder token) {
11894        final long origId = Binder.clearCallingIdentity();
11895        try {
11896            synchronized (this) {
11897                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11898                if (r != null) {
11899                    final ActivityOptions activityOptions = r.pendingOptions;
11900                    r.pendingOptions = null;
11901                    return activityOptions;
11902                }
11903                return null;
11904            }
11905        } finally {
11906            Binder.restoreCallingIdentity(origId);
11907        }
11908    }
11909
11910    @Override
11911    public void setImmersive(IBinder token, boolean immersive) {
11912        synchronized(this) {
11913            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11914            if (r == null) {
11915                throw new IllegalArgumentException();
11916            }
11917            r.immersive = immersive;
11918
11919            // update associated state if we're frontmost
11920            if (r == mFocusedActivity) {
11921                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11922                applyUpdateLockStateLocked(r);
11923            }
11924        }
11925    }
11926
11927    @Override
11928    public boolean isImmersive(IBinder token) {
11929        synchronized (this) {
11930            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11931            if (r == null) {
11932                throw new IllegalArgumentException();
11933            }
11934            return r.immersive;
11935        }
11936    }
11937
11938    @Override
11939    public void setVrMode(IBinder token, boolean enabled) {
11940        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11941            throw new UnsupportedOperationException("VR mode not supported on this device!");
11942        }
11943
11944        synchronized(this) {
11945            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11946            if (r == null) {
11947                throw new IllegalArgumentException();
11948            }
11949            r.isVrActivity = enabled;
11950
11951            // Update associated state if this activity is currently focused
11952            if (r == mFocusedActivity) {
11953                applyUpdateVrModeLocked(r);
11954            }
11955        }
11956    }
11957
11958    public boolean isTopActivityImmersive() {
11959        enforceNotIsolatedCaller("startActivity");
11960        synchronized (this) {
11961            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11962            return (r != null) ? r.immersive : false;
11963        }
11964    }
11965
11966    @Override
11967    public boolean isTopOfTask(IBinder token) {
11968        synchronized (this) {
11969            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11970            if (r == null) {
11971                throw new IllegalArgumentException();
11972            }
11973            return r.task.getTopActivity() == r;
11974        }
11975    }
11976
11977    public final void enterSafeMode() {
11978        synchronized(this) {
11979            // It only makes sense to do this before the system is ready
11980            // and started launching other packages.
11981            if (!mSystemReady) {
11982                try {
11983                    AppGlobals.getPackageManager().enterSafeMode();
11984                } catch (RemoteException e) {
11985                }
11986            }
11987
11988            mSafeMode = true;
11989        }
11990    }
11991
11992    public final void showSafeModeOverlay() {
11993        View v = LayoutInflater.from(mContext).inflate(
11994                com.android.internal.R.layout.safe_mode, null);
11995        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11996        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11997        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11998        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11999        lp.gravity = Gravity.BOTTOM | Gravity.START;
12000        lp.format = v.getBackground().getOpacity();
12001        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12002                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12003        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12004        ((WindowManager)mContext.getSystemService(
12005                Context.WINDOW_SERVICE)).addView(v, lp);
12006    }
12007
12008    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12009        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12010            return;
12011        }
12012        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12013        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12014        synchronized (stats) {
12015            if (mBatteryStatsService.isOnBattery()) {
12016                mBatteryStatsService.enforceCallingPermission();
12017                int MY_UID = Binder.getCallingUid();
12018                final int uid;
12019                if (sender == null) {
12020                    uid = sourceUid;
12021                } else {
12022                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12023                }
12024                BatteryStatsImpl.Uid.Pkg pkg =
12025                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12026                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12027                pkg.noteWakeupAlarmLocked(tag);
12028            }
12029        }
12030    }
12031
12032    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12033        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12034            return;
12035        }
12036        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12037        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12038        synchronized (stats) {
12039            mBatteryStatsService.enforceCallingPermission();
12040            int MY_UID = Binder.getCallingUid();
12041            final int uid;
12042            if (sender == null) {
12043                uid = sourceUid;
12044            } else {
12045                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12046            }
12047            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12048        }
12049    }
12050
12051    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12052        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12053            return;
12054        }
12055        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12056        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12057        synchronized (stats) {
12058            mBatteryStatsService.enforceCallingPermission();
12059            int MY_UID = Binder.getCallingUid();
12060            final int uid;
12061            if (sender == null) {
12062                uid = sourceUid;
12063            } else {
12064                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12065            }
12066            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12067        }
12068    }
12069
12070    public boolean killPids(int[] pids, String pReason, boolean secure) {
12071        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12072            throw new SecurityException("killPids only available to the system");
12073        }
12074        String reason = (pReason == null) ? "Unknown" : pReason;
12075        // XXX Note: don't acquire main activity lock here, because the window
12076        // manager calls in with its locks held.
12077
12078        boolean killed = false;
12079        synchronized (mPidsSelfLocked) {
12080            int worstType = 0;
12081            for (int i=0; i<pids.length; i++) {
12082                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12083                if (proc != null) {
12084                    int type = proc.setAdj;
12085                    if (type > worstType) {
12086                        worstType = type;
12087                    }
12088                }
12089            }
12090
12091            // If the worst oom_adj is somewhere in the cached proc LRU range,
12092            // then constrain it so we will kill all cached procs.
12093            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12094                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12095                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12096            }
12097
12098            // If this is not a secure call, don't let it kill processes that
12099            // are important.
12100            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12101                worstType = ProcessList.SERVICE_ADJ;
12102            }
12103
12104            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12105            for (int i=0; i<pids.length; i++) {
12106                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12107                if (proc == null) {
12108                    continue;
12109                }
12110                int adj = proc.setAdj;
12111                if (adj >= worstType && !proc.killedByAm) {
12112                    proc.kill(reason, true);
12113                    killed = true;
12114                }
12115            }
12116        }
12117        return killed;
12118    }
12119
12120    @Override
12121    public void killUid(int appId, int userId, String reason) {
12122        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12123        synchronized (this) {
12124            final long identity = Binder.clearCallingIdentity();
12125            try {
12126                killPackageProcessesLocked(null, appId, userId,
12127                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, true,
12128                        reason != null ? reason : "kill uid");
12129            } finally {
12130                Binder.restoreCallingIdentity(identity);
12131            }
12132        }
12133    }
12134
12135    @Override
12136    public boolean killProcessesBelowForeground(String reason) {
12137        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12138            throw new SecurityException("killProcessesBelowForeground() only available to system");
12139        }
12140
12141        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12142    }
12143
12144    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12145        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12146            throw new SecurityException("killProcessesBelowAdj() only available to system");
12147        }
12148
12149        boolean killed = false;
12150        synchronized (mPidsSelfLocked) {
12151            final int size = mPidsSelfLocked.size();
12152            for (int i = 0; i < size; i++) {
12153                final int pid = mPidsSelfLocked.keyAt(i);
12154                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12155                if (proc == null) continue;
12156
12157                final int adj = proc.setAdj;
12158                if (adj > belowAdj && !proc.killedByAm) {
12159                    proc.kill(reason, true);
12160                    killed = true;
12161                }
12162            }
12163        }
12164        return killed;
12165    }
12166
12167    @Override
12168    public void hang(final IBinder who, boolean allowRestart) {
12169        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12170                != PackageManager.PERMISSION_GRANTED) {
12171            throw new SecurityException("Requires permission "
12172                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12173        }
12174
12175        final IBinder.DeathRecipient death = new DeathRecipient() {
12176            @Override
12177            public void binderDied() {
12178                synchronized (this) {
12179                    notifyAll();
12180                }
12181            }
12182        };
12183
12184        try {
12185            who.linkToDeath(death, 0);
12186        } catch (RemoteException e) {
12187            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12188            return;
12189        }
12190
12191        synchronized (this) {
12192            Watchdog.getInstance().setAllowRestart(allowRestart);
12193            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12194            synchronized (death) {
12195                while (who.isBinderAlive()) {
12196                    try {
12197                        death.wait();
12198                    } catch (InterruptedException e) {
12199                    }
12200                }
12201            }
12202            Watchdog.getInstance().setAllowRestart(true);
12203        }
12204    }
12205
12206    @Override
12207    public void restart() {
12208        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12209                != PackageManager.PERMISSION_GRANTED) {
12210            throw new SecurityException("Requires permission "
12211                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12212        }
12213
12214        Log.i(TAG, "Sending shutdown broadcast...");
12215
12216        BroadcastReceiver br = new BroadcastReceiver() {
12217            @Override public void onReceive(Context context, Intent intent) {
12218                // Now the broadcast is done, finish up the low-level shutdown.
12219                Log.i(TAG, "Shutting down activity manager...");
12220                shutdown(10000);
12221                Log.i(TAG, "Shutdown complete, restarting!");
12222                Process.killProcess(Process.myPid());
12223                System.exit(10);
12224            }
12225        };
12226
12227        // First send the high-level shut down broadcast.
12228        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12229        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12230        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12231        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12232        mContext.sendOrderedBroadcastAsUser(intent,
12233                UserHandle.ALL, null, br, mHandler, 0, null, null);
12234        */
12235        br.onReceive(mContext, intent);
12236    }
12237
12238    private long getLowRamTimeSinceIdle(long now) {
12239        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12240    }
12241
12242    @Override
12243    public void performIdleMaintenance() {
12244        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12245                != PackageManager.PERMISSION_GRANTED) {
12246            throw new SecurityException("Requires permission "
12247                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12248        }
12249
12250        synchronized (this) {
12251            final long now = SystemClock.uptimeMillis();
12252            final long timeSinceLastIdle = now - mLastIdleTime;
12253            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12254            mLastIdleTime = now;
12255            mLowRamTimeSinceLastIdle = 0;
12256            if (mLowRamStartTime != 0) {
12257                mLowRamStartTime = now;
12258            }
12259
12260            StringBuilder sb = new StringBuilder(128);
12261            sb.append("Idle maintenance over ");
12262            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12263            sb.append(" low RAM for ");
12264            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12265            Slog.i(TAG, sb.toString());
12266
12267            // If at least 1/3 of our time since the last idle period has been spent
12268            // with RAM low, then we want to kill processes.
12269            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12270
12271            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12272                ProcessRecord proc = mLruProcesses.get(i);
12273                if (proc.notCachedSinceIdle) {
12274                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12275                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12276                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12277                        if (doKilling && proc.initialIdlePss != 0
12278                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12279                            sb = new StringBuilder(128);
12280                            sb.append("Kill");
12281                            sb.append(proc.processName);
12282                            sb.append(" in idle maint: pss=");
12283                            sb.append(proc.lastPss);
12284                            sb.append(", swapPss=");
12285                            sb.append(proc.lastSwapPss);
12286                            sb.append(", initialPss=");
12287                            sb.append(proc.initialIdlePss);
12288                            sb.append(", period=");
12289                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12290                            sb.append(", lowRamPeriod=");
12291                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12292                            Slog.wtfQuiet(TAG, sb.toString());
12293                            proc.kill("idle maint (pss " + proc.lastPss
12294                                    + " from " + proc.initialIdlePss + ")", true);
12295                        }
12296                    }
12297                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12298                    proc.notCachedSinceIdle = true;
12299                    proc.initialIdlePss = 0;
12300                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12301                            mTestPssMode, isSleeping(), now);
12302                }
12303            }
12304
12305            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12306            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12307        }
12308    }
12309
12310    private void retrieveSettings() {
12311        final ContentResolver resolver = mContext.getContentResolver();
12312        final boolean freeformWindowManagement =
12313                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12314                        || Settings.Global.getInt(
12315                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12316        final boolean supportsPictureInPicture =
12317                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12318
12319        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12320        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12321        final boolean alwaysFinishActivities =
12322                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12323        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12324        final boolean forceResizable = Settings.Global.getInt(
12325                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12326        // Transfer any global setting for forcing RTL layout, into a System Property
12327        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12328
12329        final Configuration configuration = new Configuration();
12330        Settings.System.getConfiguration(resolver, configuration);
12331        if (forceRtl) {
12332            // This will take care of setting the correct layout direction flags
12333            configuration.setLayoutDirection(configuration.locale);
12334        }
12335
12336        synchronized (this) {
12337            mDebugApp = mOrigDebugApp = debugApp;
12338            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12339            mAlwaysFinishActivities = alwaysFinishActivities;
12340            mForceResizableActivities = forceResizable;
12341            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12342            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12343            // This happens before any activities are started, so we can
12344            // change mConfiguration in-place.
12345            updateConfigurationLocked(configuration, null, true);
12346            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12347                    "Initial config: " + mConfiguration);
12348
12349            // Load resources only after the current configuration has been set.
12350            final Resources res = mContext.getResources();
12351            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12352            mThumbnailWidth = res.getDimensionPixelSize(
12353                    com.android.internal.R.dimen.thumbnail_width);
12354            mThumbnailHeight = res.getDimensionPixelSize(
12355                    com.android.internal.R.dimen.thumbnail_height);
12356            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12357                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12358            final String appsNotReportingCrashes = res.getString(
12359                    com.android.internal.R.string.config_appsNotReportingCrashes);
12360            if (appsNotReportingCrashes != null) {
12361                final String[] split = appsNotReportingCrashes.split(",");
12362                if (split.length > 0) {
12363                    mAppsNotReportingCrashes = new ArraySet<>();
12364                    for (int i = 0; i < split.length; i++) {
12365                        mAppsNotReportingCrashes.add(split[i]);
12366                    }
12367                }
12368            }
12369        }
12370    }
12371
12372    public boolean testIsSystemReady() {
12373        // no need to synchronize(this) just to read & return the value
12374        return mSystemReady;
12375    }
12376
12377    private static File getCalledPreBootReceiversFile() {
12378        File dataDir = Environment.getDataDirectory();
12379        File systemDir = new File(dataDir, "system");
12380        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12381        return fname;
12382    }
12383
12384    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12385        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12386        File file = getCalledPreBootReceiversFile();
12387        FileInputStream fis = null;
12388        try {
12389            fis = new FileInputStream(file);
12390            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12391            int fvers = dis.readInt();
12392            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12393                String vers = dis.readUTF();
12394                String codename = dis.readUTF();
12395                String build = dis.readUTF();
12396                if (android.os.Build.VERSION.RELEASE.equals(vers)
12397                        && android.os.Build.VERSION.CODENAME.equals(codename)
12398                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12399                    int num = dis.readInt();
12400                    while (num > 0) {
12401                        num--;
12402                        String pkg = dis.readUTF();
12403                        String cls = dis.readUTF();
12404                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12405                    }
12406                }
12407            }
12408        } catch (FileNotFoundException e) {
12409        } catch (IOException e) {
12410            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12411        } finally {
12412            if (fis != null) {
12413                try {
12414                    fis.close();
12415                } catch (IOException e) {
12416                }
12417            }
12418        }
12419        return lastDoneReceivers;
12420    }
12421
12422    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12423        File file = getCalledPreBootReceiversFile();
12424        FileOutputStream fos = null;
12425        DataOutputStream dos = null;
12426        try {
12427            fos = new FileOutputStream(file);
12428            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12429            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12430            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12431            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12432            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12433            dos.writeInt(list.size());
12434            for (int i=0; i<list.size(); i++) {
12435                dos.writeUTF(list.get(i).getPackageName());
12436                dos.writeUTF(list.get(i).getClassName());
12437            }
12438        } catch (IOException e) {
12439            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12440            file.delete();
12441        } finally {
12442            FileUtils.sync(fos);
12443            if (dos != null) {
12444                try {
12445                    dos.close();
12446                } catch (IOException e) {
12447                    // TODO Auto-generated catch block
12448                    e.printStackTrace();
12449                }
12450            }
12451        }
12452    }
12453
12454    final class PreBootContinuation extends IIntentReceiver.Stub {
12455        final Intent intent;
12456        final Runnable onFinishCallback;
12457        final ArrayList<ComponentName> doneReceivers;
12458        final List<ResolveInfo> ris;
12459        final int[] users;
12460        int lastRi = -1;
12461        int curRi = 0;
12462        int curUser = 0;
12463
12464        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12465                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12466            intent = _intent;
12467            onFinishCallback = _onFinishCallback;
12468            doneReceivers = _doneReceivers;
12469            ris = _ris;
12470            users = _users;
12471        }
12472
12473        void go() {
12474            if (lastRi != curRi) {
12475                ActivityInfo ai = ris.get(curRi).activityInfo;
12476                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12477                intent.setComponent(comp);
12478                doneReceivers.add(comp);
12479                lastRi = curRi;
12480                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12481                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12482            }
12483            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12484                    + " for user " + users[curUser]);
12485            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12486            broadcastIntentLocked(null, null, intent, null, this,
12487                    0, null, null, null, AppOpsManager.OP_NONE,
12488                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12489        }
12490
12491        public void performReceive(Intent intent, int resultCode,
12492                String data, Bundle extras, boolean ordered,
12493                boolean sticky, int sendingUser) {
12494            curUser++;
12495            if (curUser >= users.length) {
12496                curUser = 0;
12497                curRi++;
12498                if (curRi >= ris.size()) {
12499                    // All done sending broadcasts!
12500                    if (onFinishCallback != null) {
12501                        // The raw IIntentReceiver interface is called
12502                        // with the AM lock held, so redispatch to
12503                        // execute our code without the lock.
12504                        mHandler.post(onFinishCallback);
12505                    }
12506                    return;
12507                }
12508            }
12509            go();
12510        }
12511    }
12512
12513    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12514            ArrayList<ComponentName> doneReceivers) {
12515        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12516        List<ResolveInfo> ris = null;
12517        try {
12518            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12519                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12520        } catch (RemoteException e) {
12521        }
12522        if (ris == null) {
12523            return false;
12524        }
12525        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12526
12527        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12528        for (int i=0; i<ris.size(); i++) {
12529            ActivityInfo ai = ris.get(i).activityInfo;
12530            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12531            if (lastDoneReceivers.contains(comp)) {
12532                // We already did the pre boot receiver for this app with the current
12533                // platform version, so don't do it again...
12534                ris.remove(i);
12535                i--;
12536                // ...however, do keep it as one that has been done, so we don't
12537                // forget about it when rewriting the file of last done receivers.
12538                doneReceivers.add(comp);
12539            }
12540        }
12541
12542        if (ris.size() <= 0) {
12543            return false;
12544        }
12545
12546        // TODO: can we still do this with per user encryption?
12547        final int[] users = mUserController.getUsers();
12548        if (users.length <= 0) {
12549            return false;
12550        }
12551
12552        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12553                ris, users);
12554        cont.go();
12555        return true;
12556    }
12557
12558    public void systemReady(final Runnable goingCallback) {
12559        synchronized(this) {
12560            if (mSystemReady) {
12561                // If we're done calling all the receivers, run the next "boot phase" passed in
12562                // by the SystemServer
12563                if (goingCallback != null) {
12564                    goingCallback.run();
12565                }
12566                return;
12567            }
12568
12569            mLocalDeviceIdleController
12570                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12571
12572            // Make sure we have the current profile info, since it is needed for
12573            // security checks.
12574            mUserController.updateCurrentProfileIdsLocked();
12575
12576            mRecentTasks.clear();
12577            mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12578            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12579            mTaskPersister.startPersisting();
12580
12581            // Check to see if there are any update receivers to run.
12582            if (!mDidUpdate) {
12583                if (mWaitingUpdate) {
12584                    return;
12585                }
12586                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12587                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12588                    public void run() {
12589                        synchronized (ActivityManagerService.this) {
12590                            mDidUpdate = true;
12591                        }
12592                        showBootMessage(mContext.getText(
12593                                R.string.android_upgrading_complete),
12594                                false);
12595                        writeLastDonePreBootReceivers(doneReceivers);
12596                        systemReady(goingCallback);
12597                    }
12598                }, doneReceivers);
12599
12600                if (mWaitingUpdate) {
12601                    return;
12602                }
12603                mDidUpdate = true;
12604            }
12605
12606            mAppOpsService.systemReady();
12607            mSystemReady = true;
12608        }
12609
12610        ArrayList<ProcessRecord> procsToKill = null;
12611        synchronized(mPidsSelfLocked) {
12612            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12613                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12614                if (!isAllowedWhileBooting(proc.info)){
12615                    if (procsToKill == null) {
12616                        procsToKill = new ArrayList<ProcessRecord>();
12617                    }
12618                    procsToKill.add(proc);
12619                }
12620            }
12621        }
12622
12623        synchronized(this) {
12624            if (procsToKill != null) {
12625                for (int i=procsToKill.size()-1; i>=0; i--) {
12626                    ProcessRecord proc = procsToKill.get(i);
12627                    Slog.i(TAG, "Removing system update proc: " + proc);
12628                    removeProcessLocked(proc, true, false, "system update done");
12629                }
12630            }
12631
12632            // Now that we have cleaned up any update processes, we
12633            // are ready to start launching real processes and know that
12634            // we won't trample on them any more.
12635            mProcessesReady = true;
12636        }
12637
12638        Slog.i(TAG, "System now ready");
12639        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12640            SystemClock.uptimeMillis());
12641
12642        synchronized(this) {
12643            // Make sure we have no pre-ready processes sitting around.
12644
12645            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12646                ResolveInfo ri = mContext.getPackageManager()
12647                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12648                                STOCK_PM_FLAGS);
12649                CharSequence errorMsg = null;
12650                if (ri != null) {
12651                    ActivityInfo ai = ri.activityInfo;
12652                    ApplicationInfo app = ai.applicationInfo;
12653                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12654                        mTopAction = Intent.ACTION_FACTORY_TEST;
12655                        mTopData = null;
12656                        mTopComponent = new ComponentName(app.packageName,
12657                                ai.name);
12658                    } else {
12659                        errorMsg = mContext.getResources().getText(
12660                                com.android.internal.R.string.factorytest_not_system);
12661                    }
12662                } else {
12663                    errorMsg = mContext.getResources().getText(
12664                            com.android.internal.R.string.factorytest_no_action);
12665                }
12666                if (errorMsg != null) {
12667                    mTopAction = null;
12668                    mTopData = null;
12669                    mTopComponent = null;
12670                    Message msg = Message.obtain();
12671                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12672                    msg.getData().putCharSequence("msg", errorMsg);
12673                    mUiHandler.sendMessage(msg);
12674                }
12675            }
12676        }
12677
12678        retrieveSettings();
12679        final int currentUserId;
12680        synchronized (this) {
12681            currentUserId = mUserController.getCurrentUserIdLocked();
12682            readGrantedUriPermissionsLocked();
12683        }
12684
12685        if (goingCallback != null) goingCallback.run();
12686
12687
12688        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12689                Integer.toString(currentUserId), currentUserId);
12690        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12691                Integer.toString(currentUserId), currentUserId);
12692        mSystemServiceManager.startUser(currentUserId);
12693
12694        synchronized (this) {
12695            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12696                try {
12697                    List apps = AppGlobals.getPackageManager().
12698                        getPersistentApplications(STOCK_PM_FLAGS);
12699                    if (apps != null) {
12700                        int N = apps.size();
12701                        int i;
12702                        for (i=0; i<N; i++) {
12703                            ApplicationInfo info
12704                                = (ApplicationInfo)apps.get(i);
12705                            if (info != null &&
12706                                    !info.packageName.equals("android")) {
12707                                addAppLocked(info, false, null /* ABI override */);
12708                            }
12709                        }
12710                    }
12711                } catch (RemoteException ex) {
12712                    // pm is in same process, this will never happen.
12713                }
12714            }
12715
12716            // Start up initial activity.
12717            mBooting = true;
12718            // Enable home activity for system user, so that the system can always boot
12719            if (UserManager.isSplitSystemUser()) {
12720                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12721                try {
12722                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12723                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12724                            UserHandle.USER_SYSTEM);
12725                } catch (RemoteException e) {
12726                    e.rethrowAsRuntimeException();
12727                }
12728            }
12729            startHomeActivityLocked(currentUserId, "systemReady");
12730
12731            try {
12732                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12733                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12734                            + " data partition or your device will be unstable.");
12735                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12736                }
12737            } catch (RemoteException e) {
12738            }
12739
12740            if (!Build.isBuildConsistent()) {
12741                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12742                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12743            }
12744
12745            long ident = Binder.clearCallingIdentity();
12746            try {
12747                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12748                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12749                        | Intent.FLAG_RECEIVER_FOREGROUND);
12750                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12751                broadcastIntentLocked(null, null, intent,
12752                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12753                        null, false, false, MY_PID, Process.SYSTEM_UID,
12754                        currentUserId);
12755                intent = new Intent(Intent.ACTION_USER_STARTING);
12756                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12757                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12758                broadcastIntentLocked(null, null, intent,
12759                        null, new IIntentReceiver.Stub() {
12760                            @Override
12761                            public void performReceive(Intent intent, int resultCode, String data,
12762                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12763                                    throws RemoteException {
12764                            }
12765                        }, 0, null, null,
12766                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12767                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12768            } catch (Throwable t) {
12769                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12770            } finally {
12771                Binder.restoreCallingIdentity(ident);
12772            }
12773            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12774            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12775        }
12776    }
12777
12778    private boolean makeAppCrashingLocked(ProcessRecord app,
12779            String shortMsg, String longMsg, String stackTrace) {
12780        app.crashing = true;
12781        app.crashingReport = generateProcessError(app,
12782                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12783        startAppProblemLocked(app);
12784        app.stopFreezingAllLocked();
12785        return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12786    }
12787
12788    private void makeAppNotRespondingLocked(ProcessRecord app,
12789            String activity, String shortMsg, String longMsg) {
12790        app.notResponding = true;
12791        app.notRespondingReport = generateProcessError(app,
12792                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12793                activity, shortMsg, longMsg, null);
12794        startAppProblemLocked(app);
12795        app.stopFreezingAllLocked();
12796    }
12797
12798    /**
12799     * Generate a process error record, suitable for attachment to a ProcessRecord.
12800     *
12801     * @param app The ProcessRecord in which the error occurred.
12802     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
12803     *                      ActivityManager.AppErrorStateInfo
12804     * @param activity The activity associated with the crash, if known.
12805     * @param shortMsg Short message describing the crash.
12806     * @param longMsg Long message describing the crash.
12807     * @param stackTrace Full crash stack trace, may be null.
12808     *
12809     * @return Returns a fully-formed AppErrorStateInfo record.
12810     */
12811    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12812            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12813        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12814
12815        report.condition = condition;
12816        report.processName = app.processName;
12817        report.pid = app.pid;
12818        report.uid = app.info.uid;
12819        report.tag = activity;
12820        report.shortMsg = shortMsg;
12821        report.longMsg = longMsg;
12822        report.stackTrace = stackTrace;
12823
12824        return report;
12825    }
12826
12827    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12828        synchronized (this) {
12829            app.crashing = false;
12830            app.crashingReport = null;
12831            app.notResponding = false;
12832            app.notRespondingReport = null;
12833            if (app.anrDialog == fromDialog) {
12834                app.anrDialog = null;
12835            }
12836            if (app.waitDialog == fromDialog) {
12837                app.waitDialog = null;
12838            }
12839            if (app.pid > 0 && app.pid != MY_PID) {
12840                handleAppCrashLocked(app, "user-terminated" /*reason*/,
12841                        null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12842                app.kill("user request after error", true);
12843            }
12844        }
12845    }
12846
12847    private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12848            String shortMsg, String longMsg, String stackTrace) {
12849        long now = SystemClock.uptimeMillis();
12850
12851        Long crashTime;
12852        if (!app.isolated) {
12853            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12854        } else {
12855            crashTime = null;
12856        }
12857        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12858            // This process loses!
12859            Slog.w(TAG, "Process " + app.info.processName
12860                    + " has crashed too many times: killing!");
12861            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12862                    app.userId, app.info.processName, app.uid);
12863            mStackSupervisor.handleAppCrashLocked(app);
12864            if (!app.persistent) {
12865                // We don't want to start this process again until the user
12866                // explicitly does so...  but for persistent process, we really
12867                // need to keep it running.  If a persistent process is actually
12868                // repeatedly crashing, then badness for everyone.
12869                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12870                        app.info.processName);
12871                if (!app.isolated) {
12872                    // XXX We don't have a way to mark isolated processes
12873                    // as bad, since they don't have a peristent identity.
12874                    mBadProcesses.put(app.info.processName, app.uid,
12875                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12876                    mProcessCrashTimes.remove(app.info.processName, app.uid);
12877                }
12878                app.bad = true;
12879                app.removed = true;
12880                // Don't let services in this process be restarted and potentially
12881                // annoy the user repeatedly.  Unless it is persistent, since those
12882                // processes run critical code.
12883                removeProcessLocked(app, false, false, "crash");
12884                mStackSupervisor.resumeFocusedStackTopActivityLocked();
12885                return false;
12886            }
12887            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12888        } else {
12889            mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12890        }
12891
12892        // Bump up the crash count of any services currently running in the proc.
12893        for (int i=app.services.size()-1; i>=0; i--) {
12894            // Any services running in the application need to be placed
12895            // back in the pending list.
12896            ServiceRecord sr = app.services.valueAt(i);
12897            sr.crashCount++;
12898        }
12899
12900        // If the crashing process is what we consider to be the "home process" and it has been
12901        // replaced by a third-party app, clear the package preferred activities from packages
12902        // with a home activity running in the process to prevent a repeatedly crashing app
12903        // from blocking the user to manually clear the list.
12904        final ArrayList<ActivityRecord> activities = app.activities;
12905        if (app == mHomeProcess && activities.size() > 0
12906                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12907            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12908                final ActivityRecord r = activities.get(activityNdx);
12909                if (r.isHomeActivity()) {
12910                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12911                    try {
12912                        ActivityThread.getPackageManager()
12913                                .clearPackagePreferredActivities(r.packageName);
12914                    } catch (RemoteException c) {
12915                        // pm is in same process, this will never happen.
12916                    }
12917                }
12918            }
12919        }
12920
12921        if (!app.isolated) {
12922            // XXX Can't keep track of crash times for isolated processes,
12923            // because they don't have a perisistent identity.
12924            mProcessCrashTimes.put(app.info.processName, app.uid, now);
12925        }
12926
12927        if (app.crashHandler != null) mHandler.post(app.crashHandler);
12928        return true;
12929    }
12930
12931    void startAppProblemLocked(ProcessRecord app) {
12932        // If this app is not running under the current user, then we
12933        // can't give it a report button because that would require
12934        // launching the report UI under a different user.
12935        app.errorReportReceiver = null;
12936
12937        for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12938            if (app.userId == userId) {
12939                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12940                        mContext, app.info.packageName, app.info.flags);
12941            }
12942        }
12943        skipCurrentReceiverLocked(app);
12944    }
12945
12946    void skipCurrentReceiverLocked(ProcessRecord app) {
12947        for (BroadcastQueue queue : mBroadcastQueues) {
12948            queue.skipCurrentReceiverLocked(app);
12949        }
12950    }
12951
12952    /**
12953     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12954     * The application process will exit immediately after this call returns.
12955     * @param app object of the crashing app, null for the system server
12956     * @param crashInfo describing the exception
12957     */
12958    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12959        ProcessRecord r = findAppProcess(app, "Crash");
12960        final String processName = app == null ? "system_server"
12961                : (r == null ? "unknown" : r.processName);
12962
12963        handleApplicationCrashInner("crash", r, processName, crashInfo);
12964    }
12965
12966    /* Native crash reporting uses this inner version because it needs to be somewhat
12967     * decoupled from the AM-managed cleanup lifecycle
12968     */
12969    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12970            ApplicationErrorReport.CrashInfo crashInfo) {
12971        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12972                UserHandle.getUserId(Binder.getCallingUid()), processName,
12973                r == null ? -1 : r.info.flags,
12974                crashInfo.exceptionClassName,
12975                crashInfo.exceptionMessage,
12976                crashInfo.throwFileName,
12977                crashInfo.throwLineNumber);
12978
12979        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12980
12981        crashApplication(r, crashInfo);
12982    }
12983
12984    public void handleApplicationStrictModeViolation(
12985            IBinder app,
12986            int violationMask,
12987            StrictMode.ViolationInfo info) {
12988        ProcessRecord r = findAppProcess(app, "StrictMode");
12989        if (r == null) {
12990            return;
12991        }
12992
12993        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12994            Integer stackFingerprint = info.hashCode();
12995            boolean logIt = true;
12996            synchronized (mAlreadyLoggedViolatedStacks) {
12997                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12998                    logIt = false;
12999                    // TODO: sub-sample into EventLog for these, with
13000                    // the info.durationMillis?  Then we'd get
13001                    // the relative pain numbers, without logging all
13002                    // the stack traces repeatedly.  We'd want to do
13003                    // likewise in the client code, which also does
13004                    // dup suppression, before the Binder call.
13005                } else {
13006                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13007                        mAlreadyLoggedViolatedStacks.clear();
13008                    }
13009                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13010                }
13011            }
13012            if (logIt) {
13013                logStrictModeViolationToDropBox(r, info);
13014            }
13015        }
13016
13017        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13018            AppErrorResult result = new AppErrorResult();
13019            synchronized (this) {
13020                final long origId = Binder.clearCallingIdentity();
13021
13022                Message msg = Message.obtain();
13023                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13024                HashMap<String, Object> data = new HashMap<String, Object>();
13025                data.put("result", result);
13026                data.put("app", r);
13027                data.put("violationMask", violationMask);
13028                data.put("info", info);
13029                msg.obj = data;
13030                mUiHandler.sendMessage(msg);
13031
13032                Binder.restoreCallingIdentity(origId);
13033            }
13034            int res = result.get();
13035            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13036        }
13037    }
13038
13039    // Depending on the policy in effect, there could be a bunch of
13040    // these in quick succession so we try to batch these together to
13041    // minimize disk writes, number of dropbox entries, and maximize
13042    // compression, by having more fewer, larger records.
13043    private void logStrictModeViolationToDropBox(
13044            ProcessRecord process,
13045            StrictMode.ViolationInfo info) {
13046        if (info == null) {
13047            return;
13048        }
13049        final boolean isSystemApp = process == null ||
13050                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13051                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13052        final String processName = process == null ? "unknown" : process.processName;
13053        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13054        final DropBoxManager dbox = (DropBoxManager)
13055                mContext.getSystemService(Context.DROPBOX_SERVICE);
13056
13057        // Exit early if the dropbox isn't configured to accept this report type.
13058        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13059
13060        boolean bufferWasEmpty;
13061        boolean needsFlush;
13062        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13063        synchronized (sb) {
13064            bufferWasEmpty = sb.length() == 0;
13065            appendDropBoxProcessHeaders(process, processName, sb);
13066            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13067            sb.append("System-App: ").append(isSystemApp).append("\n");
13068            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13069            if (info.violationNumThisLoop != 0) {
13070                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13071            }
13072            if (info.numAnimationsRunning != 0) {
13073                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13074            }
13075            if (info.broadcastIntentAction != null) {
13076                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13077            }
13078            if (info.durationMillis != -1) {
13079                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13080            }
13081            if (info.numInstances != -1) {
13082                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13083            }
13084            if (info.tags != null) {
13085                for (String tag : info.tags) {
13086                    sb.append("Span-Tag: ").append(tag).append("\n");
13087                }
13088            }
13089            sb.append("\n");
13090            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13091                sb.append(info.crashInfo.stackTrace);
13092                sb.append("\n");
13093            }
13094            if (info.message != null) {
13095                sb.append(info.message);
13096                sb.append("\n");
13097            }
13098
13099            // Only buffer up to ~64k.  Various logging bits truncate
13100            // things at 128k.
13101            needsFlush = (sb.length() > 64 * 1024);
13102        }
13103
13104        // Flush immediately if the buffer's grown too large, or this
13105        // is a non-system app.  Non-system apps are isolated with a
13106        // different tag & policy and not batched.
13107        //
13108        // Batching is useful during internal testing with
13109        // StrictMode settings turned up high.  Without batching,
13110        // thousands of separate files could be created on boot.
13111        if (!isSystemApp || needsFlush) {
13112            new Thread("Error dump: " + dropboxTag) {
13113                @Override
13114                public void run() {
13115                    String report;
13116                    synchronized (sb) {
13117                        report = sb.toString();
13118                        sb.delete(0, sb.length());
13119                        sb.trimToSize();
13120                    }
13121                    if (report.length() != 0) {
13122                        dbox.addText(dropboxTag, report);
13123                    }
13124                }
13125            }.start();
13126            return;
13127        }
13128
13129        // System app batching:
13130        if (!bufferWasEmpty) {
13131            // An existing dropbox-writing thread is outstanding, so
13132            // we don't need to start it up.  The existing thread will
13133            // catch the buffer appends we just did.
13134            return;
13135        }
13136
13137        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13138        // (After this point, we shouldn't access AMS internal data structures.)
13139        new Thread("Error dump: " + dropboxTag) {
13140            @Override
13141            public void run() {
13142                // 5 second sleep to let stacks arrive and be batched together
13143                try {
13144                    Thread.sleep(5000);  // 5 seconds
13145                } catch (InterruptedException e) {}
13146
13147                String errorReport;
13148                synchronized (mStrictModeBuffer) {
13149                    errorReport = mStrictModeBuffer.toString();
13150                    if (errorReport.length() == 0) {
13151                        return;
13152                    }
13153                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13154                    mStrictModeBuffer.trimToSize();
13155                }
13156                dbox.addText(dropboxTag, errorReport);
13157            }
13158        }.start();
13159    }
13160
13161    /**
13162     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13163     * @param app object of the crashing app, null for the system server
13164     * @param tag reported by the caller
13165     * @param system whether this wtf is coming from the system
13166     * @param crashInfo describing the context of the error
13167     * @return true if the process should exit immediately (WTF is fatal)
13168     */
13169    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13170            final ApplicationErrorReport.CrashInfo crashInfo) {
13171        final int callingUid = Binder.getCallingUid();
13172        final int callingPid = Binder.getCallingPid();
13173
13174        if (system) {
13175            // If this is coming from the system, we could very well have low-level
13176            // system locks held, so we want to do this all asynchronously.  And we
13177            // never want this to become fatal, so there is that too.
13178            mHandler.post(new Runnable() {
13179                @Override public void run() {
13180                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13181                }
13182            });
13183            return false;
13184        }
13185
13186        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13187                crashInfo);
13188
13189        if (r != null && r.pid != Process.myPid() &&
13190                Settings.Global.getInt(mContext.getContentResolver(),
13191                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13192            crashApplication(r, crashInfo);
13193            return true;
13194        } else {
13195            return false;
13196        }
13197    }
13198
13199    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13200            final ApplicationErrorReport.CrashInfo crashInfo) {
13201        final ProcessRecord r = findAppProcess(app, "WTF");
13202        final String processName = app == null ? "system_server"
13203                : (r == null ? "unknown" : r.processName);
13204
13205        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13206                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13207
13208        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13209
13210        return r;
13211    }
13212
13213    /**
13214     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13215     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13216     */
13217    private ProcessRecord findAppProcess(IBinder app, String reason) {
13218        if (app == null) {
13219            return null;
13220        }
13221
13222        synchronized (this) {
13223            final int NP = mProcessNames.getMap().size();
13224            for (int ip=0; ip<NP; ip++) {
13225                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13226                final int NA = apps.size();
13227                for (int ia=0; ia<NA; ia++) {
13228                    ProcessRecord p = apps.valueAt(ia);
13229                    if (p.thread != null && p.thread.asBinder() == app) {
13230                        return p;
13231                    }
13232                }
13233            }
13234
13235            Slog.w(TAG, "Can't find mystery application for " + reason
13236                    + " from pid=" + Binder.getCallingPid()
13237                    + " uid=" + Binder.getCallingUid() + ": " + app);
13238            return null;
13239        }
13240    }
13241
13242    /**
13243     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13244     * to append various headers to the dropbox log text.
13245     */
13246    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13247            StringBuilder sb) {
13248        // Watchdog thread ends up invoking this function (with
13249        // a null ProcessRecord) to add the stack file to dropbox.
13250        // Do not acquire a lock on this (am) in such cases, as it
13251        // could cause a potential deadlock, if and when watchdog
13252        // is invoked due to unavailability of lock on am and it
13253        // would prevent watchdog from killing system_server.
13254        if (process == null) {
13255            sb.append("Process: ").append(processName).append("\n");
13256            return;
13257        }
13258        // Note: ProcessRecord 'process' is guarded by the service
13259        // instance.  (notably process.pkgList, which could otherwise change
13260        // concurrently during execution of this method)
13261        synchronized (this) {
13262            sb.append("Process: ").append(processName).append("\n");
13263            int flags = process.info.flags;
13264            IPackageManager pm = AppGlobals.getPackageManager();
13265            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13266            for (int ip=0; ip<process.pkgList.size(); ip++) {
13267                String pkg = process.pkgList.keyAt(ip);
13268                sb.append("Package: ").append(pkg);
13269                try {
13270                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13271                    if (pi != null) {
13272                        sb.append(" v").append(pi.versionCode);
13273                        if (pi.versionName != null) {
13274                            sb.append(" (").append(pi.versionName).append(")");
13275                        }
13276                    }
13277                } catch (RemoteException e) {
13278                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13279                }
13280                sb.append("\n");
13281            }
13282        }
13283    }
13284
13285    private static String processClass(ProcessRecord process) {
13286        if (process == null || process.pid == MY_PID) {
13287            return "system_server";
13288        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13289            return "system_app";
13290        } else {
13291            return "data_app";
13292        }
13293    }
13294
13295    /**
13296     * Write a description of an error (crash, WTF, ANR) to the drop box.
13297     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13298     * @param process which caused the error, null means the system server
13299     * @param activity which triggered the error, null if unknown
13300     * @param parent activity related to the error, null if unknown
13301     * @param subject line related to the error, null if absent
13302     * @param report in long form describing the error, null if absent
13303     * @param logFile to include in the report, null if none
13304     * @param crashInfo giving an application stack trace, null if absent
13305     */
13306    public void addErrorToDropBox(String eventType,
13307            ProcessRecord process, String processName, ActivityRecord activity,
13308            ActivityRecord parent, String subject,
13309            final String report, final File logFile,
13310            final ApplicationErrorReport.CrashInfo crashInfo) {
13311        // NOTE -- this must never acquire the ActivityManagerService lock,
13312        // otherwise the watchdog may be prevented from resetting the system.
13313
13314        final String dropboxTag = processClass(process) + "_" + eventType;
13315        final DropBoxManager dbox = (DropBoxManager)
13316                mContext.getSystemService(Context.DROPBOX_SERVICE);
13317
13318        // Exit early if the dropbox isn't configured to accept this report type.
13319        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13320
13321        final StringBuilder sb = new StringBuilder(1024);
13322        appendDropBoxProcessHeaders(process, processName, sb);
13323        if (activity != null) {
13324            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13325        }
13326        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13327            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13328        }
13329        if (parent != null && parent != activity) {
13330            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13331        }
13332        if (subject != null) {
13333            sb.append("Subject: ").append(subject).append("\n");
13334        }
13335        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13336        if (Debug.isDebuggerConnected()) {
13337            sb.append("Debugger: Connected\n");
13338        }
13339        sb.append("\n");
13340
13341        // Do the rest in a worker thread to avoid blocking the caller on I/O
13342        // (After this point, we shouldn't access AMS internal data structures.)
13343        Thread worker = new Thread("Error dump: " + dropboxTag) {
13344            @Override
13345            public void run() {
13346                if (report != null) {
13347                    sb.append(report);
13348                }
13349                if (logFile != null) {
13350                    try {
13351                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13352                                    "\n\n[[TRUNCATED]]"));
13353                    } catch (IOException e) {
13354                        Slog.e(TAG, "Error reading " + logFile, e);
13355                    }
13356                }
13357                if (crashInfo != null && crashInfo.stackTrace != null) {
13358                    sb.append(crashInfo.stackTrace);
13359                }
13360
13361                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13362                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13363                if (lines > 0) {
13364                    sb.append("\n");
13365
13366                    // Merge several logcat streams, and take the last N lines
13367                    InputStreamReader input = null;
13368                    try {
13369                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13370                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13371                                "-b", "crash",
13372                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13373
13374                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13375                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13376                        input = new InputStreamReader(logcat.getInputStream());
13377
13378                        int num;
13379                        char[] buf = new char[8192];
13380                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13381                    } catch (IOException e) {
13382                        Slog.e(TAG, "Error running logcat", e);
13383                    } finally {
13384                        if (input != null) try { input.close(); } catch (IOException e) {}
13385                    }
13386                }
13387
13388                dbox.addText(dropboxTag, sb.toString());
13389            }
13390        };
13391
13392        if (process == null) {
13393            // If process is null, we are being called from some internal code
13394            // and may be about to die -- run this synchronously.
13395            worker.run();
13396        } else {
13397            worker.start();
13398        }
13399    }
13400
13401    /**
13402     * Bring up the "unexpected error" dialog box for a crashing app.
13403     * Deal with edge cases (intercepts from instrumented applications,
13404     * ActivityController, error intent receivers, that sort of thing).
13405     * @param r the application crashing
13406     * @param crashInfo describing the failure
13407     */
13408    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13409        long timeMillis = System.currentTimeMillis();
13410        String shortMsg = crashInfo.exceptionClassName;
13411        String longMsg = crashInfo.exceptionMessage;
13412        String stackTrace = crashInfo.stackTrace;
13413        if (shortMsg != null && longMsg != null) {
13414            longMsg = shortMsg + ": " + longMsg;
13415        } else if (shortMsg != null) {
13416            longMsg = shortMsg;
13417        }
13418
13419        AppErrorResult result = new AppErrorResult();
13420        synchronized (this) {
13421            if (mController != null) {
13422                try {
13423                    String name = r != null ? r.processName : null;
13424                    int pid = r != null ? r.pid : Binder.getCallingPid();
13425                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
13426                    if (!mController.appCrashed(name, pid,
13427                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13428                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13429                                && "Native crash".equals(crashInfo.exceptionClassName)) {
13430                            Slog.w(TAG, "Skip killing native crashed app " + name
13431                                    + "(" + pid + ") during testing");
13432                        } else {
13433                            Slog.w(TAG, "Force-killing crashed app " + name
13434                                    + " at watcher's request");
13435                            if (r != null) {
13436                                r.kill("crash", true);
13437                            } else {
13438                                // Huh.
13439                                Process.killProcess(pid);
13440                                killProcessGroup(uid, pid);
13441                            }
13442                        }
13443                        return;
13444                    }
13445                } catch (RemoteException e) {
13446                    mController = null;
13447                    Watchdog.getInstance().setActivityController(null);
13448                }
13449            }
13450
13451            final long origId = Binder.clearCallingIdentity();
13452
13453            // If this process is running instrumentation, finish it.
13454            if (r != null && r.instrumentationClass != null) {
13455                Slog.w(TAG, "Error in app " + r.processName
13456                      + " running instrumentation " + r.instrumentationClass + ":");
13457                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
13458                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
13459                Bundle info = new Bundle();
13460                info.putString("shortMsg", shortMsg);
13461                info.putString("longMsg", longMsg);
13462                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13463                Binder.restoreCallingIdentity(origId);
13464                return;
13465            }
13466
13467            // Log crash in battery stats.
13468            if (r != null) {
13469                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13470            }
13471
13472            // If we can't identify the process or it's already exceeded its crash quota,
13473            // quit right away without showing a crash dialog.
13474            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13475                Binder.restoreCallingIdentity(origId);
13476                return;
13477            }
13478
13479            Message msg = Message.obtain();
13480            msg.what = SHOW_ERROR_UI_MSG;
13481            HashMap data = new HashMap();
13482            data.put("result", result);
13483            data.put("app", r);
13484            msg.obj = data;
13485            mUiHandler.sendMessage(msg);
13486
13487            Binder.restoreCallingIdentity(origId);
13488        }
13489
13490        int res = result.get();
13491
13492        Intent appErrorIntent = null;
13493        synchronized (this) {
13494            if (r != null && !r.isolated) {
13495                // XXX Can't keep track of crash time for isolated processes,
13496                // since they don't have a persistent identity.
13497                mProcessCrashTimes.put(r.info.processName, r.uid,
13498                        SystemClock.uptimeMillis());
13499            }
13500            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13501                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13502            }
13503        }
13504
13505        if (appErrorIntent != null) {
13506            try {
13507                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13508            } catch (ActivityNotFoundException e) {
13509                Slog.w(TAG, "bug report receiver dissappeared", e);
13510            }
13511        }
13512    }
13513
13514    Intent createAppErrorIntentLocked(ProcessRecord r,
13515            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13516        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13517        if (report == null) {
13518            return null;
13519        }
13520        Intent result = new Intent(Intent.ACTION_APP_ERROR);
13521        result.setComponent(r.errorReportReceiver);
13522        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13523        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13524        return result;
13525    }
13526
13527    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13528            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13529        if (r.errorReportReceiver == null) {
13530            return null;
13531        }
13532
13533        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13534            return null;
13535        }
13536
13537        ApplicationErrorReport report = new ApplicationErrorReport();
13538        report.packageName = r.info.packageName;
13539        report.installerPackageName = r.errorReportReceiver.getPackageName();
13540        report.processName = r.processName;
13541        report.time = timeMillis;
13542        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13543
13544        if (r.crashing || r.forceCrashReport) {
13545            report.type = ApplicationErrorReport.TYPE_CRASH;
13546            report.crashInfo = crashInfo;
13547        } else if (r.notResponding) {
13548            report.type = ApplicationErrorReport.TYPE_ANR;
13549            report.anrInfo = new ApplicationErrorReport.AnrInfo();
13550
13551            report.anrInfo.activity = r.notRespondingReport.tag;
13552            report.anrInfo.cause = r.notRespondingReport.shortMsg;
13553            report.anrInfo.info = r.notRespondingReport.longMsg;
13554        }
13555
13556        return report;
13557    }
13558
13559    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13560        enforceNotIsolatedCaller("getProcessesInErrorState");
13561        // assume our apps are happy - lazy create the list
13562        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13563
13564        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13565                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13566        int userId = UserHandle.getUserId(Binder.getCallingUid());
13567
13568        synchronized (this) {
13569
13570            // iterate across all processes
13571            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13572                ProcessRecord app = mLruProcesses.get(i);
13573                if (!allUsers && app.userId != userId) {
13574                    continue;
13575                }
13576                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13577                    // This one's in trouble, so we'll generate a report for it
13578                    // crashes are higher priority (in case there's a crash *and* an anr)
13579                    ActivityManager.ProcessErrorStateInfo report = null;
13580                    if (app.crashing) {
13581                        report = app.crashingReport;
13582                    } else if (app.notResponding) {
13583                        report = app.notRespondingReport;
13584                    }
13585
13586                    if (report != null) {
13587                        if (errList == null) {
13588                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13589                        }
13590                        errList.add(report);
13591                    } else {
13592                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13593                                " crashing = " + app.crashing +
13594                                " notResponding = " + app.notResponding);
13595                    }
13596                }
13597            }
13598        }
13599
13600        return errList;
13601    }
13602
13603    static int procStateToImportance(int procState, int memAdj,
13604            ActivityManager.RunningAppProcessInfo currApp) {
13605        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13606        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13607            currApp.lru = memAdj;
13608        } else {
13609            currApp.lru = 0;
13610        }
13611        return imp;
13612    }
13613
13614    private void fillInProcMemInfo(ProcessRecord app,
13615            ActivityManager.RunningAppProcessInfo outInfo) {
13616        outInfo.pid = app.pid;
13617        outInfo.uid = app.info.uid;
13618        if (mHeavyWeightProcess == app) {
13619            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13620        }
13621        if (app.persistent) {
13622            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13623        }
13624        if (app.activities.size() > 0) {
13625            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13626        }
13627        outInfo.lastTrimLevel = app.trimMemoryLevel;
13628        int adj = app.curAdj;
13629        int procState = app.curProcState;
13630        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13631        outInfo.importanceReasonCode = app.adjTypeCode;
13632        outInfo.processState = app.curProcState;
13633    }
13634
13635    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13636        enforceNotIsolatedCaller("getRunningAppProcesses");
13637
13638        final int callingUid = Binder.getCallingUid();
13639
13640        // Lazy instantiation of list
13641        List<ActivityManager.RunningAppProcessInfo> runList = null;
13642        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13643                callingUid) == PackageManager.PERMISSION_GRANTED;
13644        final int userId = UserHandle.getUserId(callingUid);
13645        final boolean allUids = isGetTasksAllowed(
13646                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13647
13648        synchronized (this) {
13649            // Iterate across all processes
13650            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13651                ProcessRecord app = mLruProcesses.get(i);
13652                if ((!allUsers && app.userId != userId)
13653                        || (!allUids && app.uid != callingUid)) {
13654                    continue;
13655                }
13656                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13657                    // Generate process state info for running application
13658                    ActivityManager.RunningAppProcessInfo currApp =
13659                        new ActivityManager.RunningAppProcessInfo(app.processName,
13660                                app.pid, app.getPackageList());
13661                    fillInProcMemInfo(app, currApp);
13662                    if (app.adjSource instanceof ProcessRecord) {
13663                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13664                        currApp.importanceReasonImportance =
13665                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13666                                        app.adjSourceProcState);
13667                    } else if (app.adjSource instanceof ActivityRecord) {
13668                        ActivityRecord r = (ActivityRecord)app.adjSource;
13669                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13670                    }
13671                    if (app.adjTarget instanceof ComponentName) {
13672                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13673                    }
13674                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13675                    //        + " lru=" + currApp.lru);
13676                    if (runList == null) {
13677                        runList = new ArrayList<>();
13678                    }
13679                    runList.add(currApp);
13680                }
13681            }
13682        }
13683        return runList;
13684    }
13685
13686    public List<ApplicationInfo> getRunningExternalApplications() {
13687        enforceNotIsolatedCaller("getRunningExternalApplications");
13688        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13689        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13690        if (runningApps != null && runningApps.size() > 0) {
13691            Set<String> extList = new HashSet<String>();
13692            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13693                if (app.pkgList != null) {
13694                    for (String pkg : app.pkgList) {
13695                        extList.add(pkg);
13696                    }
13697                }
13698            }
13699            IPackageManager pm = AppGlobals.getPackageManager();
13700            for (String pkg : extList) {
13701                try {
13702                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13703                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13704                        retList.add(info);
13705                    }
13706                } catch (RemoteException e) {
13707                }
13708            }
13709        }
13710        return retList;
13711    }
13712
13713    @Override
13714    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13715        enforceNotIsolatedCaller("getMyMemoryState");
13716        synchronized (this) {
13717            ProcessRecord proc;
13718            synchronized (mPidsSelfLocked) {
13719                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13720            }
13721            fillInProcMemInfo(proc, outInfo);
13722        }
13723    }
13724
13725    @Override
13726    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13727            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13728        (new ActivityManagerShellCommand(this, false)).exec(
13729                this, in, out, err, args, resultReceiver);
13730    }
13731
13732    @Override
13733    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13734        if (checkCallingPermission(android.Manifest.permission.DUMP)
13735                != PackageManager.PERMISSION_GRANTED) {
13736            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13737                    + Binder.getCallingPid()
13738                    + ", uid=" + Binder.getCallingUid()
13739                    + " without permission "
13740                    + android.Manifest.permission.DUMP);
13741            return;
13742        }
13743
13744        boolean dumpAll = false;
13745        boolean dumpClient = false;
13746        String dumpPackage = null;
13747
13748        int opti = 0;
13749        while (opti < args.length) {
13750            String opt = args[opti];
13751            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13752                break;
13753            }
13754            opti++;
13755            if ("-a".equals(opt)) {
13756                dumpAll = true;
13757            } else if ("-c".equals(opt)) {
13758                dumpClient = true;
13759            } else if ("-p".equals(opt)) {
13760                if (opti < args.length) {
13761                    dumpPackage = args[opti];
13762                    opti++;
13763                } else {
13764                    pw.println("Error: -p option requires package argument");
13765                    return;
13766                }
13767                dumpClient = true;
13768            } else if ("-h".equals(opt)) {
13769                ActivityManagerShellCommand.dumpHelp(pw, true);
13770                return;
13771            } else {
13772                pw.println("Unknown argument: " + opt + "; use -h for help");
13773            }
13774        }
13775
13776        long origId = Binder.clearCallingIdentity();
13777        boolean more = false;
13778        // Is the caller requesting to dump a particular piece of data?
13779        if (opti < args.length) {
13780            String cmd = args[opti];
13781            opti++;
13782            if ("activities".equals(cmd) || "a".equals(cmd)) {
13783                synchronized (this) {
13784                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13785                }
13786            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13787                synchronized (this) {
13788                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13789                }
13790            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13791                String[] newArgs;
13792                String name;
13793                if (opti >= args.length) {
13794                    name = null;
13795                    newArgs = EMPTY_STRING_ARRAY;
13796                } else {
13797                    dumpPackage = args[opti];
13798                    opti++;
13799                    newArgs = new String[args.length - opti];
13800                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13801                            args.length - opti);
13802                }
13803                synchronized (this) {
13804                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13805                }
13806            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13807                String[] newArgs;
13808                String name;
13809                if (opti >= args.length) {
13810                    name = null;
13811                    newArgs = EMPTY_STRING_ARRAY;
13812                } else {
13813                    dumpPackage = args[opti];
13814                    opti++;
13815                    newArgs = new String[args.length - opti];
13816                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13817                            args.length - opti);
13818                }
13819                synchronized (this) {
13820                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13821                }
13822            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13823                String[] newArgs;
13824                String name;
13825                if (opti >= args.length) {
13826                    name = null;
13827                    newArgs = EMPTY_STRING_ARRAY;
13828                } else {
13829                    dumpPackage = args[opti];
13830                    opti++;
13831                    newArgs = new String[args.length - opti];
13832                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13833                            args.length - opti);
13834                }
13835                synchronized (this) {
13836                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13837                }
13838            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13839                synchronized (this) {
13840                    dumpOomLocked(fd, pw, args, opti, true);
13841                }
13842            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13843                synchronized (this) {
13844                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13845                }
13846            } else if ("provider".equals(cmd)) {
13847                String[] newArgs;
13848                String name;
13849                if (opti >= args.length) {
13850                    name = null;
13851                    newArgs = EMPTY_STRING_ARRAY;
13852                } else {
13853                    name = args[opti];
13854                    opti++;
13855                    newArgs = new String[args.length - opti];
13856                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13857                }
13858                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13859                    pw.println("No providers match: " + name);
13860                    pw.println("Use -h for help.");
13861                }
13862            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13863                synchronized (this) {
13864                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13865                }
13866            } else if ("service".equals(cmd)) {
13867                String[] newArgs;
13868                String name;
13869                if (opti >= args.length) {
13870                    name = null;
13871                    newArgs = EMPTY_STRING_ARRAY;
13872                } else {
13873                    name = args[opti];
13874                    opti++;
13875                    newArgs = new String[args.length - opti];
13876                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13877                            args.length - opti);
13878                }
13879                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13880                    pw.println("No services match: " + name);
13881                    pw.println("Use -h for help.");
13882                }
13883            } else if ("package".equals(cmd)) {
13884                String[] newArgs;
13885                if (opti >= args.length) {
13886                    pw.println("package: no package name specified");
13887                    pw.println("Use -h for help.");
13888                } else {
13889                    dumpPackage = args[opti];
13890                    opti++;
13891                    newArgs = new String[args.length - opti];
13892                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13893                            args.length - opti);
13894                    args = newArgs;
13895                    opti = 0;
13896                    more = true;
13897                }
13898            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13899                synchronized (this) {
13900                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13901                }
13902            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13903                synchronized (this) {
13904                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13905                }
13906            } else {
13907                // Dumping a single activity?
13908                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13909                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13910                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13911                    if (res < 0) {
13912                        pw.println("Bad activity command, or no activities match: " + cmd);
13913                        pw.println("Use -h for help.");
13914                    }
13915                }
13916            }
13917            if (!more) {
13918                Binder.restoreCallingIdentity(origId);
13919                return;
13920            }
13921        }
13922
13923        // No piece of data specified, dump everything.
13924        synchronized (this) {
13925            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13926            pw.println();
13927            if (dumpAll) {
13928                pw.println("-------------------------------------------------------------------------------");
13929            }
13930            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13931            pw.println();
13932            if (dumpAll) {
13933                pw.println("-------------------------------------------------------------------------------");
13934            }
13935            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13936            pw.println();
13937            if (dumpAll) {
13938                pw.println("-------------------------------------------------------------------------------");
13939            }
13940            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13941            pw.println();
13942            if (dumpAll) {
13943                pw.println("-------------------------------------------------------------------------------");
13944            }
13945            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13946            pw.println();
13947            if (dumpAll) {
13948                pw.println("-------------------------------------------------------------------------------");
13949            }
13950            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13951            pw.println();
13952            if (dumpAll) {
13953                pw.println("-------------------------------------------------------------------------------");
13954            }
13955            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13956            if (mAssociations.size() > 0) {
13957                pw.println();
13958                if (dumpAll) {
13959                    pw.println("-------------------------------------------------------------------------------");
13960                }
13961                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13962            }
13963            pw.println();
13964            if (dumpAll) {
13965                pw.println("-------------------------------------------------------------------------------");
13966            }
13967            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13968        }
13969        Binder.restoreCallingIdentity(origId);
13970    }
13971
13972    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13973            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13974        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13975
13976        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13977                dumpPackage);
13978        boolean needSep = printedAnything;
13979
13980        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13981                dumpPackage, needSep, "  mFocusedActivity: ");
13982        if (printed) {
13983            printedAnything = true;
13984            needSep = false;
13985        }
13986
13987        if (dumpPackage == null) {
13988            if (needSep) {
13989                pw.println();
13990            }
13991            needSep = true;
13992            printedAnything = true;
13993            mStackSupervisor.dump(pw, "  ");
13994        }
13995
13996        if (!printedAnything) {
13997            pw.println("  (nothing)");
13998        }
13999    }
14000
14001    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14002            int opti, boolean dumpAll, String dumpPackage) {
14003        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14004
14005        boolean printedAnything = false;
14006
14007        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14008            boolean printedHeader = false;
14009
14010            final int N = mRecentTasks.size();
14011            for (int i=0; i<N; i++) {
14012                TaskRecord tr = mRecentTasks.get(i);
14013                if (dumpPackage != null) {
14014                    if (tr.realActivity == null ||
14015                            !dumpPackage.equals(tr.realActivity)) {
14016                        continue;
14017                    }
14018                }
14019                if (!printedHeader) {
14020                    pw.println("  Recent tasks:");
14021                    printedHeader = true;
14022                    printedAnything = true;
14023                }
14024                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14025                        pw.println(tr);
14026                if (dumpAll) {
14027                    mRecentTasks.get(i).dump(pw, "    ");
14028                }
14029            }
14030        }
14031
14032        if (!printedAnything) {
14033            pw.println("  (nothing)");
14034        }
14035    }
14036
14037    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14038            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14039        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14040
14041        int dumpUid = 0;
14042        if (dumpPackage != null) {
14043            IPackageManager pm = AppGlobals.getPackageManager();
14044            try {
14045                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14046            } catch (RemoteException e) {
14047            }
14048        }
14049
14050        boolean printedAnything = false;
14051
14052        final long now = SystemClock.uptimeMillis();
14053
14054        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14055            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14056                    = mAssociations.valueAt(i1);
14057            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14058                SparseArray<ArrayMap<String, Association>> sourceUids
14059                        = targetComponents.valueAt(i2);
14060                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14061                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14062                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14063                        Association ass = sourceProcesses.valueAt(i4);
14064                        if (dumpPackage != null) {
14065                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14066                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14067                                continue;
14068                            }
14069                        }
14070                        printedAnything = true;
14071                        pw.print("  ");
14072                        pw.print(ass.mTargetProcess);
14073                        pw.print("/");
14074                        UserHandle.formatUid(pw, ass.mTargetUid);
14075                        pw.print(" <- ");
14076                        pw.print(ass.mSourceProcess);
14077                        pw.print("/");
14078                        UserHandle.formatUid(pw, ass.mSourceUid);
14079                        pw.println();
14080                        pw.print("    via ");
14081                        pw.print(ass.mTargetComponent.flattenToShortString());
14082                        pw.println();
14083                        pw.print("    ");
14084                        long dur = ass.mTime;
14085                        if (ass.mNesting > 0) {
14086                            dur += now - ass.mStartTime;
14087                        }
14088                        TimeUtils.formatDuration(dur, pw);
14089                        pw.print(" (");
14090                        pw.print(ass.mCount);
14091                        pw.println(" times)");
14092                        if (ass.mNesting > 0) {
14093                            pw.print("    ");
14094                            pw.print(" Currently active: ");
14095                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14096                            pw.println();
14097                        }
14098                    }
14099                }
14100            }
14101
14102        }
14103
14104        if (!printedAnything) {
14105            pw.println("  (nothing)");
14106        }
14107    }
14108
14109    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14110            String header, boolean needSep) {
14111        boolean printed = false;
14112        int whichAppId = -1;
14113        if (dumpPackage != null) {
14114            try {
14115                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14116                        dumpPackage, 0);
14117                whichAppId = UserHandle.getAppId(info.uid);
14118            } catch (NameNotFoundException e) {
14119                e.printStackTrace();
14120            }
14121        }
14122        for (int i=0; i<uids.size(); i++) {
14123            UidRecord uidRec = uids.valueAt(i);
14124            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14125                continue;
14126            }
14127            if (!printed) {
14128                printed = true;
14129                if (needSep) {
14130                    pw.println();
14131                }
14132                pw.print("  ");
14133                pw.println(header);
14134                needSep = true;
14135            }
14136            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14137            pw.print(": "); pw.println(uidRec);
14138        }
14139        return printed;
14140    }
14141
14142    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14143            int opti, boolean dumpAll, String dumpPackage) {
14144        boolean needSep = false;
14145        boolean printedAnything = false;
14146        int numPers = 0;
14147
14148        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14149
14150        if (dumpAll) {
14151            final int NP = mProcessNames.getMap().size();
14152            for (int ip=0; ip<NP; ip++) {
14153                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14154                final int NA = procs.size();
14155                for (int ia=0; ia<NA; ia++) {
14156                    ProcessRecord r = procs.valueAt(ia);
14157                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14158                        continue;
14159                    }
14160                    if (!needSep) {
14161                        pw.println("  All known processes:");
14162                        needSep = true;
14163                        printedAnything = true;
14164                    }
14165                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14166                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14167                        pw.print(" "); pw.println(r);
14168                    r.dump(pw, "    ");
14169                    if (r.persistent) {
14170                        numPers++;
14171                    }
14172                }
14173            }
14174        }
14175
14176        if (mIsolatedProcesses.size() > 0) {
14177            boolean printed = false;
14178            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14179                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14180                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14181                    continue;
14182                }
14183                if (!printed) {
14184                    if (needSep) {
14185                        pw.println();
14186                    }
14187                    pw.println("  Isolated process list (sorted by uid):");
14188                    printedAnything = true;
14189                    printed = true;
14190                    needSep = true;
14191                }
14192                pw.println(String.format("%sIsolated #%2d: %s",
14193                        "    ", i, r.toString()));
14194            }
14195        }
14196
14197        if (mActiveUids.size() > 0) {
14198            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14199                printedAnything = needSep = true;
14200            }
14201        }
14202        if (mValidateUids.size() > 0) {
14203            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14204                printedAnything = needSep = true;
14205            }
14206        }
14207
14208        if (mLruProcesses.size() > 0) {
14209            if (needSep) {
14210                pw.println();
14211            }
14212            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14213                    pw.print(" total, non-act at ");
14214                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14215                    pw.print(", non-svc at ");
14216                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14217                    pw.println("):");
14218            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14219            needSep = true;
14220            printedAnything = true;
14221        }
14222
14223        if (dumpAll || dumpPackage != null) {
14224            synchronized (mPidsSelfLocked) {
14225                boolean printed = false;
14226                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14227                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14228                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14229                        continue;
14230                    }
14231                    if (!printed) {
14232                        if (needSep) pw.println();
14233                        needSep = true;
14234                        pw.println("  PID mappings:");
14235                        printed = true;
14236                        printedAnything = true;
14237                    }
14238                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14239                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14240                }
14241            }
14242        }
14243
14244        if (mForegroundProcesses.size() > 0) {
14245            synchronized (mPidsSelfLocked) {
14246                boolean printed = false;
14247                for (int i=0; i<mForegroundProcesses.size(); i++) {
14248                    ProcessRecord r = mPidsSelfLocked.get(
14249                            mForegroundProcesses.valueAt(i).pid);
14250                    if (dumpPackage != null && (r == null
14251                            || !r.pkgList.containsKey(dumpPackage))) {
14252                        continue;
14253                    }
14254                    if (!printed) {
14255                        if (needSep) pw.println();
14256                        needSep = true;
14257                        pw.println("  Foreground Processes:");
14258                        printed = true;
14259                        printedAnything = true;
14260                    }
14261                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14262                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14263                }
14264            }
14265        }
14266
14267        if (mPersistentStartingProcesses.size() > 0) {
14268            if (needSep) pw.println();
14269            needSep = true;
14270            printedAnything = true;
14271            pw.println("  Persisent processes that are starting:");
14272            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14273                    "Starting Norm", "Restarting PERS", dumpPackage);
14274        }
14275
14276        if (mRemovedProcesses.size() > 0) {
14277            if (needSep) pw.println();
14278            needSep = true;
14279            printedAnything = true;
14280            pw.println("  Processes that are being removed:");
14281            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14282                    "Removed Norm", "Removed PERS", dumpPackage);
14283        }
14284
14285        if (mProcessesOnHold.size() > 0) {
14286            if (needSep) pw.println();
14287            needSep = true;
14288            printedAnything = true;
14289            pw.println("  Processes that are on old until the system is ready:");
14290            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14291                    "OnHold Norm", "OnHold PERS", dumpPackage);
14292        }
14293
14294        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14295
14296        if (mProcessCrashTimes.getMap().size() > 0) {
14297            boolean printed = false;
14298            long now = SystemClock.uptimeMillis();
14299            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14300            final int NP = pmap.size();
14301            for (int ip=0; ip<NP; ip++) {
14302                String pname = pmap.keyAt(ip);
14303                SparseArray<Long> uids = pmap.valueAt(ip);
14304                final int N = uids.size();
14305                for (int i=0; i<N; i++) {
14306                    int puid = uids.keyAt(i);
14307                    ProcessRecord r = mProcessNames.get(pname, puid);
14308                    if (dumpPackage != null && (r == null
14309                            || !r.pkgList.containsKey(dumpPackage))) {
14310                        continue;
14311                    }
14312                    if (!printed) {
14313                        if (needSep) pw.println();
14314                        needSep = true;
14315                        pw.println("  Time since processes crashed:");
14316                        printed = true;
14317                        printedAnything = true;
14318                    }
14319                    pw.print("    Process "); pw.print(pname);
14320                            pw.print(" uid "); pw.print(puid);
14321                            pw.print(": last crashed ");
14322                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14323                            pw.println(" ago");
14324                }
14325            }
14326        }
14327
14328        if (mBadProcesses.getMap().size() > 0) {
14329            boolean printed = false;
14330            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14331            final int NP = pmap.size();
14332            for (int ip=0; ip<NP; ip++) {
14333                String pname = pmap.keyAt(ip);
14334                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14335                final int N = uids.size();
14336                for (int i=0; i<N; i++) {
14337                    int puid = uids.keyAt(i);
14338                    ProcessRecord r = mProcessNames.get(pname, puid);
14339                    if (dumpPackage != null && (r == null
14340                            || !r.pkgList.containsKey(dumpPackage))) {
14341                        continue;
14342                    }
14343                    if (!printed) {
14344                        if (needSep) pw.println();
14345                        needSep = true;
14346                        pw.println("  Bad processes:");
14347                        printedAnything = true;
14348                    }
14349                    BadProcessInfo info = uids.valueAt(i);
14350                    pw.print("    Bad process "); pw.print(pname);
14351                            pw.print(" uid "); pw.print(puid);
14352                            pw.print(": crashed at time "); pw.println(info.time);
14353                    if (info.shortMsg != null) {
14354                        pw.print("      Short msg: "); pw.println(info.shortMsg);
14355                    }
14356                    if (info.longMsg != null) {
14357                        pw.print("      Long msg: "); pw.println(info.longMsg);
14358                    }
14359                    if (info.stack != null) {
14360                        pw.println("      Stack:");
14361                        int lastPos = 0;
14362                        for (int pos=0; pos<info.stack.length(); pos++) {
14363                            if (info.stack.charAt(pos) == '\n') {
14364                                pw.print("        ");
14365                                pw.write(info.stack, lastPos, pos-lastPos);
14366                                pw.println();
14367                                lastPos = pos+1;
14368                            }
14369                        }
14370                        if (lastPos < info.stack.length()) {
14371                            pw.print("        ");
14372                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14373                            pw.println();
14374                        }
14375                    }
14376                }
14377            }
14378        }
14379
14380        if (dumpPackage == null) {
14381            pw.println();
14382            needSep = false;
14383            mUserController.dump(pw, dumpAll);
14384        }
14385        if (mHomeProcess != null && (dumpPackage == null
14386                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14387            if (needSep) {
14388                pw.println();
14389                needSep = false;
14390            }
14391            pw.println("  mHomeProcess: " + mHomeProcess);
14392        }
14393        if (mPreviousProcess != null && (dumpPackage == null
14394                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14395            if (needSep) {
14396                pw.println();
14397                needSep = false;
14398            }
14399            pw.println("  mPreviousProcess: " + mPreviousProcess);
14400        }
14401        if (dumpAll) {
14402            StringBuilder sb = new StringBuilder(128);
14403            sb.append("  mPreviousProcessVisibleTime: ");
14404            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14405            pw.println(sb);
14406        }
14407        if (mHeavyWeightProcess != null && (dumpPackage == null
14408                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14409            if (needSep) {
14410                pw.println();
14411                needSep = false;
14412            }
14413            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14414        }
14415        if (dumpPackage == null) {
14416            pw.println("  mConfiguration: " + mConfiguration);
14417        }
14418        if (dumpAll) {
14419            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14420            if (mCompatModePackages.getPackages().size() > 0) {
14421                boolean printed = false;
14422                for (Map.Entry<String, Integer> entry
14423                        : mCompatModePackages.getPackages().entrySet()) {
14424                    String pkg = entry.getKey();
14425                    int mode = entry.getValue();
14426                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14427                        continue;
14428                    }
14429                    if (!printed) {
14430                        pw.println("  mScreenCompatPackages:");
14431                        printed = true;
14432                    }
14433                    pw.print("    "); pw.print(pkg); pw.print(": ");
14434                            pw.print(mode); pw.println();
14435                }
14436            }
14437        }
14438        if (dumpPackage == null) {
14439            pw.println("  mWakefulness="
14440                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14441            pw.println("  mSleepTokens=" + mSleepTokens);
14442            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14443                    + lockScreenShownToString());
14444            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14445            if (mRunningVoice != null) {
14446                pw.println("  mRunningVoice=" + mRunningVoice);
14447                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14448            }
14449        }
14450        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14451                || mOrigWaitForDebugger) {
14452            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14453                    || dumpPackage.equals(mOrigDebugApp)) {
14454                if (needSep) {
14455                    pw.println();
14456                    needSep = false;
14457                }
14458                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14459                        + " mDebugTransient=" + mDebugTransient
14460                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14461            }
14462        }
14463        if (mCurAppTimeTracker != null) {
14464            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14465        }
14466        if (mMemWatchProcesses.getMap().size() > 0) {
14467            pw.println("  Mem watch processes:");
14468            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14469                    = mMemWatchProcesses.getMap();
14470            for (int i=0; i<procs.size(); i++) {
14471                final String proc = procs.keyAt(i);
14472                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14473                for (int j=0; j<uids.size(); j++) {
14474                    if (needSep) {
14475                        pw.println();
14476                        needSep = false;
14477                    }
14478                    StringBuilder sb = new StringBuilder();
14479                    sb.append("    ").append(proc).append('/');
14480                    UserHandle.formatUid(sb, uids.keyAt(j));
14481                    Pair<Long, String> val = uids.valueAt(j);
14482                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14483                    if (val.second != null) {
14484                        sb.append(", report to ").append(val.second);
14485                    }
14486                    pw.println(sb.toString());
14487                }
14488            }
14489            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14490            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14491            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14492                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14493        }
14494        if (mTrackAllocationApp != null) {
14495            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14496                if (needSep) {
14497                    pw.println();
14498                    needSep = false;
14499                }
14500                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14501            }
14502        }
14503        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14504                || mProfileFd != null) {
14505            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14506                if (needSep) {
14507                    pw.println();
14508                    needSep = false;
14509                }
14510                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14511                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14512                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14513                        + mAutoStopProfiler);
14514                pw.println("  mProfileType=" + mProfileType);
14515            }
14516        }
14517        if (dumpPackage == null) {
14518            if (mAlwaysFinishActivities || mController != null) {
14519                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14520                        + " mController=" + mController);
14521            }
14522            if (dumpAll) {
14523                pw.println("  Total persistent processes: " + numPers);
14524                pw.println("  mProcessesReady=" + mProcessesReady
14525                        + " mSystemReady=" + mSystemReady
14526                        + " mBooted=" + mBooted
14527                        + " mFactoryTest=" + mFactoryTest);
14528                pw.println("  mBooting=" + mBooting
14529                        + " mCallFinishBooting=" + mCallFinishBooting
14530                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14531                pw.print("  mLastPowerCheckRealtime=");
14532                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14533                        pw.println("");
14534                pw.print("  mLastPowerCheckUptime=");
14535                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14536                        pw.println("");
14537                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14538                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14539                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14540                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14541                        + " (" + mLruProcesses.size() + " total)"
14542                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14543                        + " mNumServiceProcs=" + mNumServiceProcs
14544                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14545                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14546                        + " mLastMemoryLevel" + mLastMemoryLevel
14547                        + " mLastNumProcesses" + mLastNumProcesses);
14548                long now = SystemClock.uptimeMillis();
14549                pw.print("  mLastIdleTime=");
14550                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14551                        pw.print(" mLowRamSinceLastIdle=");
14552                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14553                        pw.println();
14554            }
14555        }
14556
14557        if (!printedAnything) {
14558            pw.println("  (nothing)");
14559        }
14560    }
14561
14562    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14563            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14564        if (mProcessesToGc.size() > 0) {
14565            boolean printed = false;
14566            long now = SystemClock.uptimeMillis();
14567            for (int i=0; i<mProcessesToGc.size(); i++) {
14568                ProcessRecord proc = mProcessesToGc.get(i);
14569                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14570                    continue;
14571                }
14572                if (!printed) {
14573                    if (needSep) pw.println();
14574                    needSep = true;
14575                    pw.println("  Processes that are waiting to GC:");
14576                    printed = true;
14577                }
14578                pw.print("    Process "); pw.println(proc);
14579                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14580                        pw.print(", last gced=");
14581                        pw.print(now-proc.lastRequestedGc);
14582                        pw.print(" ms ago, last lowMem=");
14583                        pw.print(now-proc.lastLowMemory);
14584                        pw.println(" ms ago");
14585
14586            }
14587        }
14588        return needSep;
14589    }
14590
14591    void printOomLevel(PrintWriter pw, String name, int adj) {
14592        pw.print("    ");
14593        if (adj >= 0) {
14594            pw.print(' ');
14595            if (adj < 10) pw.print(' ');
14596        } else {
14597            if (adj > -10) pw.print(' ');
14598        }
14599        pw.print(adj);
14600        pw.print(": ");
14601        pw.print(name);
14602        pw.print(" (");
14603        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14604        pw.println(")");
14605    }
14606
14607    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14608            int opti, boolean dumpAll) {
14609        boolean needSep = false;
14610
14611        if (mLruProcesses.size() > 0) {
14612            if (needSep) pw.println();
14613            needSep = true;
14614            pw.println("  OOM levels:");
14615            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14616            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14617            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14618            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14619            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14620            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14621            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14622            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14623            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14624            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14625            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14626            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14627            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14628            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14629
14630            if (needSep) pw.println();
14631            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14632                    pw.print(" total, non-act at ");
14633                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14634                    pw.print(", non-svc at ");
14635                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14636                    pw.println("):");
14637            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14638            needSep = true;
14639        }
14640
14641        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14642
14643        pw.println();
14644        pw.println("  mHomeProcess: " + mHomeProcess);
14645        pw.println("  mPreviousProcess: " + mPreviousProcess);
14646        if (mHeavyWeightProcess != null) {
14647            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14648        }
14649
14650        return true;
14651    }
14652
14653    /**
14654     * There are three ways to call this:
14655     *  - no provider specified: dump all the providers
14656     *  - a flattened component name that matched an existing provider was specified as the
14657     *    first arg: dump that one provider
14658     *  - the first arg isn't the flattened component name of an existing provider:
14659     *    dump all providers whose component contains the first arg as a substring
14660     */
14661    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14662            int opti, boolean dumpAll) {
14663        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14664    }
14665
14666    static class ItemMatcher {
14667        ArrayList<ComponentName> components;
14668        ArrayList<String> strings;
14669        ArrayList<Integer> objects;
14670        boolean all;
14671
14672        ItemMatcher() {
14673            all = true;
14674        }
14675
14676        void build(String name) {
14677            ComponentName componentName = ComponentName.unflattenFromString(name);
14678            if (componentName != null) {
14679                if (components == null) {
14680                    components = new ArrayList<ComponentName>();
14681                }
14682                components.add(componentName);
14683                all = false;
14684            } else {
14685                int objectId = 0;
14686                // Not a '/' separated full component name; maybe an object ID?
14687                try {
14688                    objectId = Integer.parseInt(name, 16);
14689                    if (objects == null) {
14690                        objects = new ArrayList<Integer>();
14691                    }
14692                    objects.add(objectId);
14693                    all = false;
14694                } catch (RuntimeException e) {
14695                    // Not an integer; just do string match.
14696                    if (strings == null) {
14697                        strings = new ArrayList<String>();
14698                    }
14699                    strings.add(name);
14700                    all = false;
14701                }
14702            }
14703        }
14704
14705        int build(String[] args, int opti) {
14706            for (; opti<args.length; opti++) {
14707                String name = args[opti];
14708                if ("--".equals(name)) {
14709                    return opti+1;
14710                }
14711                build(name);
14712            }
14713            return opti;
14714        }
14715
14716        boolean match(Object object, ComponentName comp) {
14717            if (all) {
14718                return true;
14719            }
14720            if (components != null) {
14721                for (int i=0; i<components.size(); i++) {
14722                    if (components.get(i).equals(comp)) {
14723                        return true;
14724                    }
14725                }
14726            }
14727            if (objects != null) {
14728                for (int i=0; i<objects.size(); i++) {
14729                    if (System.identityHashCode(object) == objects.get(i)) {
14730                        return true;
14731                    }
14732                }
14733            }
14734            if (strings != null) {
14735                String flat = comp.flattenToString();
14736                for (int i=0; i<strings.size(); i++) {
14737                    if (flat.contains(strings.get(i))) {
14738                        return true;
14739                    }
14740                }
14741            }
14742            return false;
14743        }
14744    }
14745
14746    /**
14747     * There are three things that cmd can be:
14748     *  - a flattened component name that matches an existing activity
14749     *  - the cmd arg isn't the flattened component name of an existing activity:
14750     *    dump all activity whose component contains the cmd as a substring
14751     *  - A hex number of the ActivityRecord object instance.
14752     */
14753    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14754            int opti, boolean dumpAll) {
14755        ArrayList<ActivityRecord> activities;
14756
14757        synchronized (this) {
14758            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14759        }
14760
14761        if (activities.size() <= 0) {
14762            return false;
14763        }
14764
14765        String[] newArgs = new String[args.length - opti];
14766        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14767
14768        TaskRecord lastTask = null;
14769        boolean needSep = false;
14770        for (int i=activities.size()-1; i>=0; i--) {
14771            ActivityRecord r = activities.get(i);
14772            if (needSep) {
14773                pw.println();
14774            }
14775            needSep = true;
14776            synchronized (this) {
14777                if (lastTask != r.task) {
14778                    lastTask = r.task;
14779                    pw.print("TASK "); pw.print(lastTask.affinity);
14780                            pw.print(" id="); pw.println(lastTask.taskId);
14781                    if (dumpAll) {
14782                        lastTask.dump(pw, "  ");
14783                    }
14784                }
14785            }
14786            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14787        }
14788        return true;
14789    }
14790
14791    /**
14792     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14793     * there is a thread associated with the activity.
14794     */
14795    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14796            final ActivityRecord r, String[] args, boolean dumpAll) {
14797        String innerPrefix = prefix + "  ";
14798        synchronized (this) {
14799            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14800                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14801                    pw.print(" pid=");
14802                    if (r.app != null) pw.println(r.app.pid);
14803                    else pw.println("(not running)");
14804            if (dumpAll) {
14805                r.dump(pw, innerPrefix);
14806            }
14807        }
14808        if (r.app != null && r.app.thread != null) {
14809            // flush anything that is already in the PrintWriter since the thread is going
14810            // to write to the file descriptor directly
14811            pw.flush();
14812            try {
14813                TransferPipe tp = new TransferPipe();
14814                try {
14815                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14816                            r.appToken, innerPrefix, args);
14817                    tp.go(fd);
14818                } finally {
14819                    tp.kill();
14820                }
14821            } catch (IOException e) {
14822                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14823            } catch (RemoteException e) {
14824                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14825            }
14826        }
14827    }
14828
14829    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14830            int opti, boolean dumpAll, String dumpPackage) {
14831        boolean needSep = false;
14832        boolean onlyHistory = false;
14833        boolean printedAnything = false;
14834
14835        if ("history".equals(dumpPackage)) {
14836            if (opti < args.length && "-s".equals(args[opti])) {
14837                dumpAll = false;
14838            }
14839            onlyHistory = true;
14840            dumpPackage = null;
14841        }
14842
14843        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14844        if (!onlyHistory && dumpAll) {
14845            if (mRegisteredReceivers.size() > 0) {
14846                boolean printed = false;
14847                Iterator it = mRegisteredReceivers.values().iterator();
14848                while (it.hasNext()) {
14849                    ReceiverList r = (ReceiverList)it.next();
14850                    if (dumpPackage != null && (r.app == null ||
14851                            !dumpPackage.equals(r.app.info.packageName))) {
14852                        continue;
14853                    }
14854                    if (!printed) {
14855                        pw.println("  Registered Receivers:");
14856                        needSep = true;
14857                        printed = true;
14858                        printedAnything = true;
14859                    }
14860                    pw.print("  * "); pw.println(r);
14861                    r.dump(pw, "    ");
14862                }
14863            }
14864
14865            if (mReceiverResolver.dump(pw, needSep ?
14866                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14867                    "    ", dumpPackage, false, false)) {
14868                needSep = true;
14869                printedAnything = true;
14870            }
14871        }
14872
14873        for (BroadcastQueue q : mBroadcastQueues) {
14874            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14875            printedAnything |= needSep;
14876        }
14877
14878        needSep = true;
14879
14880        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14881            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14882                if (needSep) {
14883                    pw.println();
14884                }
14885                needSep = true;
14886                printedAnything = true;
14887                pw.print("  Sticky broadcasts for user ");
14888                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14889                StringBuilder sb = new StringBuilder(128);
14890                for (Map.Entry<String, ArrayList<Intent>> ent
14891                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14892                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14893                    if (dumpAll) {
14894                        pw.println(":");
14895                        ArrayList<Intent> intents = ent.getValue();
14896                        final int N = intents.size();
14897                        for (int i=0; i<N; i++) {
14898                            sb.setLength(0);
14899                            sb.append("    Intent: ");
14900                            intents.get(i).toShortString(sb, false, true, false, false);
14901                            pw.println(sb.toString());
14902                            Bundle bundle = intents.get(i).getExtras();
14903                            if (bundle != null) {
14904                                pw.print("      ");
14905                                pw.println(bundle.toString());
14906                            }
14907                        }
14908                    } else {
14909                        pw.println("");
14910                    }
14911                }
14912            }
14913        }
14914
14915        if (!onlyHistory && dumpAll) {
14916            pw.println();
14917            for (BroadcastQueue queue : mBroadcastQueues) {
14918                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14919                        + queue.mBroadcastsScheduled);
14920            }
14921            pw.println("  mHandler:");
14922            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14923            needSep = true;
14924            printedAnything = true;
14925        }
14926
14927        if (!printedAnything) {
14928            pw.println("  (nothing)");
14929        }
14930    }
14931
14932    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14933            int opti, boolean dumpAll, String dumpPackage) {
14934        boolean needSep;
14935        boolean printedAnything = false;
14936
14937        ItemMatcher matcher = new ItemMatcher();
14938        matcher.build(args, opti);
14939
14940        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14941
14942        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14943        printedAnything |= needSep;
14944
14945        if (mLaunchingProviders.size() > 0) {
14946            boolean printed = false;
14947            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14948                ContentProviderRecord r = mLaunchingProviders.get(i);
14949                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14950                    continue;
14951                }
14952                if (!printed) {
14953                    if (needSep) pw.println();
14954                    needSep = true;
14955                    pw.println("  Launching content providers:");
14956                    printed = true;
14957                    printedAnything = true;
14958                }
14959                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14960                        pw.println(r);
14961            }
14962        }
14963
14964        if (!printedAnything) {
14965            pw.println("  (nothing)");
14966        }
14967    }
14968
14969    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14970            int opti, boolean dumpAll, String dumpPackage) {
14971        boolean needSep = false;
14972        boolean printedAnything = false;
14973
14974        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14975
14976        if (mGrantedUriPermissions.size() > 0) {
14977            boolean printed = false;
14978            int dumpUid = -2;
14979            if (dumpPackage != null) {
14980                try {
14981                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14982                            MATCH_UNINSTALLED_PACKAGES, 0);
14983                } catch (NameNotFoundException e) {
14984                    dumpUid = -1;
14985                }
14986            }
14987            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14988                int uid = mGrantedUriPermissions.keyAt(i);
14989                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14990                    continue;
14991                }
14992                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14993                if (!printed) {
14994                    if (needSep) pw.println();
14995                    needSep = true;
14996                    pw.println("  Granted Uri Permissions:");
14997                    printed = true;
14998                    printedAnything = true;
14999                }
15000                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15001                for (UriPermission perm : perms.values()) {
15002                    pw.print("    "); pw.println(perm);
15003                    if (dumpAll) {
15004                        perm.dump(pw, "      ");
15005                    }
15006                }
15007            }
15008        }
15009
15010        if (!printedAnything) {
15011            pw.println("  (nothing)");
15012        }
15013    }
15014
15015    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15016            int opti, boolean dumpAll, String dumpPackage) {
15017        boolean printed = false;
15018
15019        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15020
15021        if (mIntentSenderRecords.size() > 0) {
15022            Iterator<WeakReference<PendingIntentRecord>> it
15023                    = mIntentSenderRecords.values().iterator();
15024            while (it.hasNext()) {
15025                WeakReference<PendingIntentRecord> ref = it.next();
15026                PendingIntentRecord rec = ref != null ? ref.get(): null;
15027                if (dumpPackage != null && (rec == null
15028                        || !dumpPackage.equals(rec.key.packageName))) {
15029                    continue;
15030                }
15031                printed = true;
15032                if (rec != null) {
15033                    pw.print("  * "); pw.println(rec);
15034                    if (dumpAll) {
15035                        rec.dump(pw, "    ");
15036                    }
15037                } else {
15038                    pw.print("  * "); pw.println(ref);
15039                }
15040            }
15041        }
15042
15043        if (!printed) {
15044            pw.println("  (nothing)");
15045        }
15046    }
15047
15048    private static final int dumpProcessList(PrintWriter pw,
15049            ActivityManagerService service, List list,
15050            String prefix, String normalLabel, String persistentLabel,
15051            String dumpPackage) {
15052        int numPers = 0;
15053        final int N = list.size()-1;
15054        for (int i=N; i>=0; i--) {
15055            ProcessRecord r = (ProcessRecord)list.get(i);
15056            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15057                continue;
15058            }
15059            pw.println(String.format("%s%s #%2d: %s",
15060                    prefix, (r.persistent ? persistentLabel : normalLabel),
15061                    i, r.toString()));
15062            if (r.persistent) {
15063                numPers++;
15064            }
15065        }
15066        return numPers;
15067    }
15068
15069    private static final boolean dumpProcessOomList(PrintWriter pw,
15070            ActivityManagerService service, List<ProcessRecord> origList,
15071            String prefix, String normalLabel, String persistentLabel,
15072            boolean inclDetails, String dumpPackage) {
15073
15074        ArrayList<Pair<ProcessRecord, Integer>> list
15075                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15076        for (int i=0; i<origList.size(); i++) {
15077            ProcessRecord r = origList.get(i);
15078            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15079                continue;
15080            }
15081            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15082        }
15083
15084        if (list.size() <= 0) {
15085            return false;
15086        }
15087
15088        Comparator<Pair<ProcessRecord, Integer>> comparator
15089                = new Comparator<Pair<ProcessRecord, Integer>>() {
15090            @Override
15091            public int compare(Pair<ProcessRecord, Integer> object1,
15092                    Pair<ProcessRecord, Integer> object2) {
15093                if (object1.first.setAdj != object2.first.setAdj) {
15094                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15095                }
15096                if (object1.first.setProcState != object2.first.setProcState) {
15097                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15098                }
15099                if (object1.second.intValue() != object2.second.intValue()) {
15100                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15101                }
15102                return 0;
15103            }
15104        };
15105
15106        Collections.sort(list, comparator);
15107
15108        final long curRealtime = SystemClock.elapsedRealtime();
15109        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15110        final long curUptime = SystemClock.uptimeMillis();
15111        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15112
15113        for (int i=list.size()-1; i>=0; i--) {
15114            ProcessRecord r = list.get(i).first;
15115            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15116            char schedGroup;
15117            switch (r.setSchedGroup) {
15118                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
15119                    schedGroup = 'B';
15120                    break;
15121                case Process.THREAD_GROUP_DEFAULT:
15122                    schedGroup = 'F';
15123                    break;
15124                default:
15125                    schedGroup = '?';
15126                    break;
15127            }
15128            char foreground;
15129            if (r.foregroundActivities) {
15130                foreground = 'A';
15131            } else if (r.foregroundServices) {
15132                foreground = 'S';
15133            } else {
15134                foreground = ' ';
15135            }
15136            String procState = ProcessList.makeProcStateString(r.curProcState);
15137            pw.print(prefix);
15138            pw.print(r.persistent ? persistentLabel : normalLabel);
15139            pw.print(" #");
15140            int num = (origList.size()-1)-list.get(i).second;
15141            if (num < 10) pw.print(' ');
15142            pw.print(num);
15143            pw.print(": ");
15144            pw.print(oomAdj);
15145            pw.print(' ');
15146            pw.print(schedGroup);
15147            pw.print('/');
15148            pw.print(foreground);
15149            pw.print('/');
15150            pw.print(procState);
15151            pw.print(" trm:");
15152            if (r.trimMemoryLevel < 10) pw.print(' ');
15153            pw.print(r.trimMemoryLevel);
15154            pw.print(' ');
15155            pw.print(r.toShortString());
15156            pw.print(" (");
15157            pw.print(r.adjType);
15158            pw.println(')');
15159            if (r.adjSource != null || r.adjTarget != null) {
15160                pw.print(prefix);
15161                pw.print("    ");
15162                if (r.adjTarget instanceof ComponentName) {
15163                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15164                } else if (r.adjTarget != null) {
15165                    pw.print(r.adjTarget.toString());
15166                } else {
15167                    pw.print("{null}");
15168                }
15169                pw.print("<=");
15170                if (r.adjSource instanceof ProcessRecord) {
15171                    pw.print("Proc{");
15172                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15173                    pw.println("}");
15174                } else if (r.adjSource != null) {
15175                    pw.println(r.adjSource.toString());
15176                } else {
15177                    pw.println("{null}");
15178                }
15179            }
15180            if (inclDetails) {
15181                pw.print(prefix);
15182                pw.print("    ");
15183                pw.print("oom: max="); pw.print(r.maxAdj);
15184                pw.print(" curRaw="); pw.print(r.curRawAdj);
15185                pw.print(" setRaw="); pw.print(r.setRawAdj);
15186                pw.print(" cur="); pw.print(r.curAdj);
15187                pw.print(" set="); pw.println(r.setAdj);
15188                pw.print(prefix);
15189                pw.print("    ");
15190                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15191                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15192                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15193                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15194                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15195                pw.println();
15196                pw.print(prefix);
15197                pw.print("    ");
15198                pw.print("cached="); pw.print(r.cached);
15199                pw.print(" empty="); pw.print(r.empty);
15200                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15201
15202                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15203                    if (r.lastWakeTime != 0) {
15204                        long wtime;
15205                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15206                        synchronized (stats) {
15207                            wtime = stats.getProcessWakeTime(r.info.uid,
15208                                    r.pid, curRealtime);
15209                        }
15210                        long timeUsed = wtime - r.lastWakeTime;
15211                        pw.print(prefix);
15212                        pw.print("    ");
15213                        pw.print("keep awake over ");
15214                        TimeUtils.formatDuration(realtimeSince, pw);
15215                        pw.print(" used ");
15216                        TimeUtils.formatDuration(timeUsed, pw);
15217                        pw.print(" (");
15218                        pw.print((timeUsed*100)/realtimeSince);
15219                        pw.println("%)");
15220                    }
15221                    if (r.lastCpuTime != 0) {
15222                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15223                        pw.print(prefix);
15224                        pw.print("    ");
15225                        pw.print("run cpu over ");
15226                        TimeUtils.formatDuration(uptimeSince, pw);
15227                        pw.print(" used ");
15228                        TimeUtils.formatDuration(timeUsed, pw);
15229                        pw.print(" (");
15230                        pw.print((timeUsed*100)/uptimeSince);
15231                        pw.println("%)");
15232                    }
15233                }
15234            }
15235        }
15236        return true;
15237    }
15238
15239    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15240            String[] args) {
15241        ArrayList<ProcessRecord> procs;
15242        synchronized (this) {
15243            if (args != null && args.length > start
15244                    && args[start].charAt(0) != '-') {
15245                procs = new ArrayList<ProcessRecord>();
15246                int pid = -1;
15247                try {
15248                    pid = Integer.parseInt(args[start]);
15249                } catch (NumberFormatException e) {
15250                }
15251                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15252                    ProcessRecord proc = mLruProcesses.get(i);
15253                    if (proc.pid == pid) {
15254                        procs.add(proc);
15255                    } else if (allPkgs && proc.pkgList != null
15256                            && proc.pkgList.containsKey(args[start])) {
15257                        procs.add(proc);
15258                    } else if (proc.processName.equals(args[start])) {
15259                        procs.add(proc);
15260                    }
15261                }
15262                if (procs.size() <= 0) {
15263                    return null;
15264                }
15265            } else {
15266                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15267            }
15268        }
15269        return procs;
15270    }
15271
15272    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15273            PrintWriter pw, String[] args) {
15274        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15275        if (procs == null) {
15276            pw.println("No process found for: " + args[0]);
15277            return;
15278        }
15279
15280        long uptime = SystemClock.uptimeMillis();
15281        long realtime = SystemClock.elapsedRealtime();
15282        pw.println("Applications Graphics Acceleration Info:");
15283        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15284
15285        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15286            ProcessRecord r = procs.get(i);
15287            if (r.thread != null) {
15288                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15289                pw.flush();
15290                try {
15291                    TransferPipe tp = new TransferPipe();
15292                    try {
15293                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15294                        tp.go(fd);
15295                    } finally {
15296                        tp.kill();
15297                    }
15298                } catch (IOException e) {
15299                    pw.println("Failure while dumping the app: " + r);
15300                    pw.flush();
15301                } catch (RemoteException e) {
15302                    pw.println("Got a RemoteException while dumping the app " + r);
15303                    pw.flush();
15304                }
15305            }
15306        }
15307    }
15308
15309    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15310        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15311        if (procs == null) {
15312            pw.println("No process found for: " + args[0]);
15313            return;
15314        }
15315
15316        pw.println("Applications Database Info:");
15317
15318        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15319            ProcessRecord r = procs.get(i);
15320            if (r.thread != null) {
15321                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15322                pw.flush();
15323                try {
15324                    TransferPipe tp = new TransferPipe();
15325                    try {
15326                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15327                        tp.go(fd);
15328                    } finally {
15329                        tp.kill();
15330                    }
15331                } catch (IOException e) {
15332                    pw.println("Failure while dumping the app: " + r);
15333                    pw.flush();
15334                } catch (RemoteException e) {
15335                    pw.println("Got a RemoteException while dumping the app " + r);
15336                    pw.flush();
15337                }
15338            }
15339        }
15340    }
15341
15342    final static class MemItem {
15343        final boolean isProc;
15344        final String label;
15345        final String shortLabel;
15346        final long pss;
15347        final long swapPss;
15348        final int id;
15349        final boolean hasActivities;
15350        ArrayList<MemItem> subitems;
15351
15352        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15353                boolean _hasActivities) {
15354            isProc = true;
15355            label = _label;
15356            shortLabel = _shortLabel;
15357            pss = _pss;
15358            swapPss = _swapPss;
15359            id = _id;
15360            hasActivities = _hasActivities;
15361        }
15362
15363        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15364            isProc = false;
15365            label = _label;
15366            shortLabel = _shortLabel;
15367            pss = _pss;
15368            swapPss = _swapPss;
15369            id = _id;
15370            hasActivities = false;
15371        }
15372    }
15373
15374    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15375            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15376        if (sort && !isCompact) {
15377            Collections.sort(items, new Comparator<MemItem>() {
15378                @Override
15379                public int compare(MemItem lhs, MemItem rhs) {
15380                    if (lhs.pss < rhs.pss) {
15381                        return 1;
15382                    } else if (lhs.pss > rhs.pss) {
15383                        return -1;
15384                    }
15385                    return 0;
15386                }
15387            });
15388        }
15389
15390        for (int i=0; i<items.size(); i++) {
15391            MemItem mi = items.get(i);
15392            if (!isCompact) {
15393                if (dumpSwapPss) {
15394                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15395                            mi.label, stringifyKBSize(mi.swapPss));
15396                } else {
15397                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15398                }
15399            } else if (mi.isProc) {
15400                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15401                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15402                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15403                pw.println(mi.hasActivities ? ",a" : ",e");
15404            } else {
15405                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15406                pw.println(mi.pss); pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15407            }
15408            if (mi.subitems != null) {
15409                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15410                        true, isCompact, dumpSwapPss);
15411            }
15412        }
15413    }
15414
15415    // These are in KB.
15416    static final long[] DUMP_MEM_BUCKETS = new long[] {
15417        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15418        120*1024, 160*1024, 200*1024,
15419        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15420        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15421    };
15422
15423    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15424            boolean stackLike) {
15425        int start = label.lastIndexOf('.');
15426        if (start >= 0) start++;
15427        else start = 0;
15428        int end = label.length();
15429        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15430            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15431                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15432                out.append(bucket);
15433                out.append(stackLike ? "MB." : "MB ");
15434                out.append(label, start, end);
15435                return;
15436            }
15437        }
15438        out.append(memKB/1024);
15439        out.append(stackLike ? "MB." : "MB ");
15440        out.append(label, start, end);
15441    }
15442
15443    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15444            ProcessList.NATIVE_ADJ,
15445            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15446            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15447            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15448            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15449            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15450            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15451    };
15452    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15453            "Native",
15454            "System", "Persistent", "Persistent Service", "Foreground",
15455            "Visible", "Perceptible",
15456            "Heavy Weight", "Backup",
15457            "A Services", "Home",
15458            "Previous", "B Services", "Cached"
15459    };
15460    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15461            "native",
15462            "sys", "pers", "persvc", "fore",
15463            "vis", "percept",
15464            "heavy", "backup",
15465            "servicea", "home",
15466            "prev", "serviceb", "cached"
15467    };
15468
15469    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15470            long realtime, boolean isCheckinRequest, boolean isCompact) {
15471        if (isCheckinRequest || isCompact) {
15472            // short checkin version
15473            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15474        } else {
15475            pw.println("Applications Memory Usage (in Kilobytes):");
15476            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15477        }
15478    }
15479
15480    private static final int KSM_SHARED = 0;
15481    private static final int KSM_SHARING = 1;
15482    private static final int KSM_UNSHARED = 2;
15483    private static final int KSM_VOLATILE = 3;
15484
15485    private final long[] getKsmInfo() {
15486        long[] longOut = new long[4];
15487        final int[] SINGLE_LONG_FORMAT = new int[] {
15488            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15489        };
15490        long[] longTmp = new long[1];
15491        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15492                SINGLE_LONG_FORMAT, null, longTmp, null);
15493        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15494        longTmp[0] = 0;
15495        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15496                SINGLE_LONG_FORMAT, null, longTmp, null);
15497        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15498        longTmp[0] = 0;
15499        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15500                SINGLE_LONG_FORMAT, null, longTmp, null);
15501        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15502        longTmp[0] = 0;
15503        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15504                SINGLE_LONG_FORMAT, null, longTmp, null);
15505        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15506        return longOut;
15507    }
15508
15509    private static String stringifySize(long size, int order) {
15510        Locale locale = Locale.US;
15511        switch (order) {
15512            case 1:
15513                return String.format(locale, "%,13d", size);
15514            case 1024:
15515                return String.format(locale, "%,9dK", size / 1024);
15516            case 1024 * 1024:
15517                return String.format(locale, "%,5dM", size / 1024 / 1024);
15518            case 1024 * 1024 * 1024:
15519                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15520            default:
15521                throw new IllegalArgumentException("Invalid size order");
15522        }
15523    }
15524
15525    private static String stringifyKBSize(long size) {
15526        return stringifySize(size * 1024, 1024);
15527    }
15528
15529    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15530            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15531        boolean dumpDetails = false;
15532        boolean dumpFullDetails = false;
15533        boolean dumpDalvik = false;
15534        boolean dumpSummaryOnly = false;
15535        boolean oomOnly = false;
15536        boolean isCompact = false;
15537        boolean localOnly = false;
15538        boolean packages = false;
15539        boolean isCheckinRequest = false;
15540        boolean dumpSwapPss = false;
15541
15542        int opti = 0;
15543        while (opti < args.length) {
15544            String opt = args[opti];
15545            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15546                break;
15547            }
15548            opti++;
15549            if ("-a".equals(opt)) {
15550                dumpDetails = true;
15551                dumpFullDetails = true;
15552                dumpDalvik = true;
15553                dumpSwapPss = true;
15554            } else if ("-d".equals(opt)) {
15555                dumpDalvik = true;
15556            } else if ("-c".equals(opt)) {
15557                isCompact = true;
15558            } else if ("-s".equals(opt)) {
15559                dumpDetails = true;
15560                dumpSummaryOnly = true;
15561            } else if ("-S".equals(opt)) {
15562                dumpSwapPss = true;
15563            } else if ("--oom".equals(opt)) {
15564                oomOnly = true;
15565            } else if ("--local".equals(opt)) {
15566                localOnly = true;
15567            } else if ("--package".equals(opt)) {
15568                packages = true;
15569            } else if ("--checkin".equals(opt)) {
15570                isCheckinRequest = true;
15571
15572            } else if ("-h".equals(opt)) {
15573                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15574                pw.println("  -a: include all available information for each process.");
15575                pw.println("  -d: include dalvik details.");
15576                pw.println("  -c: dump in a compact machine-parseable representation.");
15577                pw.println("  -s: dump only summary of application memory usage.");
15578                pw.println("  -S: dump also SwapPss.");
15579                pw.println("  --oom: only show processes organized by oom adj.");
15580                pw.println("  --local: only collect details locally, don't call process.");
15581                pw.println("  --package: interpret process arg as package, dumping all");
15582                pw.println("             processes that have loaded that package.");
15583                pw.println("  --checkin: dump data for a checkin");
15584                pw.println("If [process] is specified it can be the name or ");
15585                pw.println("pid of a specific process to dump.");
15586                return;
15587            } else {
15588                pw.println("Unknown argument: " + opt + "; use -h for help");
15589            }
15590        }
15591
15592        long uptime = SystemClock.uptimeMillis();
15593        long realtime = SystemClock.elapsedRealtime();
15594        final long[] tmpLong = new long[1];
15595
15596        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15597        if (procs == null) {
15598            // No Java processes.  Maybe they want to print a native process.
15599            if (args != null && args.length > opti
15600                    && args[opti].charAt(0) != '-') {
15601                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15602                        = new ArrayList<ProcessCpuTracker.Stats>();
15603                updateCpuStatsNow();
15604                int findPid = -1;
15605                try {
15606                    findPid = Integer.parseInt(args[opti]);
15607                } catch (NumberFormatException e) {
15608                }
15609                synchronized (mProcessCpuTracker) {
15610                    final int N = mProcessCpuTracker.countStats();
15611                    for (int i=0; i<N; i++) {
15612                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15613                        if (st.pid == findPid || (st.baseName != null
15614                                && st.baseName.equals(args[opti]))) {
15615                            nativeProcs.add(st);
15616                        }
15617                    }
15618                }
15619                if (nativeProcs.size() > 0) {
15620                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15621                            isCompact);
15622                    Debug.MemoryInfo mi = null;
15623                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15624                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15625                        final int pid = r.pid;
15626                        if (!isCheckinRequest && dumpDetails) {
15627                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15628                        }
15629                        if (mi == null) {
15630                            mi = new Debug.MemoryInfo();
15631                        }
15632                        if (dumpDetails || (!brief && !oomOnly)) {
15633                            Debug.getMemoryInfo(pid, mi);
15634                        } else {
15635                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15636                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15637                        }
15638                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15639                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15640                        if (isCheckinRequest) {
15641                            pw.println();
15642                        }
15643                    }
15644                    return;
15645                }
15646            }
15647            pw.println("No process found for: " + args[opti]);
15648            return;
15649        }
15650
15651        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15652            dumpDetails = true;
15653        }
15654
15655        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15656
15657        String[] innerArgs = new String[args.length-opti];
15658        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15659
15660        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15661        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15662        long nativePss = 0;
15663        long nativeSwapPss = 0;
15664        long dalvikPss = 0;
15665        long dalvikSwapPss = 0;
15666        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15667                EmptyArray.LONG;
15668        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15669                EmptyArray.LONG;
15670        long otherPss = 0;
15671        long otherSwapPss = 0;
15672        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15673        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15674
15675        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15676        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15677        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15678                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15679
15680        long totalPss = 0;
15681        long totalSwapPss = 0;
15682        long cachedPss = 0;
15683        long cachedSwapPss = 0;
15684        boolean hasSwapPss = false;
15685
15686        Debug.MemoryInfo mi = null;
15687        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15688            final ProcessRecord r = procs.get(i);
15689            final IApplicationThread thread;
15690            final int pid;
15691            final int oomAdj;
15692            final boolean hasActivities;
15693            synchronized (this) {
15694                thread = r.thread;
15695                pid = r.pid;
15696                oomAdj = r.getSetAdjWithServices();
15697                hasActivities = r.activities.size() > 0;
15698            }
15699            if (thread != null) {
15700                if (!isCheckinRequest && dumpDetails) {
15701                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15702                }
15703                if (mi == null) {
15704                    mi = new Debug.MemoryInfo();
15705                }
15706                if (dumpDetails || (!brief && !oomOnly)) {
15707                    Debug.getMemoryInfo(pid, mi);
15708                    hasSwapPss = mi.hasSwappedOutPss;
15709                } else {
15710                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15711                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15712                }
15713                if (dumpDetails) {
15714                    if (localOnly) {
15715                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15716                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15717                        if (isCheckinRequest) {
15718                            pw.println();
15719                        }
15720                    } else {
15721                        try {
15722                            pw.flush();
15723                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15724                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15725                        } catch (RemoteException e) {
15726                            if (!isCheckinRequest) {
15727                                pw.println("Got RemoteException!");
15728                                pw.flush();
15729                            }
15730                        }
15731                    }
15732                }
15733
15734                final long myTotalPss = mi.getTotalPss();
15735                final long myTotalUss = mi.getTotalUss();
15736                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15737
15738                synchronized (this) {
15739                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15740                        // Record this for posterity if the process has been stable.
15741                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15742                    }
15743                }
15744
15745                if (!isCheckinRequest && mi != null) {
15746                    totalPss += myTotalPss;
15747                    totalSwapPss += myTotalSwapPss;
15748                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15749                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15750                            myTotalSwapPss, pid, hasActivities);
15751                    procMems.add(pssItem);
15752                    procMemsMap.put(pid, pssItem);
15753
15754                    nativePss += mi.nativePss;
15755                    nativeSwapPss += mi.nativeSwappedOutPss;
15756                    dalvikPss += mi.dalvikPss;
15757                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15758                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15759                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15760                        dalvikSubitemSwapPss[j] +=
15761                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15762                    }
15763                    otherPss += mi.otherPss;
15764                    otherSwapPss += mi.otherSwappedOutPss;
15765                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15766                        long mem = mi.getOtherPss(j);
15767                        miscPss[j] += mem;
15768                        otherPss -= mem;
15769                        mem = mi.getOtherSwappedOutPss(j);
15770                        miscSwapPss[j] += mem;
15771                        otherSwapPss -= mem;
15772                    }
15773
15774                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15775                        cachedPss += myTotalPss;
15776                        cachedSwapPss += myTotalSwapPss;
15777                    }
15778
15779                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15780                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15781                                || oomIndex == (oomPss.length-1)) {
15782                            oomPss[oomIndex] += myTotalPss;
15783                            oomSwapPss[oomIndex] += myTotalSwapPss;
15784                            if (oomProcs[oomIndex] == null) {
15785                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15786                            }
15787                            oomProcs[oomIndex].add(pssItem);
15788                            break;
15789                        }
15790                    }
15791                }
15792            }
15793        }
15794
15795        long nativeProcTotalPss = 0;
15796
15797        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15798            // If we are showing aggregations, also look for native processes to
15799            // include so that our aggregations are more accurate.
15800            updateCpuStatsNow();
15801            mi = null;
15802            synchronized (mProcessCpuTracker) {
15803                final int N = mProcessCpuTracker.countStats();
15804                for (int i=0; i<N; i++) {
15805                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15806                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15807                        if (mi == null) {
15808                            mi = new Debug.MemoryInfo();
15809                        }
15810                        if (!brief && !oomOnly) {
15811                            Debug.getMemoryInfo(st.pid, mi);
15812                        } else {
15813                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15814                            mi.nativePrivateDirty = (int)tmpLong[0];
15815                        }
15816
15817                        final long myTotalPss = mi.getTotalPss();
15818                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15819                        totalPss += myTotalPss;
15820                        nativeProcTotalPss += myTotalPss;
15821
15822                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15823                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15824                        procMems.add(pssItem);
15825
15826                        nativePss += mi.nativePss;
15827                        nativeSwapPss += mi.nativeSwappedOutPss;
15828                        dalvikPss += mi.dalvikPss;
15829                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15830                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15831                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15832                            dalvikSubitemSwapPss[j] +=
15833                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15834                        }
15835                        otherPss += mi.otherPss;
15836                        otherSwapPss += mi.otherSwappedOutPss;
15837                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15838                            long mem = mi.getOtherPss(j);
15839                            miscPss[j] += mem;
15840                            otherPss -= mem;
15841                            mem = mi.getOtherSwappedOutPss(j);
15842                            miscSwapPss[j] += mem;
15843                            otherSwapPss -= mem;
15844                        }
15845                        oomPss[0] += myTotalPss;
15846                        oomSwapPss[0] += myTotalSwapPss;
15847                        if (oomProcs[0] == null) {
15848                            oomProcs[0] = new ArrayList<MemItem>();
15849                        }
15850                        oomProcs[0].add(pssItem);
15851                    }
15852                }
15853            }
15854
15855            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15856
15857            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15858            final MemItem dalvikItem =
15859                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15860            if (dalvikSubitemPss.length > 0) {
15861                dalvikItem.subitems = new ArrayList<MemItem>();
15862                for (int j=0; j<dalvikSubitemPss.length; j++) {
15863                    final String name = Debug.MemoryInfo.getOtherLabel(
15864                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15865                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15866                                    dalvikSubitemSwapPss[j], j));
15867                }
15868            }
15869            catMems.add(dalvikItem);
15870            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15871            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15872                String label = Debug.MemoryInfo.getOtherLabel(j);
15873                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15874            }
15875
15876            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15877            for (int j=0; j<oomPss.length; j++) {
15878                if (oomPss[j] != 0) {
15879                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15880                            : DUMP_MEM_OOM_LABEL[j];
15881                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15882                            DUMP_MEM_OOM_ADJ[j]);
15883                    item.subitems = oomProcs[j];
15884                    oomMems.add(item);
15885                }
15886            }
15887
15888            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15889            if (!brief && !oomOnly && !isCompact) {
15890                pw.println();
15891                pw.println("Total PSS by process:");
15892                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15893                pw.println();
15894            }
15895            if (!isCompact) {
15896                pw.println("Total PSS by OOM adjustment:");
15897            }
15898            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15899            if (!brief && !oomOnly) {
15900                PrintWriter out = categoryPw != null ? categoryPw : pw;
15901                if (!isCompact) {
15902                    out.println();
15903                    out.println("Total PSS by category:");
15904                }
15905                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15906            }
15907            if (!isCompact) {
15908                pw.println();
15909            }
15910            MemInfoReader memInfo = new MemInfoReader();
15911            memInfo.readMemInfo();
15912            if (nativeProcTotalPss > 0) {
15913                synchronized (this) {
15914                    final long cachedKb = memInfo.getCachedSizeKb();
15915                    final long freeKb = memInfo.getFreeSizeKb();
15916                    final long zramKb = memInfo.getZramTotalSizeKb();
15917                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15918                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15919                            kernelKb*1024, nativeProcTotalPss*1024);
15920                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15921                            nativeProcTotalPss);
15922                }
15923            }
15924            if (!brief) {
15925                if (!isCompact) {
15926                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15927                    pw.print(" (status ");
15928                    switch (mLastMemoryLevel) {
15929                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15930                            pw.println("normal)");
15931                            break;
15932                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15933                            pw.println("moderate)");
15934                            break;
15935                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15936                            pw.println("low)");
15937                            break;
15938                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15939                            pw.println("critical)");
15940                            break;
15941                        default:
15942                            pw.print(mLastMemoryLevel);
15943                            pw.println(")");
15944                            break;
15945                    }
15946                    pw.print(" Free RAM: ");
15947                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15948                            + memInfo.getFreeSizeKb()));
15949                    pw.print(" (");
15950                    pw.print(stringifyKBSize(cachedPss));
15951                    pw.print(" cached pss + ");
15952                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15953                    pw.print(" cached kernel + ");
15954                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15955                    pw.println(" free)");
15956                } else {
15957                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15958                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15959                            + memInfo.getFreeSizeKb()); pw.print(",");
15960                    pw.println(totalPss - cachedPss);
15961                }
15962            }
15963            long lostRAM = memInfo.getTotalSizeKb()
15964                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15965                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15966            if (!isCompact) {
15967                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15968                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15969                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15970                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15971                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15972            } else {
15973                pw.print("lostram,"); pw.println(lostRAM);
15974            }
15975            if (!brief) {
15976                if (memInfo.getZramTotalSizeKb() != 0) {
15977                    if (!isCompact) {
15978                        pw.print("     ZRAM: ");
15979                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15980                                pw.print(" physical used for ");
15981                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15982                                        - memInfo.getSwapFreeSizeKb()));
15983                                pw.print(" in swap (");
15984                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15985                                pw.println(" total swap)");
15986                    } else {
15987                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15988                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15989                                pw.println(memInfo.getSwapFreeSizeKb());
15990                    }
15991                }
15992                final long[] ksm = getKsmInfo();
15993                if (!isCompact) {
15994                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15995                            || ksm[KSM_VOLATILE] != 0) {
15996                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15997                                pw.print(" saved from shared ");
15998                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15999                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16000                                pw.print(" unshared; ");
16001                                pw.print(stringifyKBSize(
16002                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16003                    }
16004                    pw.print("   Tuning: ");
16005                    pw.print(ActivityManager.staticGetMemoryClass());
16006                    pw.print(" (large ");
16007                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16008                    pw.print("), oom ");
16009                    pw.print(stringifySize(
16010                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16011                    pw.print(", restore limit ");
16012                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16013                    if (ActivityManager.isLowRamDeviceStatic()) {
16014                        pw.print(" (low-ram)");
16015                    }
16016                    if (ActivityManager.isHighEndGfx()) {
16017                        pw.print(" (high-end-gfx)");
16018                    }
16019                    pw.println();
16020                } else {
16021                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16022                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16023                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16024                    pw.print("tuning,");
16025                    pw.print(ActivityManager.staticGetMemoryClass());
16026                    pw.print(',');
16027                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16028                    pw.print(',');
16029                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16030                    if (ActivityManager.isLowRamDeviceStatic()) {
16031                        pw.print(",low-ram");
16032                    }
16033                    if (ActivityManager.isHighEndGfx()) {
16034                        pw.print(",high-end-gfx");
16035                    }
16036                    pw.println();
16037                }
16038            }
16039        }
16040    }
16041
16042    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16043            long memtrack, String name) {
16044        sb.append("  ");
16045        sb.append(ProcessList.makeOomAdjString(oomAdj));
16046        sb.append(' ');
16047        sb.append(ProcessList.makeProcStateString(procState));
16048        sb.append(' ');
16049        ProcessList.appendRamKb(sb, pss);
16050        sb.append(": ");
16051        sb.append(name);
16052        if (memtrack > 0) {
16053            sb.append(" (");
16054            sb.append(stringifyKBSize(memtrack));
16055            sb.append(" memtrack)");
16056        }
16057    }
16058
16059    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16060        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16061        sb.append(" (pid ");
16062        sb.append(mi.pid);
16063        sb.append(") ");
16064        sb.append(mi.adjType);
16065        sb.append('\n');
16066        if (mi.adjReason != null) {
16067            sb.append("                      ");
16068            sb.append(mi.adjReason);
16069            sb.append('\n');
16070        }
16071    }
16072
16073    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16074        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16075        for (int i=0, N=memInfos.size(); i<N; i++) {
16076            ProcessMemInfo mi = memInfos.get(i);
16077            infoMap.put(mi.pid, mi);
16078        }
16079        updateCpuStatsNow();
16080        long[] memtrackTmp = new long[1];
16081        synchronized (mProcessCpuTracker) {
16082            final int N = mProcessCpuTracker.countStats();
16083            for (int i=0; i<N; i++) {
16084                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16085                if (st.vsize > 0) {
16086                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16087                    if (pss > 0) {
16088                        if (infoMap.indexOfKey(st.pid) < 0) {
16089                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16090                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16091                            mi.pss = pss;
16092                            mi.memtrack = memtrackTmp[0];
16093                            memInfos.add(mi);
16094                        }
16095                    }
16096                }
16097            }
16098        }
16099
16100        long totalPss = 0;
16101        long totalMemtrack = 0;
16102        for (int i=0, N=memInfos.size(); i<N; i++) {
16103            ProcessMemInfo mi = memInfos.get(i);
16104            if (mi.pss == 0) {
16105                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16106                mi.memtrack = memtrackTmp[0];
16107            }
16108            totalPss += mi.pss;
16109            totalMemtrack += mi.memtrack;
16110        }
16111        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16112            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16113                if (lhs.oomAdj != rhs.oomAdj) {
16114                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16115                }
16116                if (lhs.pss != rhs.pss) {
16117                    return lhs.pss < rhs.pss ? 1 : -1;
16118                }
16119                return 0;
16120            }
16121        });
16122
16123        StringBuilder tag = new StringBuilder(128);
16124        StringBuilder stack = new StringBuilder(128);
16125        tag.append("Low on memory -- ");
16126        appendMemBucket(tag, totalPss, "total", false);
16127        appendMemBucket(stack, totalPss, "total", true);
16128
16129        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16130        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16131        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16132
16133        boolean firstLine = true;
16134        int lastOomAdj = Integer.MIN_VALUE;
16135        long extraNativeRam = 0;
16136        long extraNativeMemtrack = 0;
16137        long cachedPss = 0;
16138        for (int i=0, N=memInfos.size(); i<N; i++) {
16139            ProcessMemInfo mi = memInfos.get(i);
16140
16141            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16142                cachedPss += mi.pss;
16143            }
16144
16145            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16146                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16147                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16148                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16149                if (lastOomAdj != mi.oomAdj) {
16150                    lastOomAdj = mi.oomAdj;
16151                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16152                        tag.append(" / ");
16153                    }
16154                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16155                        if (firstLine) {
16156                            stack.append(":");
16157                            firstLine = false;
16158                        }
16159                        stack.append("\n\t at ");
16160                    } else {
16161                        stack.append("$");
16162                    }
16163                } else {
16164                    tag.append(" ");
16165                    stack.append("$");
16166                }
16167                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16168                    appendMemBucket(tag, mi.pss, mi.name, false);
16169                }
16170                appendMemBucket(stack, mi.pss, mi.name, true);
16171                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16172                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16173                    stack.append("(");
16174                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16175                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16176                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16177                            stack.append(":");
16178                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16179                        }
16180                    }
16181                    stack.append(")");
16182                }
16183            }
16184
16185            appendMemInfo(fullNativeBuilder, mi);
16186            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16187                // The short form only has native processes that are >= 512K.
16188                if (mi.pss >= 512) {
16189                    appendMemInfo(shortNativeBuilder, mi);
16190                } else {
16191                    extraNativeRam += mi.pss;
16192                    extraNativeMemtrack += mi.memtrack;
16193                }
16194            } else {
16195                // Short form has all other details, but if we have collected RAM
16196                // from smaller native processes let's dump a summary of that.
16197                if (extraNativeRam > 0) {
16198                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16199                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16200                    shortNativeBuilder.append('\n');
16201                    extraNativeRam = 0;
16202                }
16203                appendMemInfo(fullJavaBuilder, mi);
16204            }
16205        }
16206
16207        fullJavaBuilder.append("           ");
16208        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16209        fullJavaBuilder.append(": TOTAL");
16210        if (totalMemtrack > 0) {
16211            fullJavaBuilder.append(" (");
16212            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16213            fullJavaBuilder.append(" memtrack)");
16214        } else {
16215        }
16216        fullJavaBuilder.append("\n");
16217
16218        MemInfoReader memInfo = new MemInfoReader();
16219        memInfo.readMemInfo();
16220        final long[] infos = memInfo.getRawInfo();
16221
16222        StringBuilder memInfoBuilder = new StringBuilder(1024);
16223        Debug.getMemInfo(infos);
16224        memInfoBuilder.append("  MemInfo: ");
16225        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16226        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16227        memInfoBuilder.append(stringifyKBSize(
16228                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16229        memInfoBuilder.append(stringifyKBSize(
16230                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16231        memInfoBuilder.append(stringifyKBSize(
16232                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16233        memInfoBuilder.append("           ");
16234        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16235        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16236        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16237        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16238        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16239            memInfoBuilder.append("  ZRAM: ");
16240            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16241            memInfoBuilder.append(" RAM, ");
16242            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16243            memInfoBuilder.append(" swap total, ");
16244            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16245            memInfoBuilder.append(" swap free\n");
16246        }
16247        final long[] ksm = getKsmInfo();
16248        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16249                || ksm[KSM_VOLATILE] != 0) {
16250            memInfoBuilder.append("  KSM: ");
16251            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16252            memInfoBuilder.append(" saved from shared ");
16253            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16254            memInfoBuilder.append("\n       ");
16255            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16256            memInfoBuilder.append(" unshared; ");
16257            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16258            memInfoBuilder.append(" volatile\n");
16259        }
16260        memInfoBuilder.append("  Free RAM: ");
16261        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16262                + memInfo.getFreeSizeKb()));
16263        memInfoBuilder.append("\n");
16264        memInfoBuilder.append("  Used RAM: ");
16265        memInfoBuilder.append(stringifyKBSize(
16266                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16267        memInfoBuilder.append("\n");
16268        memInfoBuilder.append("  Lost RAM: ");
16269        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16270                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16271                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16272        memInfoBuilder.append("\n");
16273        Slog.i(TAG, "Low on memory:");
16274        Slog.i(TAG, shortNativeBuilder.toString());
16275        Slog.i(TAG, fullJavaBuilder.toString());
16276        Slog.i(TAG, memInfoBuilder.toString());
16277
16278        StringBuilder dropBuilder = new StringBuilder(1024);
16279        /*
16280        StringWriter oomSw = new StringWriter();
16281        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16282        StringWriter catSw = new StringWriter();
16283        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16284        String[] emptyArgs = new String[] { };
16285        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16286        oomPw.flush();
16287        String oomString = oomSw.toString();
16288        */
16289        dropBuilder.append("Low on memory:");
16290        dropBuilder.append(stack);
16291        dropBuilder.append('\n');
16292        dropBuilder.append(fullNativeBuilder);
16293        dropBuilder.append(fullJavaBuilder);
16294        dropBuilder.append('\n');
16295        dropBuilder.append(memInfoBuilder);
16296        dropBuilder.append('\n');
16297        /*
16298        dropBuilder.append(oomString);
16299        dropBuilder.append('\n');
16300        */
16301        StringWriter catSw = new StringWriter();
16302        synchronized (ActivityManagerService.this) {
16303            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16304            String[] emptyArgs = new String[] { };
16305            catPw.println();
16306            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16307            catPw.println();
16308            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16309                    false, false, null);
16310            catPw.println();
16311            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16312            catPw.flush();
16313        }
16314        dropBuilder.append(catSw.toString());
16315        addErrorToDropBox("lowmem", null, "system_server", null,
16316                null, tag.toString(), dropBuilder.toString(), null, null);
16317        //Slog.i(TAG, "Sent to dropbox:");
16318        //Slog.i(TAG, dropBuilder.toString());
16319        synchronized (ActivityManagerService.this) {
16320            long now = SystemClock.uptimeMillis();
16321            if (mLastMemUsageReportTime < now) {
16322                mLastMemUsageReportTime = now;
16323            }
16324        }
16325    }
16326
16327    /**
16328     * Searches array of arguments for the specified string
16329     * @param args array of argument strings
16330     * @param value value to search for
16331     * @return true if the value is contained in the array
16332     */
16333    private static boolean scanArgs(String[] args, String value) {
16334        if (args != null) {
16335            for (String arg : args) {
16336                if (value.equals(arg)) {
16337                    return true;
16338                }
16339            }
16340        }
16341        return false;
16342    }
16343
16344    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16345            ContentProviderRecord cpr, boolean always) {
16346        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16347
16348        if (!inLaunching || always) {
16349            synchronized (cpr) {
16350                cpr.launchingApp = null;
16351                cpr.notifyAll();
16352            }
16353            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16354            String names[] = cpr.info.authority.split(";");
16355            for (int j = 0; j < names.length; j++) {
16356                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16357            }
16358        }
16359
16360        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16361            ContentProviderConnection conn = cpr.connections.get(i);
16362            if (conn.waiting) {
16363                // If this connection is waiting for the provider, then we don't
16364                // need to mess with its process unless we are always removing
16365                // or for some reason the provider is not currently launching.
16366                if (inLaunching && !always) {
16367                    continue;
16368                }
16369            }
16370            ProcessRecord capp = conn.client;
16371            conn.dead = true;
16372            if (conn.stableCount > 0) {
16373                if (!capp.persistent && capp.thread != null
16374                        && capp.pid != 0
16375                        && capp.pid != MY_PID) {
16376                    capp.kill("depends on provider "
16377                            + cpr.name.flattenToShortString()
16378                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16379                }
16380            } else if (capp.thread != null && conn.provider.provider != null) {
16381                try {
16382                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16383                } catch (RemoteException e) {
16384                }
16385                // In the protocol here, we don't expect the client to correctly
16386                // clean up this connection, we'll just remove it.
16387                cpr.connections.remove(i);
16388                if (conn.client.conProviders.remove(conn)) {
16389                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16390                }
16391            }
16392        }
16393
16394        if (inLaunching && always) {
16395            mLaunchingProviders.remove(cpr);
16396        }
16397        return inLaunching;
16398    }
16399
16400    /**
16401     * Main code for cleaning up a process when it has gone away.  This is
16402     * called both as a result of the process dying, or directly when stopping
16403     * a process when running in single process mode.
16404     *
16405     * @return Returns true if the given process has been restarted, so the
16406     * app that was passed in must remain on the process lists.
16407     */
16408    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16409            boolean restarting, boolean allowRestart, int index) {
16410        if (index >= 0) {
16411            removeLruProcessLocked(app);
16412            ProcessList.remove(app.pid);
16413        }
16414
16415        mProcessesToGc.remove(app);
16416        mPendingPssProcesses.remove(app);
16417
16418        // Dismiss any open dialogs.
16419        if (app.crashDialog != null && !app.forceCrashReport) {
16420            app.crashDialog.dismiss();
16421            app.crashDialog = null;
16422        }
16423        if (app.anrDialog != null) {
16424            app.anrDialog.dismiss();
16425            app.anrDialog = null;
16426        }
16427        if (app.waitDialog != null) {
16428            app.waitDialog.dismiss();
16429            app.waitDialog = null;
16430        }
16431
16432        app.crashing = false;
16433        app.notResponding = false;
16434
16435        app.resetPackageList(mProcessStats);
16436        app.unlinkDeathRecipient();
16437        app.makeInactive(mProcessStats);
16438        app.waitingToKill = null;
16439        app.forcingToForeground = null;
16440        updateProcessForegroundLocked(app, false, false);
16441        app.foregroundActivities = false;
16442        app.hasShownUi = false;
16443        app.treatLikeActivity = false;
16444        app.hasAboveClient = false;
16445        app.hasClientActivities = false;
16446
16447        mServices.killServicesLocked(app, allowRestart);
16448
16449        boolean restart = false;
16450
16451        // Remove published content providers.
16452        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16453            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16454            final boolean always = app.bad || !allowRestart;
16455            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16456            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16457                // We left the provider in the launching list, need to
16458                // restart it.
16459                restart = true;
16460            }
16461
16462            cpr.provider = null;
16463            cpr.proc = null;
16464        }
16465        app.pubProviders.clear();
16466
16467        // Take care of any launching providers waiting for this process.
16468        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16469            restart = true;
16470        }
16471
16472        // Unregister from connected content providers.
16473        if (!app.conProviders.isEmpty()) {
16474            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16475                ContentProviderConnection conn = app.conProviders.get(i);
16476                conn.provider.connections.remove(conn);
16477                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16478                        conn.provider.name);
16479            }
16480            app.conProviders.clear();
16481        }
16482
16483        // At this point there may be remaining entries in mLaunchingProviders
16484        // where we were the only one waiting, so they are no longer of use.
16485        // Look for these and clean up if found.
16486        // XXX Commented out for now.  Trying to figure out a way to reproduce
16487        // the actual situation to identify what is actually going on.
16488        if (false) {
16489            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16490                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16491                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16492                    synchronized (cpr) {
16493                        cpr.launchingApp = null;
16494                        cpr.notifyAll();
16495                    }
16496                }
16497            }
16498        }
16499
16500        skipCurrentReceiverLocked(app);
16501
16502        // Unregister any receivers.
16503        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16504            removeReceiverLocked(app.receivers.valueAt(i));
16505        }
16506        app.receivers.clear();
16507
16508        // If the app is undergoing backup, tell the backup manager about it
16509        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16510            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16511                    + mBackupTarget.appInfo + " died during backup");
16512            try {
16513                IBackupManager bm = IBackupManager.Stub.asInterface(
16514                        ServiceManager.getService(Context.BACKUP_SERVICE));
16515                bm.agentDisconnected(app.info.packageName);
16516            } catch (RemoteException e) {
16517                // can't happen; backup manager is local
16518            }
16519        }
16520
16521        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16522            ProcessChangeItem item = mPendingProcessChanges.get(i);
16523            if (item.pid == app.pid) {
16524                mPendingProcessChanges.remove(i);
16525                mAvailProcessChanges.add(item);
16526            }
16527        }
16528        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16529                null).sendToTarget();
16530
16531        // If the caller is restarting this app, then leave it in its
16532        // current lists and let the caller take care of it.
16533        if (restarting) {
16534            return false;
16535        }
16536
16537        if (!app.persistent || app.isolated) {
16538            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16539                    "Removing non-persistent process during cleanup: " + app);
16540            removeProcessNameLocked(app.processName, app.uid);
16541            if (mHeavyWeightProcess == app) {
16542                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16543                        mHeavyWeightProcess.userId, 0));
16544                mHeavyWeightProcess = null;
16545            }
16546        } else if (!app.removed) {
16547            // This app is persistent, so we need to keep its record around.
16548            // If it is not already on the pending app list, add it there
16549            // and start a new process for it.
16550            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16551                mPersistentStartingProcesses.add(app);
16552                restart = true;
16553            }
16554        }
16555        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16556                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16557        mProcessesOnHold.remove(app);
16558
16559        if (app == mHomeProcess) {
16560            mHomeProcess = null;
16561        }
16562        if (app == mPreviousProcess) {
16563            mPreviousProcess = null;
16564        }
16565
16566        if (restart && !app.isolated) {
16567            // We have components that still need to be running in the
16568            // process, so re-launch it.
16569            if (index < 0) {
16570                ProcessList.remove(app.pid);
16571            }
16572            addProcessNameLocked(app);
16573            startProcessLocked(app, "restart", app.processName);
16574            return true;
16575        } else if (app.pid > 0 && app.pid != MY_PID) {
16576            // Goodbye!
16577            boolean removed;
16578            synchronized (mPidsSelfLocked) {
16579                mPidsSelfLocked.remove(app.pid);
16580                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16581            }
16582            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16583            if (app.isolated) {
16584                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16585            }
16586            app.setPid(0);
16587        }
16588        return false;
16589    }
16590
16591    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16592        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16593            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16594            if (cpr.launchingApp == app) {
16595                return true;
16596            }
16597        }
16598        return false;
16599    }
16600
16601    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16602        // Look through the content providers we are waiting to have launched,
16603        // and if any run in this process then either schedule a restart of
16604        // the process or kill the client waiting for it if this process has
16605        // gone bad.
16606        boolean restart = false;
16607        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16608            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16609            if (cpr.launchingApp == app) {
16610                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16611                    restart = true;
16612                } else {
16613                    removeDyingProviderLocked(app, cpr, true);
16614                }
16615            }
16616        }
16617        return restart;
16618    }
16619
16620    // =========================================================
16621    // SERVICES
16622    // =========================================================
16623
16624    @Override
16625    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16626            int flags) {
16627        enforceNotIsolatedCaller("getServices");
16628        synchronized (this) {
16629            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16630        }
16631    }
16632
16633    @Override
16634    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16635        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16636        synchronized (this) {
16637            return mServices.getRunningServiceControlPanelLocked(name);
16638        }
16639    }
16640
16641    @Override
16642    public ComponentName startService(IApplicationThread caller, Intent service,
16643            String resolvedType, String callingPackage, int userId)
16644            throws TransactionTooLargeException {
16645        enforceNotIsolatedCaller("startService");
16646        // Refuse possible leaked file descriptors
16647        if (service != null && service.hasFileDescriptors() == true) {
16648            throw new IllegalArgumentException("File descriptors passed in Intent");
16649        }
16650
16651        if (callingPackage == null) {
16652            throw new IllegalArgumentException("callingPackage cannot be null");
16653        }
16654
16655        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16656                "startService: " + service + " type=" + resolvedType);
16657        synchronized(this) {
16658            final int callingPid = Binder.getCallingPid();
16659            final int callingUid = Binder.getCallingUid();
16660            final long origId = Binder.clearCallingIdentity();
16661            ComponentName res = mServices.startServiceLocked(caller, service,
16662                    resolvedType, callingPid, callingUid, callingPackage, userId);
16663            Binder.restoreCallingIdentity(origId);
16664            return res;
16665        }
16666    }
16667
16668    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16669            String callingPackage, int userId)
16670            throws TransactionTooLargeException {
16671        synchronized(this) {
16672            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16673                    "startServiceInPackage: " + service + " type=" + resolvedType);
16674            final long origId = Binder.clearCallingIdentity();
16675            ComponentName res = mServices.startServiceLocked(null, service,
16676                    resolvedType, -1, uid, callingPackage, userId);
16677            Binder.restoreCallingIdentity(origId);
16678            return res;
16679        }
16680    }
16681
16682    @Override
16683    public int stopService(IApplicationThread caller, Intent service,
16684            String resolvedType, int userId) {
16685        enforceNotIsolatedCaller("stopService");
16686        // Refuse possible leaked file descriptors
16687        if (service != null && service.hasFileDescriptors() == true) {
16688            throw new IllegalArgumentException("File descriptors passed in Intent");
16689        }
16690
16691        synchronized(this) {
16692            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16693        }
16694    }
16695
16696    @Override
16697    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16698        enforceNotIsolatedCaller("peekService");
16699        // Refuse possible leaked file descriptors
16700        if (service != null && service.hasFileDescriptors() == true) {
16701            throw new IllegalArgumentException("File descriptors passed in Intent");
16702        }
16703
16704        if (callingPackage == null) {
16705            throw new IllegalArgumentException("callingPackage cannot be null");
16706        }
16707
16708        synchronized(this) {
16709            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16710        }
16711    }
16712
16713    @Override
16714    public boolean stopServiceToken(ComponentName className, IBinder token,
16715            int startId) {
16716        synchronized(this) {
16717            return mServices.stopServiceTokenLocked(className, token, startId);
16718        }
16719    }
16720
16721    @Override
16722    public void setServiceForeground(ComponentName className, IBinder token,
16723            int id, Notification notification, boolean removeNotification) {
16724        synchronized(this) {
16725            mServices.setServiceForegroundLocked(className, token, id, notification,
16726                    removeNotification);
16727        }
16728    }
16729
16730    @Override
16731    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16732            boolean requireFull, String name, String callerPackage) {
16733        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16734                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16735    }
16736
16737    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16738            String className, int flags) {
16739        boolean result = false;
16740        // For apps that don't have pre-defined UIDs, check for permission
16741        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16742            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16743                if (ActivityManager.checkUidPermission(
16744                        INTERACT_ACROSS_USERS,
16745                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16746                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16747                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16748                            + " requests FLAG_SINGLE_USER, but app does not hold "
16749                            + INTERACT_ACROSS_USERS;
16750                    Slog.w(TAG, msg);
16751                    throw new SecurityException(msg);
16752                }
16753                // Permission passed
16754                result = true;
16755            }
16756        } else if ("system".equals(componentProcessName)) {
16757            result = true;
16758        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16759            // Phone app and persistent apps are allowed to export singleuser providers.
16760            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16761                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16762        }
16763        if (DEBUG_MU) Slog.v(TAG_MU,
16764                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16765                + Integer.toHexString(flags) + ") = " + result);
16766        return result;
16767    }
16768
16769    /**
16770     * Checks to see if the caller is in the same app as the singleton
16771     * component, or the component is in a special app. It allows special apps
16772     * to export singleton components but prevents exporting singleton
16773     * components for regular apps.
16774     */
16775    boolean isValidSingletonCall(int callingUid, int componentUid) {
16776        int componentAppId = UserHandle.getAppId(componentUid);
16777        return UserHandle.isSameApp(callingUid, componentUid)
16778                || componentAppId == Process.SYSTEM_UID
16779                || componentAppId == Process.PHONE_UID
16780                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16781                        == PackageManager.PERMISSION_GRANTED;
16782    }
16783
16784    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16785            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16786            int userId) throws TransactionTooLargeException {
16787        enforceNotIsolatedCaller("bindService");
16788
16789        // Refuse possible leaked file descriptors
16790        if (service != null && service.hasFileDescriptors() == true) {
16791            throw new IllegalArgumentException("File descriptors passed in Intent");
16792        }
16793
16794        if (callingPackage == null) {
16795            throw new IllegalArgumentException("callingPackage cannot be null");
16796        }
16797
16798        synchronized(this) {
16799            return mServices.bindServiceLocked(caller, token, service,
16800                    resolvedType, connection, flags, callingPackage, userId);
16801        }
16802    }
16803
16804    public boolean unbindService(IServiceConnection connection) {
16805        synchronized (this) {
16806            return mServices.unbindServiceLocked(connection);
16807        }
16808    }
16809
16810    public void publishService(IBinder token, Intent intent, IBinder service) {
16811        // Refuse possible leaked file descriptors
16812        if (intent != null && intent.hasFileDescriptors() == true) {
16813            throw new IllegalArgumentException("File descriptors passed in Intent");
16814        }
16815
16816        synchronized(this) {
16817            if (!(token instanceof ServiceRecord)) {
16818                throw new IllegalArgumentException("Invalid service token");
16819            }
16820            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16821        }
16822    }
16823
16824    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16825        // Refuse possible leaked file descriptors
16826        if (intent != null && intent.hasFileDescriptors() == true) {
16827            throw new IllegalArgumentException("File descriptors passed in Intent");
16828        }
16829
16830        synchronized(this) {
16831            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16832        }
16833    }
16834
16835    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16836        synchronized(this) {
16837            if (!(token instanceof ServiceRecord)) {
16838                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16839                throw new IllegalArgumentException("Invalid service token");
16840            }
16841            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16842        }
16843    }
16844
16845    // =========================================================
16846    // BACKUP AND RESTORE
16847    // =========================================================
16848
16849    // Cause the target app to be launched if necessary and its backup agent
16850    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16851    // activity manager to announce its creation.
16852    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16853        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16854                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16855        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16856
16857        synchronized(this) {
16858            // !!! TODO: currently no check here that we're already bound
16859            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16860            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16861            synchronized (stats) {
16862                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16863            }
16864
16865            // Backup agent is now in use, its package can't be stopped.
16866            try {
16867                AppGlobals.getPackageManager().setPackageStoppedState(
16868                        app.packageName, false, UserHandle.getUserId(app.uid));
16869            } catch (RemoteException e) {
16870            } catch (IllegalArgumentException e) {
16871                Slog.w(TAG, "Failed trying to unstop package "
16872                        + app.packageName + ": " + e);
16873            }
16874
16875            BackupRecord r = new BackupRecord(ss, app, backupMode);
16876            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16877                    ? new ComponentName(app.packageName, app.backupAgentName)
16878                    : new ComponentName("android", "FullBackupAgent");
16879            // startProcessLocked() returns existing proc's record if it's already running
16880            ProcessRecord proc = startProcessLocked(app.processName, app,
16881                    false, 0, "backup", hostingName, false, false, false);
16882            if (proc == null) {
16883                Slog.e(TAG, "Unable to start backup agent process " + r);
16884                return false;
16885            }
16886
16887            r.app = proc;
16888            mBackupTarget = r;
16889            mBackupAppName = app.packageName;
16890
16891            // Try not to kill the process during backup
16892            updateOomAdjLocked(proc);
16893
16894            // If the process is already attached, schedule the creation of the backup agent now.
16895            // If it is not yet live, this will be done when it attaches to the framework.
16896            if (proc.thread != null) {
16897                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16898                try {
16899                    proc.thread.scheduleCreateBackupAgent(app,
16900                            compatibilityInfoForPackageLocked(app), backupMode);
16901                } catch (RemoteException e) {
16902                    // Will time out on the backup manager side
16903                }
16904            } else {
16905                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16906            }
16907            // Invariants: at this point, the target app process exists and the application
16908            // is either already running or in the process of coming up.  mBackupTarget and
16909            // mBackupAppName describe the app, so that when it binds back to the AM we
16910            // know that it's scheduled for a backup-agent operation.
16911        }
16912
16913        return true;
16914    }
16915
16916    @Override
16917    public void clearPendingBackup() {
16918        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16919        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16920
16921        synchronized (this) {
16922            mBackupTarget = null;
16923            mBackupAppName = null;
16924        }
16925    }
16926
16927    // A backup agent has just come up
16928    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16929        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16930                + " = " + agent);
16931
16932        synchronized(this) {
16933            if (!agentPackageName.equals(mBackupAppName)) {
16934                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16935                return;
16936            }
16937        }
16938
16939        long oldIdent = Binder.clearCallingIdentity();
16940        try {
16941            IBackupManager bm = IBackupManager.Stub.asInterface(
16942                    ServiceManager.getService(Context.BACKUP_SERVICE));
16943            bm.agentConnected(agentPackageName, agent);
16944        } catch (RemoteException e) {
16945            // can't happen; the backup manager service is local
16946        } catch (Exception e) {
16947            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16948            e.printStackTrace();
16949        } finally {
16950            Binder.restoreCallingIdentity(oldIdent);
16951        }
16952    }
16953
16954    // done with this agent
16955    public void unbindBackupAgent(ApplicationInfo appInfo) {
16956        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16957        if (appInfo == null) {
16958            Slog.w(TAG, "unbind backup agent for null app");
16959            return;
16960        }
16961
16962        synchronized(this) {
16963            try {
16964                if (mBackupAppName == null) {
16965                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16966                    return;
16967                }
16968
16969                if (!mBackupAppName.equals(appInfo.packageName)) {
16970                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16971                    return;
16972                }
16973
16974                // Not backing this app up any more; reset its OOM adjustment
16975                final ProcessRecord proc = mBackupTarget.app;
16976                updateOomAdjLocked(proc);
16977
16978                // If the app crashed during backup, 'thread' will be null here
16979                if (proc.thread != null) {
16980                    try {
16981                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16982                                compatibilityInfoForPackageLocked(appInfo));
16983                    } catch (Exception e) {
16984                        Slog.e(TAG, "Exception when unbinding backup agent:");
16985                        e.printStackTrace();
16986                    }
16987                }
16988            } finally {
16989                mBackupTarget = null;
16990                mBackupAppName = null;
16991            }
16992        }
16993    }
16994    // =========================================================
16995    // BROADCASTS
16996    // =========================================================
16997
16998    boolean isPendingBroadcastProcessLocked(int pid) {
16999        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17000                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17001    }
17002
17003    void skipPendingBroadcastLocked(int pid) {
17004            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17005            for (BroadcastQueue queue : mBroadcastQueues) {
17006                queue.skipPendingBroadcastLocked(pid);
17007            }
17008    }
17009
17010    // The app just attached; send any pending broadcasts that it should receive
17011    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17012        boolean didSomething = false;
17013        for (BroadcastQueue queue : mBroadcastQueues) {
17014            didSomething |= queue.sendPendingBroadcastsLocked(app);
17015        }
17016        return didSomething;
17017    }
17018
17019    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17020            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17021        enforceNotIsolatedCaller("registerReceiver");
17022        ArrayList<Intent> stickyIntents = null;
17023        ProcessRecord callerApp = null;
17024        int callingUid;
17025        int callingPid;
17026        synchronized(this) {
17027            if (caller != null) {
17028                callerApp = getRecordForAppLocked(caller);
17029                if (callerApp == null) {
17030                    throw new SecurityException(
17031                            "Unable to find app for caller " + caller
17032                            + " (pid=" + Binder.getCallingPid()
17033                            + ") when registering receiver " + receiver);
17034                }
17035                if (callerApp.info.uid != Process.SYSTEM_UID &&
17036                        !callerApp.pkgList.containsKey(callerPackage) &&
17037                        !"android".equals(callerPackage)) {
17038                    throw new SecurityException("Given caller package " + callerPackage
17039                            + " is not running in process " + callerApp);
17040                }
17041                callingUid = callerApp.info.uid;
17042                callingPid = callerApp.pid;
17043            } else {
17044                callerPackage = null;
17045                callingUid = Binder.getCallingUid();
17046                callingPid = Binder.getCallingPid();
17047            }
17048
17049            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17050                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17051
17052            Iterator<String> actions = filter.actionsIterator();
17053            if (actions == null) {
17054                ArrayList<String> noAction = new ArrayList<String>(1);
17055                noAction.add(null);
17056                actions = noAction.iterator();
17057            }
17058
17059            // Collect stickies of users
17060            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17061            while (actions.hasNext()) {
17062                String action = actions.next();
17063                for (int id : userIds) {
17064                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17065                    if (stickies != null) {
17066                        ArrayList<Intent> intents = stickies.get(action);
17067                        if (intents != null) {
17068                            if (stickyIntents == null) {
17069                                stickyIntents = new ArrayList<Intent>();
17070                            }
17071                            stickyIntents.addAll(intents);
17072                        }
17073                    }
17074                }
17075            }
17076        }
17077
17078        ArrayList<Intent> allSticky = null;
17079        if (stickyIntents != null) {
17080            final ContentResolver resolver = mContext.getContentResolver();
17081            // Look for any matching sticky broadcasts...
17082            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17083                Intent intent = stickyIntents.get(i);
17084                // If intent has scheme "content", it will need to acccess
17085                // provider that needs to lock mProviderMap in ActivityThread
17086                // and also it may need to wait application response, so we
17087                // cannot lock ActivityManagerService here.
17088                if (filter.match(resolver, intent, true, TAG) >= 0) {
17089                    if (allSticky == null) {
17090                        allSticky = new ArrayList<Intent>();
17091                    }
17092                    allSticky.add(intent);
17093                }
17094            }
17095        }
17096
17097        // The first sticky in the list is returned directly back to the client.
17098        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17099        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17100        if (receiver == null) {
17101            return sticky;
17102        }
17103
17104        synchronized (this) {
17105            if (callerApp != null && (callerApp.thread == null
17106                    || callerApp.thread.asBinder() != caller.asBinder())) {
17107                // Original caller already died
17108                return null;
17109            }
17110            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17111            if (rl == null) {
17112                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17113                        userId, receiver);
17114                if (rl.app != null) {
17115                    rl.app.receivers.add(rl);
17116                } else {
17117                    try {
17118                        receiver.asBinder().linkToDeath(rl, 0);
17119                    } catch (RemoteException e) {
17120                        return sticky;
17121                    }
17122                    rl.linkedToDeath = true;
17123                }
17124                mRegisteredReceivers.put(receiver.asBinder(), rl);
17125            } else if (rl.uid != callingUid) {
17126                throw new IllegalArgumentException(
17127                        "Receiver requested to register for uid " + callingUid
17128                        + " was previously registered for uid " + rl.uid);
17129            } else if (rl.pid != callingPid) {
17130                throw new IllegalArgumentException(
17131                        "Receiver requested to register for pid " + callingPid
17132                        + " was previously registered for pid " + rl.pid);
17133            } else if (rl.userId != userId) {
17134                throw new IllegalArgumentException(
17135                        "Receiver requested to register for user " + userId
17136                        + " was previously registered for user " + rl.userId);
17137            }
17138            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17139                    permission, callingUid, userId);
17140            rl.add(bf);
17141            if (!bf.debugCheck()) {
17142                Slog.w(TAG, "==> For Dynamic broadcast");
17143            }
17144            mReceiverResolver.addFilter(bf);
17145
17146            // Enqueue broadcasts for all existing stickies that match
17147            // this filter.
17148            if (allSticky != null) {
17149                ArrayList receivers = new ArrayList();
17150                receivers.add(bf);
17151
17152                final int stickyCount = allSticky.size();
17153                for (int i = 0; i < stickyCount; i++) {
17154                    Intent intent = allSticky.get(i);
17155                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17156                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17157                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17158                            null, 0, null, null, false, true, true, -1);
17159                    queue.enqueueParallelBroadcastLocked(r);
17160                    queue.scheduleBroadcastsLocked();
17161                }
17162            }
17163
17164            return sticky;
17165        }
17166    }
17167
17168    public void unregisterReceiver(IIntentReceiver receiver) {
17169        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17170
17171        final long origId = Binder.clearCallingIdentity();
17172        try {
17173            boolean doTrim = false;
17174
17175            synchronized(this) {
17176                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17177                if (rl != null) {
17178                    final BroadcastRecord r = rl.curBroadcast;
17179                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17180                        final boolean doNext = r.queue.finishReceiverLocked(
17181                                r, r.resultCode, r.resultData, r.resultExtras,
17182                                r.resultAbort, false);
17183                        if (doNext) {
17184                            doTrim = true;
17185                            r.queue.processNextBroadcast(false);
17186                        }
17187                    }
17188
17189                    if (rl.app != null) {
17190                        rl.app.receivers.remove(rl);
17191                    }
17192                    removeReceiverLocked(rl);
17193                    if (rl.linkedToDeath) {
17194                        rl.linkedToDeath = false;
17195                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17196                    }
17197                }
17198            }
17199
17200            // If we actually concluded any broadcasts, we might now be able
17201            // to trim the recipients' apps from our working set
17202            if (doTrim) {
17203                trimApplications();
17204                return;
17205            }
17206
17207        } finally {
17208            Binder.restoreCallingIdentity(origId);
17209        }
17210    }
17211
17212    void removeReceiverLocked(ReceiverList rl) {
17213        mRegisteredReceivers.remove(rl.receiver.asBinder());
17214        for (int i = rl.size() - 1; i >= 0; i--) {
17215            mReceiverResolver.removeFilter(rl.get(i));
17216        }
17217    }
17218
17219    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17220        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17221            ProcessRecord r = mLruProcesses.get(i);
17222            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17223                try {
17224                    r.thread.dispatchPackageBroadcast(cmd, packages);
17225                } catch (RemoteException ex) {
17226                }
17227            }
17228        }
17229    }
17230
17231    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17232            int callingUid, int[] users) {
17233        // TODO: come back and remove this assumption to triage all broadcasts
17234        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17235
17236        List<ResolveInfo> receivers = null;
17237        try {
17238            HashSet<ComponentName> singleUserReceivers = null;
17239            boolean scannedFirstReceivers = false;
17240            for (int user : users) {
17241                // Skip users that have Shell restrictions
17242                if (callingUid == Process.SHELL_UID
17243                        && mUserController.hasUserRestriction(
17244                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
17245                    continue;
17246                }
17247                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17248                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
17249                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17250                    // If this is not the system user, we need to check for
17251                    // any receivers that should be filtered out.
17252                    for (int i=0; i<newReceivers.size(); i++) {
17253                        ResolveInfo ri = newReceivers.get(i);
17254                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17255                            newReceivers.remove(i);
17256                            i--;
17257                        }
17258                    }
17259                }
17260                if (newReceivers != null && newReceivers.size() == 0) {
17261                    newReceivers = null;
17262                }
17263                if (receivers == null) {
17264                    receivers = newReceivers;
17265                } else if (newReceivers != null) {
17266                    // We need to concatenate the additional receivers
17267                    // found with what we have do far.  This would be easy,
17268                    // but we also need to de-dup any receivers that are
17269                    // singleUser.
17270                    if (!scannedFirstReceivers) {
17271                        // Collect any single user receivers we had already retrieved.
17272                        scannedFirstReceivers = true;
17273                        for (int i=0; i<receivers.size(); i++) {
17274                            ResolveInfo ri = receivers.get(i);
17275                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17276                                ComponentName cn = new ComponentName(
17277                                        ri.activityInfo.packageName, ri.activityInfo.name);
17278                                if (singleUserReceivers == null) {
17279                                    singleUserReceivers = new HashSet<ComponentName>();
17280                                }
17281                                singleUserReceivers.add(cn);
17282                            }
17283                        }
17284                    }
17285                    // Add the new results to the existing results, tracking
17286                    // and de-dupping single user receivers.
17287                    for (int i=0; i<newReceivers.size(); i++) {
17288                        ResolveInfo ri = newReceivers.get(i);
17289                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17290                            ComponentName cn = new ComponentName(
17291                                    ri.activityInfo.packageName, ri.activityInfo.name);
17292                            if (singleUserReceivers == null) {
17293                                singleUserReceivers = new HashSet<ComponentName>();
17294                            }
17295                            if (!singleUserReceivers.contains(cn)) {
17296                                singleUserReceivers.add(cn);
17297                                receivers.add(ri);
17298                            }
17299                        } else {
17300                            receivers.add(ri);
17301                        }
17302                    }
17303                }
17304            }
17305        } catch (RemoteException ex) {
17306            // pm is in same process, this will never happen.
17307        }
17308        return receivers;
17309    }
17310
17311    final int broadcastIntentLocked(ProcessRecord callerApp,
17312            String callerPackage, Intent intent, String resolvedType,
17313            IIntentReceiver resultTo, int resultCode, String resultData,
17314            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17315            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17316        intent = new Intent(intent);
17317
17318        // By default broadcasts do not go to stopped apps.
17319        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17320
17321        // If we have not finished booting, don't allow this to launch new processes.
17322        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17323            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17324        }
17325
17326        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17327                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17328                + " ordered=" + ordered + " userid=" + userId);
17329        if ((resultTo != null) && !ordered) {
17330            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17331        }
17332
17333        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17334                ALLOW_NON_FULL, "broadcast", callerPackage);
17335
17336        // Make sure that the user who is receiving this broadcast is running.
17337        // If not, we will just skip it. Make an exception for shutdown broadcasts
17338        // and upgrade steps.
17339
17340        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17341            if ((callingUid != Process.SYSTEM_UID
17342                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17343                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17344                Slog.w(TAG, "Skipping broadcast of " + intent
17345                        + ": user " + userId + " is stopped");
17346                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17347            }
17348        }
17349
17350        BroadcastOptions brOptions = null;
17351        if (bOptions != null) {
17352            brOptions = new BroadcastOptions(bOptions);
17353            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17354                // See if the caller is allowed to do this.  Note we are checking against
17355                // the actual real caller (not whoever provided the operation as say a
17356                // PendingIntent), because that who is actually supplied the arguments.
17357                if (checkComponentPermission(
17358                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17359                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17360                        != PackageManager.PERMISSION_GRANTED) {
17361                    String msg = "Permission Denial: " + intent.getAction()
17362                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17363                            + ", uid=" + callingUid + ")"
17364                            + " requires "
17365                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17366                    Slog.w(TAG, msg);
17367                    throw new SecurityException(msg);
17368                }
17369            }
17370        }
17371
17372        // Verify that protected broadcasts are only being sent by system code,
17373        // and that system code is only sending protected broadcasts.
17374        final String action = intent.getAction();
17375        final boolean isProtectedBroadcast;
17376        try {
17377            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17378        } catch (RemoteException e) {
17379            Slog.w(TAG, "Remote exception", e);
17380            return ActivityManager.BROADCAST_SUCCESS;
17381        }
17382
17383        final boolean isCallerSystem;
17384        switch (UserHandle.getAppId(callingUid)) {
17385            case Process.ROOT_UID:
17386            case Process.SYSTEM_UID:
17387            case Process.PHONE_UID:
17388            case Process.SHELL_UID:
17389            case Process.BLUETOOTH_UID:
17390            case Process.NFC_UID:
17391                isCallerSystem = true;
17392                break;
17393            default:
17394                isCallerSystem = (callerApp != null) && callerApp.persistent;
17395                break;
17396        }
17397
17398        if (isCallerSystem) {
17399            if (isProtectedBroadcast
17400                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17401                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17402                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17403                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17404                // Broadcast is either protected, or it's a public action that
17405                // we've relaxed, so it's fine for system internals to send.
17406            } else {
17407                // The vast majority of broadcasts sent from system internals
17408                // should be protected to avoid security holes, so yell loudly
17409                // to ensure we examine these cases.
17410                Log.wtf(TAG, "Sending non-protected broadcast " + action
17411                        + " from system", new Throwable());
17412            }
17413
17414        } else {
17415            if (isProtectedBroadcast) {
17416                String msg = "Permission Denial: not allowed to send broadcast "
17417                        + action + " from pid="
17418                        + callingPid + ", uid=" + callingUid;
17419                Slog.w(TAG, msg);
17420                throw new SecurityException(msg);
17421
17422            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17423                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17424                // Special case for compatibility: we don't want apps to send this,
17425                // but historically it has not been protected and apps may be using it
17426                // to poke their own app widget.  So, instead of making it protected,
17427                // just limit it to the caller.
17428                if (callerApp == null) {
17429                    String msg = "Permission Denial: not allowed to send broadcast "
17430                            + action + " from unknown caller.";
17431                    Slog.w(TAG, msg);
17432                    throw new SecurityException(msg);
17433                } else if (intent.getComponent() != null) {
17434                    // They are good enough to send to an explicit component...  verify
17435                    // it is being sent to the calling app.
17436                    if (!intent.getComponent().getPackageName().equals(
17437                            callerApp.info.packageName)) {
17438                        String msg = "Permission Denial: not allowed to send broadcast "
17439                                + action + " to "
17440                                + intent.getComponent().getPackageName() + " from "
17441                                + callerApp.info.packageName;
17442                        Slog.w(TAG, msg);
17443                        throw new SecurityException(msg);
17444                    }
17445                } else {
17446                    // Limit broadcast to their own package.
17447                    intent.setPackage(callerApp.info.packageName);
17448                }
17449            }
17450        }
17451
17452        if (action != null) {
17453            switch (action) {
17454                case Intent.ACTION_UID_REMOVED:
17455                case Intent.ACTION_PACKAGE_REMOVED:
17456                case Intent.ACTION_PACKAGE_CHANGED:
17457                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17458                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17459                    // Handle special intents: if this broadcast is from the package
17460                    // manager about a package being removed, we need to remove all of
17461                    // its activities from the history stack.
17462                    if (checkComponentPermission(
17463                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17464                            callingPid, callingUid, -1, true)
17465                            != PackageManager.PERMISSION_GRANTED) {
17466                        String msg = "Permission Denial: " + intent.getAction()
17467                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17468                                + ", uid=" + callingUid + ")"
17469                                + " requires "
17470                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17471                        Slog.w(TAG, msg);
17472                        throw new SecurityException(msg);
17473                    }
17474                    switch (action) {
17475                        case Intent.ACTION_UID_REMOVED:
17476                            final Bundle intentExtras = intent.getExtras();
17477                            final int uid = intentExtras != null
17478                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17479                            if (uid >= 0) {
17480                                mBatteryStatsService.removeUid(uid);
17481                                mAppOpsService.uidRemoved(uid);
17482                            }
17483                            break;
17484                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17485                            // If resources are unavailable just force stop all those packages
17486                            // and flush the attribute cache as well.
17487                            String list[] =
17488                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17489                            if (list != null && list.length > 0) {
17490                                for (int i = 0; i < list.length; i++) {
17491                                    forceStopPackageLocked(list[i], -1, false, true, true,
17492                                            false, false, userId, "storage unmount");
17493                                }
17494                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17495                                sendPackageBroadcastLocked(
17496                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17497                                        userId);
17498                            }
17499                            break;
17500                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17501                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17502                            break;
17503                        case Intent.ACTION_PACKAGE_REMOVED:
17504                        case Intent.ACTION_PACKAGE_CHANGED:
17505                            Uri data = intent.getData();
17506                            String ssp;
17507                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17508                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17509                                boolean fullUninstall = removed &&
17510                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17511                                final boolean killProcess =
17512                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17513                                if (killProcess) {
17514                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17515                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17516                                            false, true, true, false, fullUninstall, userId,
17517                                            removed ? "pkg removed" : "pkg changed");
17518                                }
17519                                if (removed) {
17520                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17521                                            new String[] {ssp}, userId);
17522                                    if (fullUninstall) {
17523                                        mAppOpsService.packageRemoved(
17524                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17525
17526                                        // Remove all permissions granted from/to this package
17527                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17528
17529                                        removeTasksByPackageNameLocked(ssp, userId);
17530                                        mBatteryStatsService.notePackageUninstalled(ssp);
17531                                    }
17532                                } else {
17533                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17534                                            intent.getStringArrayExtra(
17535                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17536                                }
17537                            }
17538                            break;
17539                    }
17540                    break;
17541                case Intent.ACTION_PACKAGE_ADDED:
17542                    // Special case for adding a package: by default turn on compatibility mode.
17543                    Uri data = intent.getData();
17544                    String ssp;
17545                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17546                        final boolean replacing =
17547                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17548                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17549
17550                        try {
17551                            ApplicationInfo ai = AppGlobals.getPackageManager().
17552                                    getApplicationInfo(ssp, 0, 0);
17553                            mBatteryStatsService.notePackageInstalled(ssp,
17554                                    ai != null ? ai.versionCode : 0);
17555                        } catch (RemoteException e) {
17556                        }
17557                    }
17558                    break;
17559                case Intent.ACTION_TIMEZONE_CHANGED:
17560                    // If this is the time zone changed action, queue up a message that will reset
17561                    // the timezone of all currently running processes. This message will get
17562                    // queued up before the broadcast happens.
17563                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17564                    break;
17565                case Intent.ACTION_TIME_CHANGED:
17566                    // If the user set the time, let all running processes know.
17567                    final int is24Hour =
17568                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17569                                    : 0;
17570                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17571                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17572                    synchronized (stats) {
17573                        stats.noteCurrentTimeChangedLocked();
17574                    }
17575                    break;
17576                case Intent.ACTION_CLEAR_DNS_CACHE:
17577                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17578                    break;
17579                case Proxy.PROXY_CHANGE_ACTION:
17580                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17581                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17582                    break;
17583            }
17584        }
17585
17586        // Add to the sticky list if requested.
17587        if (sticky) {
17588            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17589                    callingPid, callingUid)
17590                    != PackageManager.PERMISSION_GRANTED) {
17591                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17592                        + callingPid + ", uid=" + callingUid
17593                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17594                Slog.w(TAG, msg);
17595                throw new SecurityException(msg);
17596            }
17597            if (requiredPermissions != null && requiredPermissions.length > 0) {
17598                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17599                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17600                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17601            }
17602            if (intent.getComponent() != null) {
17603                throw new SecurityException(
17604                        "Sticky broadcasts can't target a specific component");
17605            }
17606            // We use userId directly here, since the "all" target is maintained
17607            // as a separate set of sticky broadcasts.
17608            if (userId != UserHandle.USER_ALL) {
17609                // But first, if this is not a broadcast to all users, then
17610                // make sure it doesn't conflict with an existing broadcast to
17611                // all users.
17612                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17613                        UserHandle.USER_ALL);
17614                if (stickies != null) {
17615                    ArrayList<Intent> list = stickies.get(intent.getAction());
17616                    if (list != null) {
17617                        int N = list.size();
17618                        int i;
17619                        for (i=0; i<N; i++) {
17620                            if (intent.filterEquals(list.get(i))) {
17621                                throw new IllegalArgumentException(
17622                                        "Sticky broadcast " + intent + " for user "
17623                                        + userId + " conflicts with existing global broadcast");
17624                            }
17625                        }
17626                    }
17627                }
17628            }
17629            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17630            if (stickies == null) {
17631                stickies = new ArrayMap<>();
17632                mStickyBroadcasts.put(userId, stickies);
17633            }
17634            ArrayList<Intent> list = stickies.get(intent.getAction());
17635            if (list == null) {
17636                list = new ArrayList<>();
17637                stickies.put(intent.getAction(), list);
17638            }
17639            final int stickiesCount = list.size();
17640            int i;
17641            for (i = 0; i < stickiesCount; i++) {
17642                if (intent.filterEquals(list.get(i))) {
17643                    // This sticky already exists, replace it.
17644                    list.set(i, new Intent(intent));
17645                    break;
17646                }
17647            }
17648            if (i >= stickiesCount) {
17649                list.add(new Intent(intent));
17650            }
17651        }
17652
17653        int[] users;
17654        if (userId == UserHandle.USER_ALL) {
17655            // Caller wants broadcast to go to all started users.
17656            users = mUserController.getStartedUserArrayLocked();
17657        } else {
17658            // Caller wants broadcast to go to one specific user.
17659            users = new int[] {userId};
17660        }
17661
17662        // Figure out who all will receive this broadcast.
17663        List receivers = null;
17664        List<BroadcastFilter> registeredReceivers = null;
17665        // Need to resolve the intent to interested receivers...
17666        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17667                 == 0) {
17668            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17669        }
17670        if (intent.getComponent() == null) {
17671            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17672                // Query one target user at a time, excluding shell-restricted users
17673                for (int i = 0; i < users.length; i++) {
17674                    if (mUserController.hasUserRestriction(
17675                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17676                        continue;
17677                    }
17678                    List<BroadcastFilter> registeredReceiversForUser =
17679                            mReceiverResolver.queryIntent(intent,
17680                                    resolvedType, false, users[i]);
17681                    if (registeredReceivers == null) {
17682                        registeredReceivers = registeredReceiversForUser;
17683                    } else if (registeredReceiversForUser != null) {
17684                        registeredReceivers.addAll(registeredReceiversForUser);
17685                    }
17686                }
17687            } else {
17688                registeredReceivers = mReceiverResolver.queryIntent(intent,
17689                        resolvedType, false, userId);
17690            }
17691        }
17692
17693        final boolean replacePending =
17694                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17695
17696        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17697                + " replacePending=" + replacePending);
17698
17699        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17700        if (!ordered && NR > 0) {
17701            // If we are not serializing this broadcast, then send the
17702            // registered receivers separately so they don't wait for the
17703            // components to be launched.
17704            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17705            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17706                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17707                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17708                    resultExtras, ordered, sticky, false, userId);
17709            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17710            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17711            if (!replaced) {
17712                queue.enqueueParallelBroadcastLocked(r);
17713                queue.scheduleBroadcastsLocked();
17714            }
17715            registeredReceivers = null;
17716            NR = 0;
17717        }
17718
17719        // Merge into one list.
17720        int ir = 0;
17721        if (receivers != null) {
17722            // A special case for PACKAGE_ADDED: do not allow the package
17723            // being added to see this broadcast.  This prevents them from
17724            // using this as a back door to get run as soon as they are
17725            // installed.  Maybe in the future we want to have a special install
17726            // broadcast or such for apps, but we'd like to deliberately make
17727            // this decision.
17728            String skipPackages[] = null;
17729            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17730                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17731                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17732                Uri data = intent.getData();
17733                if (data != null) {
17734                    String pkgName = data.getSchemeSpecificPart();
17735                    if (pkgName != null) {
17736                        skipPackages = new String[] { pkgName };
17737                    }
17738                }
17739            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17740                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17741            }
17742            if (skipPackages != null && (skipPackages.length > 0)) {
17743                for (String skipPackage : skipPackages) {
17744                    if (skipPackage != null) {
17745                        int NT = receivers.size();
17746                        for (int it=0; it<NT; it++) {
17747                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17748                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17749                                receivers.remove(it);
17750                                it--;
17751                                NT--;
17752                            }
17753                        }
17754                    }
17755                }
17756            }
17757
17758            int NT = receivers != null ? receivers.size() : 0;
17759            int it = 0;
17760            ResolveInfo curt = null;
17761            BroadcastFilter curr = null;
17762            while (it < NT && ir < NR) {
17763                if (curt == null) {
17764                    curt = (ResolveInfo)receivers.get(it);
17765                }
17766                if (curr == null) {
17767                    curr = registeredReceivers.get(ir);
17768                }
17769                if (curr.getPriority() >= curt.priority) {
17770                    // Insert this broadcast record into the final list.
17771                    receivers.add(it, curr);
17772                    ir++;
17773                    curr = null;
17774                    it++;
17775                    NT++;
17776                } else {
17777                    // Skip to the next ResolveInfo in the final list.
17778                    it++;
17779                    curt = null;
17780                }
17781            }
17782        }
17783        while (ir < NR) {
17784            if (receivers == null) {
17785                receivers = new ArrayList();
17786            }
17787            receivers.add(registeredReceivers.get(ir));
17788            ir++;
17789        }
17790
17791        if ((receivers != null && receivers.size() > 0)
17792                || resultTo != null) {
17793            BroadcastQueue queue = broadcastQueueForIntent(intent);
17794            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17795                    callerPackage, callingPid, callingUid, resolvedType,
17796                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17797                    resultData, resultExtras, ordered, sticky, false, userId);
17798
17799            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17800                    + ": prev had " + queue.mOrderedBroadcasts.size());
17801            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17802                    "Enqueueing broadcast " + r.intent.getAction());
17803
17804            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17805            if (!replaced) {
17806                queue.enqueueOrderedBroadcastLocked(r);
17807                queue.scheduleBroadcastsLocked();
17808            }
17809        }
17810
17811        return ActivityManager.BROADCAST_SUCCESS;
17812    }
17813
17814    final Intent verifyBroadcastLocked(Intent intent) {
17815        // Refuse possible leaked file descriptors
17816        if (intent != null && intent.hasFileDescriptors() == true) {
17817            throw new IllegalArgumentException("File descriptors passed in Intent");
17818        }
17819
17820        int flags = intent.getFlags();
17821
17822        if (!mProcessesReady) {
17823            // if the caller really truly claims to know what they're doing, go
17824            // ahead and allow the broadcast without launching any receivers
17825            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17826                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17827            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17828                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17829                        + " before boot completion");
17830                throw new IllegalStateException("Cannot broadcast before boot completed");
17831            }
17832        }
17833
17834        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17835            throw new IllegalArgumentException(
17836                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17837        }
17838
17839        return intent;
17840    }
17841
17842    public final int broadcastIntent(IApplicationThread caller,
17843            Intent intent, String resolvedType, IIntentReceiver resultTo,
17844            int resultCode, String resultData, Bundle resultExtras,
17845            String[] requiredPermissions, int appOp, Bundle bOptions,
17846            boolean serialized, boolean sticky, int userId) {
17847        enforceNotIsolatedCaller("broadcastIntent");
17848        synchronized(this) {
17849            intent = verifyBroadcastLocked(intent);
17850
17851            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17852            final int callingPid = Binder.getCallingPid();
17853            final int callingUid = Binder.getCallingUid();
17854            final long origId = Binder.clearCallingIdentity();
17855            int res = broadcastIntentLocked(callerApp,
17856                    callerApp != null ? callerApp.info.packageName : null,
17857                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17858                    requiredPermissions, appOp, null, serialized, sticky,
17859                    callingPid, callingUid, userId);
17860            Binder.restoreCallingIdentity(origId);
17861            return res;
17862        }
17863    }
17864
17865
17866    int broadcastIntentInPackage(String packageName, int uid,
17867            Intent intent, String resolvedType, IIntentReceiver resultTo,
17868            int resultCode, String resultData, Bundle resultExtras,
17869            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17870            int userId) {
17871        synchronized(this) {
17872            intent = verifyBroadcastLocked(intent);
17873
17874            final long origId = Binder.clearCallingIdentity();
17875            String[] requiredPermissions = requiredPermission == null ? null
17876                    : new String[] {requiredPermission};
17877            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17878                    resultTo, resultCode, resultData, resultExtras,
17879                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17880                    sticky, -1, uid, userId);
17881            Binder.restoreCallingIdentity(origId);
17882            return res;
17883        }
17884    }
17885
17886    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17887        // Refuse possible leaked file descriptors
17888        if (intent != null && intent.hasFileDescriptors() == true) {
17889            throw new IllegalArgumentException("File descriptors passed in Intent");
17890        }
17891
17892        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17893                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17894
17895        synchronized(this) {
17896            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17897                    != PackageManager.PERMISSION_GRANTED) {
17898                String msg = "Permission Denial: unbroadcastIntent() from pid="
17899                        + Binder.getCallingPid()
17900                        + ", uid=" + Binder.getCallingUid()
17901                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17902                Slog.w(TAG, msg);
17903                throw new SecurityException(msg);
17904            }
17905            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17906            if (stickies != null) {
17907                ArrayList<Intent> list = stickies.get(intent.getAction());
17908                if (list != null) {
17909                    int N = list.size();
17910                    int i;
17911                    for (i=0; i<N; i++) {
17912                        if (intent.filterEquals(list.get(i))) {
17913                            list.remove(i);
17914                            break;
17915                        }
17916                    }
17917                    if (list.size() <= 0) {
17918                        stickies.remove(intent.getAction());
17919                    }
17920                }
17921                if (stickies.size() <= 0) {
17922                    mStickyBroadcasts.remove(userId);
17923                }
17924            }
17925        }
17926    }
17927
17928    void backgroundServicesFinishedLocked(int userId) {
17929        for (BroadcastQueue queue : mBroadcastQueues) {
17930            queue.backgroundServicesFinishedLocked(userId);
17931        }
17932    }
17933
17934    public void finishReceiver(IBinder who, int resultCode, String resultData,
17935            Bundle resultExtras, boolean resultAbort, int flags) {
17936        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17937
17938        // Refuse possible leaked file descriptors
17939        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17940            throw new IllegalArgumentException("File descriptors passed in Bundle");
17941        }
17942
17943        final long origId = Binder.clearCallingIdentity();
17944        try {
17945            boolean doNext = false;
17946            BroadcastRecord r;
17947
17948            synchronized(this) {
17949                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17950                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17951                r = queue.getMatchingOrderedReceiver(who);
17952                if (r != null) {
17953                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17954                        resultData, resultExtras, resultAbort, true);
17955                }
17956            }
17957
17958            if (doNext) {
17959                r.queue.processNextBroadcast(false);
17960            }
17961            trimApplications();
17962        } finally {
17963            Binder.restoreCallingIdentity(origId);
17964        }
17965    }
17966
17967    // =========================================================
17968    // INSTRUMENTATION
17969    // =========================================================
17970
17971    public boolean startInstrumentation(ComponentName className,
17972            String profileFile, int flags, Bundle arguments,
17973            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17974            int userId, String abiOverride) {
17975        enforceNotIsolatedCaller("startInstrumentation");
17976        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17977                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17978        // Refuse possible leaked file descriptors
17979        if (arguments != null && arguments.hasFileDescriptors()) {
17980            throw new IllegalArgumentException("File descriptors passed in Bundle");
17981        }
17982
17983        synchronized(this) {
17984            InstrumentationInfo ii = null;
17985            ApplicationInfo ai = null;
17986            try {
17987                ii = mContext.getPackageManager().getInstrumentationInfo(
17988                    className, STOCK_PM_FLAGS);
17989                ai = AppGlobals.getPackageManager().getApplicationInfo(
17990                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17991            } catch (PackageManager.NameNotFoundException e) {
17992            } catch (RemoteException e) {
17993            }
17994            if (ii == null) {
17995                reportStartInstrumentationFailure(watcher, className,
17996                        "Unable to find instrumentation info for: " + className);
17997                return false;
17998            }
17999            if (ai == null) {
18000                reportStartInstrumentationFailure(watcher, className,
18001                        "Unable to find instrumentation target package: " + ii.targetPackage);
18002                return false;
18003            }
18004            if (!ai.hasCode()) {
18005                reportStartInstrumentationFailure(watcher, className,
18006                        "Instrumentation target has no code: " + ii.targetPackage);
18007                return false;
18008            }
18009
18010            int match = mContext.getPackageManager().checkSignatures(
18011                    ii.targetPackage, ii.packageName);
18012            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18013                String msg = "Permission Denial: starting instrumentation "
18014                        + className + " from pid="
18015                        + Binder.getCallingPid()
18016                        + ", uid=" + Binder.getCallingPid()
18017                        + " not allowed because package " + ii.packageName
18018                        + " does not have a signature matching the target "
18019                        + ii.targetPackage;
18020                reportStartInstrumentationFailure(watcher, className, msg);
18021                throw new SecurityException(msg);
18022            }
18023
18024            final long origId = Binder.clearCallingIdentity();
18025            // Instrumentation can kill and relaunch even persistent processes
18026            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18027                    "start instr");
18028            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18029            app.instrumentationClass = className;
18030            app.instrumentationInfo = ai;
18031            app.instrumentationProfileFile = profileFile;
18032            app.instrumentationArguments = arguments;
18033            app.instrumentationWatcher = watcher;
18034            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18035            app.instrumentationResultClass = className;
18036            Binder.restoreCallingIdentity(origId);
18037        }
18038
18039        return true;
18040    }
18041
18042    /**
18043     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18044     * error to the logs, but if somebody is watching, send the report there too.  This enables
18045     * the "am" command to report errors with more information.
18046     *
18047     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18048     * @param cn The component name of the instrumentation.
18049     * @param report The error report.
18050     */
18051    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
18052            ComponentName cn, String report) {
18053        Slog.w(TAG, report);
18054        try {
18055            if (watcher != null) {
18056                Bundle results = new Bundle();
18057                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18058                results.putString("Error", report);
18059                watcher.instrumentationStatus(cn, -1, results);
18060            }
18061        } catch (RemoteException e) {
18062            Slog.w(TAG, e);
18063        }
18064    }
18065
18066    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18067        if (app.instrumentationWatcher != null) {
18068            try {
18069                // NOTE:  IInstrumentationWatcher *must* be oneway here
18070                app.instrumentationWatcher.instrumentationFinished(
18071                    app.instrumentationClass,
18072                    resultCode,
18073                    results);
18074            } catch (RemoteException e) {
18075            }
18076        }
18077
18078        // Can't call out of the system process with a lock held, so post a message.
18079        if (app.instrumentationUiAutomationConnection != null) {
18080            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18081                    app.instrumentationUiAutomationConnection).sendToTarget();
18082        }
18083
18084        app.instrumentationWatcher = null;
18085        app.instrumentationUiAutomationConnection = null;
18086        app.instrumentationClass = null;
18087        app.instrumentationInfo = null;
18088        app.instrumentationProfileFile = null;
18089        app.instrumentationArguments = null;
18090
18091        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18092                "finished inst");
18093    }
18094
18095    public void finishInstrumentation(IApplicationThread target,
18096            int resultCode, Bundle results) {
18097        int userId = UserHandle.getCallingUserId();
18098        // Refuse possible leaked file descriptors
18099        if (results != null && results.hasFileDescriptors()) {
18100            throw new IllegalArgumentException("File descriptors passed in Intent");
18101        }
18102
18103        synchronized(this) {
18104            ProcessRecord app = getRecordForAppLocked(target);
18105            if (app == null) {
18106                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18107                return;
18108            }
18109            final long origId = Binder.clearCallingIdentity();
18110            finishInstrumentationLocked(app, resultCode, results);
18111            Binder.restoreCallingIdentity(origId);
18112        }
18113    }
18114
18115    // =========================================================
18116    // CONFIGURATION
18117    // =========================================================
18118
18119    public ConfigurationInfo getDeviceConfigurationInfo() {
18120        ConfigurationInfo config = new ConfigurationInfo();
18121        synchronized (this) {
18122            config.reqTouchScreen = mConfiguration.touchscreen;
18123            config.reqKeyboardType = mConfiguration.keyboard;
18124            config.reqNavigation = mConfiguration.navigation;
18125            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18126                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18127                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18128            }
18129            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18130                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18131                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18132            }
18133            config.reqGlEsVersion = GL_ES_VERSION;
18134        }
18135        return config;
18136    }
18137
18138    ActivityStack getFocusedStack() {
18139        return mStackSupervisor.getFocusedStack();
18140    }
18141
18142    @Override
18143    public int getFocusedStackId() throws RemoteException {
18144        ActivityStack focusedStack = getFocusedStack();
18145        if (focusedStack != null) {
18146            return focusedStack.getStackId();
18147        }
18148        return -1;
18149    }
18150
18151    public Configuration getConfiguration() {
18152        Configuration ci;
18153        synchronized(this) {
18154            ci = new Configuration(mConfiguration);
18155            ci.userSetLocale = false;
18156        }
18157        return ci;
18158    }
18159
18160    @Override
18161    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18162        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18163        synchronized (this) {
18164            mSuppressResizeConfigChanges = suppress;
18165        }
18166    }
18167
18168    @Override
18169    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18170        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18171        if (fromStackId == HOME_STACK_ID) {
18172            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18173        }
18174        synchronized (this) {
18175            final long origId = Binder.clearCallingIdentity();
18176            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
18177            if (stack != null) {
18178                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
18179                final int size = tasks.size();
18180                if (onTop) {
18181                    for (int i = 0; i < size; i++) {
18182                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18183                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
18184                                "moveTasksToFullscreenStack", ANIMATE);
18185                    }
18186                } else {
18187                    for (int i = size - 1; i >= 0; i--) {
18188                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18189                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
18190                    }
18191                }
18192            }
18193            Binder.restoreCallingIdentity(origId);
18194        }
18195    }
18196
18197    @Override
18198    public void updatePersistentConfiguration(Configuration values) {
18199        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18200                "updateConfiguration()");
18201        enforceWriteSettingsPermission("updateConfiguration()");
18202        if (values == null) {
18203            throw new NullPointerException("Configuration must not be null");
18204        }
18205
18206        int userId = UserHandle.getCallingUserId();
18207
18208        synchronized(this) {
18209            final long origId = Binder.clearCallingIdentity();
18210            updateConfigurationLocked(values, null, false, true, userId);
18211            Binder.restoreCallingIdentity(origId);
18212        }
18213    }
18214
18215    private void enforceWriteSettingsPermission(String func) {
18216        int uid = Binder.getCallingUid();
18217        if (uid == Process.ROOT_UID) {
18218            return;
18219        }
18220
18221        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18222                Settings.getPackageNameForUid(mContext, uid), false)) {
18223            return;
18224        }
18225
18226        String msg = "Permission Denial: " + func + " from pid="
18227                + Binder.getCallingPid()
18228                + ", uid=" + uid
18229                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18230        Slog.w(TAG, msg);
18231        throw new SecurityException(msg);
18232    }
18233
18234    public void updateConfiguration(Configuration values) {
18235        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18236                "updateConfiguration()");
18237
18238        synchronized(this) {
18239            if (values == null && mWindowManager != null) {
18240                // sentinel: fetch the current configuration from the window manager
18241                values = mWindowManager.computeNewConfiguration();
18242            }
18243
18244            if (mWindowManager != null) {
18245                mProcessList.applyDisplaySize(mWindowManager);
18246            }
18247
18248            final long origId = Binder.clearCallingIdentity();
18249            if (values != null) {
18250                Settings.System.clearConfiguration(values);
18251            }
18252            updateConfigurationLocked(values, null, false);
18253            Binder.restoreCallingIdentity(origId);
18254        }
18255    }
18256
18257    void updateUserConfigurationLocked() {
18258        Configuration configuration = new Configuration(mConfiguration);
18259        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18260                mUserController.getCurrentUserIdLocked());
18261        updateConfigurationLocked(configuration, null, false);
18262    }
18263
18264    boolean updateConfigurationLocked(Configuration values,
18265            ActivityRecord starting, boolean initLocale) {
18266        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18267        return updateConfigurationLocked(values, starting, initLocale, false,
18268                UserHandle.USER_NULL);
18269    }
18270
18271    // To cache the list of supported system locales
18272    private String[] mSupportedSystemLocales = null;
18273
18274    /**
18275     * Do either or both things: (1) change the current configuration, and (2)
18276     * make sure the given activity is running with the (now) current
18277     * configuration.  Returns true if the activity has been left running, or
18278     * false if <var>starting</var> is being destroyed to match the new
18279     * configuration.
18280     *
18281     * @param userId is only used when persistent parameter is set to true to persist configuration
18282     *               for that particular user
18283     */
18284    private boolean updateConfigurationLocked(Configuration values,
18285            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18286        int changes = 0;
18287
18288        if (values != null) {
18289            Configuration newConfig = new Configuration(mConfiguration);
18290            changes = newConfig.updateFrom(values);
18291            if (changes != 0) {
18292                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18293                        "Updating configuration to: " + values);
18294
18295                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18296
18297                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18298                    final Locale locale;
18299                    if (values.getLocales().size() == 1) {
18300                        // This is an optimization to avoid the JNI call when the result of
18301                        // getFirstMatch() does not depend on the supported locales.
18302                        locale = values.getLocales().getPrimary();
18303                    } else {
18304                        if (mSupportedSystemLocales == null) {
18305                            mSupportedSystemLocales =
18306                                    Resources.getSystem().getAssets().getLocales();
18307                        }
18308                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18309                    }
18310                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18311                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18312                            locale));
18313                }
18314
18315                mConfigurationSeq++;
18316                if (mConfigurationSeq <= 0) {
18317                    mConfigurationSeq = 1;
18318                }
18319                newConfig.seq = mConfigurationSeq;
18320                mConfiguration = newConfig;
18321                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18322                mUsageStatsService.reportConfigurationChange(newConfig,
18323                        mUserController.getCurrentUserIdLocked());
18324                //mUsageStatsService.noteStartConfig(newConfig);
18325
18326                final Configuration configCopy = new Configuration(mConfiguration);
18327
18328                // TODO: If our config changes, should we auto dismiss any currently
18329                // showing dialogs?
18330                mShowDialogs = shouldShowDialogs(newConfig);
18331
18332                AttributeCache ac = AttributeCache.instance();
18333                if (ac != null) {
18334                    ac.updateConfiguration(configCopy);
18335                }
18336
18337                // Make sure all resources in our process are updated
18338                // right now, so that anyone who is going to retrieve
18339                // resource values after we return will be sure to get
18340                // the new ones.  This is especially important during
18341                // boot, where the first config change needs to guarantee
18342                // all resources have that config before following boot
18343                // code is executed.
18344                mSystemThread.applyConfigurationToResources(configCopy);
18345
18346                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18347                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18348                    msg.obj = new Configuration(configCopy);
18349                    msg.arg1 = userId;
18350                    mHandler.sendMessage(msg);
18351                }
18352
18353                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18354                    ProcessRecord app = mLruProcesses.get(i);
18355                    try {
18356                        if (app.thread != null) {
18357                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18358                                    + app.processName + " new config " + mConfiguration);
18359                            app.thread.scheduleConfigurationChanged(configCopy);
18360                        }
18361                    } catch (Exception e) {
18362                    }
18363                }
18364                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18365                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18366                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18367                        | Intent.FLAG_RECEIVER_FOREGROUND);
18368                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18369                        null, AppOpsManager.OP_NONE, null, false, false,
18370                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18371                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18372                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18373                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18374                    if (!mProcessesReady) {
18375                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18376                    }
18377                    broadcastIntentLocked(null, null, intent,
18378                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18379                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18380                }
18381            }
18382        }
18383
18384        boolean kept = true;
18385        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18386        // mainStack is null during startup.
18387        if (mainStack != null) {
18388            if (changes != 0 && starting == null) {
18389                // If the configuration changed, and the caller is not already
18390                // in the process of starting an activity, then find the top
18391                // activity to check if its configuration needs to change.
18392                starting = mainStack.topRunningActivityLocked();
18393            }
18394
18395            if (starting != null) {
18396                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18397                // And we need to make sure at this point that all other activities
18398                // are made visible with the correct configuration.
18399                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18400                        !PRESERVE_WINDOWS);
18401            }
18402        }
18403
18404        if (values != null && mWindowManager != null) {
18405            mWindowManager.setNewConfiguration(mConfiguration);
18406        }
18407
18408        return kept;
18409    }
18410
18411    /**
18412     * Decide based on the configuration whether we should shouw the ANR,
18413     * crash, etc dialogs.  The idea is that if there is no affordnace to
18414     * press the on-screen buttons, we shouldn't show the dialog.
18415     *
18416     * A thought: SystemUI might also want to get told about this, the Power
18417     * dialog / global actions also might want different behaviors.
18418     */
18419    private static final boolean shouldShowDialogs(Configuration config) {
18420        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18421                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18422                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18423        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18424                                    == Configuration.UI_MODE_TYPE_CAR);
18425        return inputMethodExists && uiIsNotCarType;
18426    }
18427
18428    @Override
18429    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18430        synchronized (this) {
18431            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18432            if (srec != null) {
18433                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18434            }
18435        }
18436        return false;
18437    }
18438
18439    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18440            Intent resultData) {
18441
18442        synchronized (this) {
18443            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18444            if (r != null) {
18445                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18446            }
18447            return false;
18448        }
18449    }
18450
18451    public int getLaunchedFromUid(IBinder activityToken) {
18452        ActivityRecord srec;
18453        synchronized (this) {
18454            srec = ActivityRecord.forTokenLocked(activityToken);
18455        }
18456        if (srec == null) {
18457            return -1;
18458        }
18459        return srec.launchedFromUid;
18460    }
18461
18462    public String getLaunchedFromPackage(IBinder activityToken) {
18463        ActivityRecord srec;
18464        synchronized (this) {
18465            srec = ActivityRecord.forTokenLocked(activityToken);
18466        }
18467        if (srec == null) {
18468            return null;
18469        }
18470        return srec.launchedFromPackage;
18471    }
18472
18473    // =========================================================
18474    // LIFETIME MANAGEMENT
18475    // =========================================================
18476
18477    // Returns which broadcast queue the app is the current [or imminent] receiver
18478    // on, or 'null' if the app is not an active broadcast recipient.
18479    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18480        BroadcastRecord r = app.curReceiver;
18481        if (r != null) {
18482            return r.queue;
18483        }
18484
18485        // It's not the current receiver, but it might be starting up to become one
18486        synchronized (this) {
18487            for (BroadcastQueue queue : mBroadcastQueues) {
18488                r = queue.mPendingBroadcast;
18489                if (r != null && r.curApp == app) {
18490                    // found it; report which queue it's in
18491                    return queue;
18492                }
18493            }
18494        }
18495
18496        return null;
18497    }
18498
18499    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18500            ComponentName targetComponent, String targetProcess) {
18501        if (!mTrackingAssociations) {
18502            return null;
18503        }
18504        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18505                = mAssociations.get(targetUid);
18506        if (components == null) {
18507            components = new ArrayMap<>();
18508            mAssociations.put(targetUid, components);
18509        }
18510        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18511        if (sourceUids == null) {
18512            sourceUids = new SparseArray<>();
18513            components.put(targetComponent, sourceUids);
18514        }
18515        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18516        if (sourceProcesses == null) {
18517            sourceProcesses = new ArrayMap<>();
18518            sourceUids.put(sourceUid, sourceProcesses);
18519        }
18520        Association ass = sourceProcesses.get(sourceProcess);
18521        if (ass == null) {
18522            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18523                    targetProcess);
18524            sourceProcesses.put(sourceProcess, ass);
18525        }
18526        ass.mCount++;
18527        ass.mNesting++;
18528        if (ass.mNesting == 1) {
18529            ass.mStartTime = SystemClock.uptimeMillis();
18530        }
18531        return ass;
18532    }
18533
18534    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18535            ComponentName targetComponent) {
18536        if (!mTrackingAssociations) {
18537            return;
18538        }
18539        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18540                = mAssociations.get(targetUid);
18541        if (components == null) {
18542            return;
18543        }
18544        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18545        if (sourceUids == null) {
18546            return;
18547        }
18548        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18549        if (sourceProcesses == null) {
18550            return;
18551        }
18552        Association ass = sourceProcesses.get(sourceProcess);
18553        if (ass == null || ass.mNesting <= 0) {
18554            return;
18555        }
18556        ass.mNesting--;
18557        if (ass.mNesting == 0) {
18558            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18559        }
18560    }
18561
18562    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18563            boolean doingAll, long now) {
18564        if (mAdjSeq == app.adjSeq) {
18565            // This adjustment has already been computed.
18566            return app.curRawAdj;
18567        }
18568
18569        if (app.thread == null) {
18570            app.adjSeq = mAdjSeq;
18571            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18572            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18573            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18574        }
18575
18576        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18577        app.adjSource = null;
18578        app.adjTarget = null;
18579        app.empty = false;
18580        app.cached = false;
18581
18582        final int activitiesSize = app.activities.size();
18583
18584        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18585            // The max adjustment doesn't allow this app to be anything
18586            // below foreground, so it is not worth doing work for it.
18587            app.adjType = "fixed";
18588            app.adjSeq = mAdjSeq;
18589            app.curRawAdj = app.maxAdj;
18590            app.foregroundActivities = false;
18591            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18592            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18593            // System processes can do UI, and when they do we want to have
18594            // them trim their memory after the user leaves the UI.  To
18595            // facilitate this, here we need to determine whether or not it
18596            // is currently showing UI.
18597            app.systemNoUi = true;
18598            if (app == TOP_APP) {
18599                app.systemNoUi = false;
18600            } else if (activitiesSize > 0) {
18601                for (int j = 0; j < activitiesSize; j++) {
18602                    final ActivityRecord r = app.activities.get(j);
18603                    if (r.visible) {
18604                        app.systemNoUi = false;
18605                    }
18606                }
18607            }
18608            if (!app.systemNoUi) {
18609                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18610            }
18611            return (app.curAdj=app.maxAdj);
18612        }
18613
18614        app.systemNoUi = false;
18615
18616        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18617
18618        // Determine the importance of the process, starting with most
18619        // important to least, and assign an appropriate OOM adjustment.
18620        int adj;
18621        int schedGroup;
18622        int procState;
18623        boolean foregroundActivities = false;
18624        BroadcastQueue queue;
18625        if (app == TOP_APP) {
18626            // The last app on the list is the foreground app.
18627            adj = ProcessList.FOREGROUND_APP_ADJ;
18628            schedGroup = Process.THREAD_GROUP_DEFAULT;
18629            app.adjType = "top-activity";
18630            foregroundActivities = true;
18631            procState = PROCESS_STATE_CUR_TOP;
18632        } else if (app.instrumentationClass != null) {
18633            // Don't want to kill running instrumentation.
18634            adj = ProcessList.FOREGROUND_APP_ADJ;
18635            schedGroup = Process.THREAD_GROUP_DEFAULT;
18636            app.adjType = "instrumentation";
18637            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18638        } else if ((queue = isReceivingBroadcast(app)) != null) {
18639            // An app that is currently receiving a broadcast also
18640            // counts as being in the foreground for OOM killer purposes.
18641            // It's placed in a sched group based on the nature of the
18642            // broadcast as reflected by which queue it's active in.
18643            adj = ProcessList.FOREGROUND_APP_ADJ;
18644            schedGroup = (queue == mFgBroadcastQueue)
18645                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18646            app.adjType = "broadcast";
18647            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18648        } else if (app.executingServices.size() > 0) {
18649            // An app that is currently executing a service callback also
18650            // counts as being in the foreground.
18651            adj = ProcessList.FOREGROUND_APP_ADJ;
18652            schedGroup = app.execServicesFg ?
18653                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18654            app.adjType = "exec-service";
18655            procState = ActivityManager.PROCESS_STATE_SERVICE;
18656            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18657        } else {
18658            // As far as we know the process is empty.  We may change our mind later.
18659            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18660            // At this point we don't actually know the adjustment.  Use the cached adj
18661            // value that the caller wants us to.
18662            adj = cachedAdj;
18663            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18664            app.cached = true;
18665            app.empty = true;
18666            app.adjType = "cch-empty";
18667        }
18668
18669        // Examine all activities if not already foreground.
18670        if (!foregroundActivities && activitiesSize > 0) {
18671            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18672            for (int j = 0; j < activitiesSize; j++) {
18673                final ActivityRecord r = app.activities.get(j);
18674                if (r.app != app) {
18675                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18676                            + app + "?!? Using " + r.app + " instead.");
18677                    continue;
18678                }
18679                if (r.visible) {
18680                    // App has a visible activity; only upgrade adjustment.
18681                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18682                        adj = ProcessList.VISIBLE_APP_ADJ;
18683                        app.adjType = "visible";
18684                    }
18685                    if (procState > PROCESS_STATE_CUR_TOP) {
18686                        procState = PROCESS_STATE_CUR_TOP;
18687                    }
18688                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18689                    app.cached = false;
18690                    app.empty = false;
18691                    foregroundActivities = true;
18692                    if (r.task != null && minLayer > 0) {
18693                        final int layer = r.task.mLayerRank;
18694                        if (layer >= 0 && minLayer > layer) {
18695                            minLayer = layer;
18696                        }
18697                    }
18698                    break;
18699                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18700                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18701                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18702                        app.adjType = "pausing";
18703                    }
18704                    if (procState > PROCESS_STATE_CUR_TOP) {
18705                        procState = PROCESS_STATE_CUR_TOP;
18706                    }
18707                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18708                    app.cached = false;
18709                    app.empty = false;
18710                    foregroundActivities = true;
18711                } else if (r.state == ActivityState.STOPPING) {
18712                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18713                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18714                        app.adjType = "stopping";
18715                    }
18716                    // For the process state, we will at this point consider the
18717                    // process to be cached.  It will be cached either as an activity
18718                    // or empty depending on whether the activity is finishing.  We do
18719                    // this so that we can treat the process as cached for purposes of
18720                    // memory trimming (determing current memory level, trim command to
18721                    // send to process) since there can be an arbitrary number of stopping
18722                    // processes and they should soon all go into the cached state.
18723                    if (!r.finishing) {
18724                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18725                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18726                        }
18727                    }
18728                    app.cached = false;
18729                    app.empty = false;
18730                    foregroundActivities = true;
18731                } else {
18732                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18733                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18734                        app.adjType = "cch-act";
18735                    }
18736                }
18737            }
18738            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18739                adj += minLayer;
18740            }
18741        }
18742
18743        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18744                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18745            if (app.foregroundServices) {
18746                // The user is aware of this app, so make it visible.
18747                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18748                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18749                app.cached = false;
18750                app.adjType = "fg-service";
18751                schedGroup = Process.THREAD_GROUP_DEFAULT;
18752            } else if (app.forcingToForeground != null) {
18753                // The user is aware of this app, so make it visible.
18754                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18755                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18756                app.cached = false;
18757                app.adjType = "force-fg";
18758                app.adjSource = app.forcingToForeground;
18759                schedGroup = Process.THREAD_GROUP_DEFAULT;
18760            }
18761        }
18762
18763        if (app == mHeavyWeightProcess) {
18764            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18765                // We don't want to kill the current heavy-weight process.
18766                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18767                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18768                app.cached = false;
18769                app.adjType = "heavy";
18770            }
18771            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18772                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18773            }
18774        }
18775
18776        if (app == mHomeProcess) {
18777            if (adj > ProcessList.HOME_APP_ADJ) {
18778                // This process is hosting what we currently consider to be the
18779                // home app, so we don't want to let it go into the background.
18780                adj = ProcessList.HOME_APP_ADJ;
18781                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18782                app.cached = false;
18783                app.adjType = "home";
18784            }
18785            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18786                procState = ActivityManager.PROCESS_STATE_HOME;
18787            }
18788        }
18789
18790        if (app == mPreviousProcess && app.activities.size() > 0) {
18791            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18792                // This was the previous process that showed UI to the user.
18793                // We want to try to keep it around more aggressively, to give
18794                // a good experience around switching between two apps.
18795                adj = ProcessList.PREVIOUS_APP_ADJ;
18796                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18797                app.cached = false;
18798                app.adjType = "previous";
18799            }
18800            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18801                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18802            }
18803        }
18804
18805        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18806                + " reason=" + app.adjType);
18807
18808        // By default, we use the computed adjustment.  It may be changed if
18809        // there are applications dependent on our services or providers, but
18810        // this gives us a baseline and makes sure we don't get into an
18811        // infinite recursion.
18812        app.adjSeq = mAdjSeq;
18813        app.curRawAdj = adj;
18814        app.hasStartedServices = false;
18815
18816        if (mBackupTarget != null && app == mBackupTarget.app) {
18817            // If possible we want to avoid killing apps while they're being backed up
18818            if (adj > ProcessList.BACKUP_APP_ADJ) {
18819                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18820                adj = ProcessList.BACKUP_APP_ADJ;
18821                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18822                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18823                }
18824                app.adjType = "backup";
18825                app.cached = false;
18826            }
18827            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18828                procState = ActivityManager.PROCESS_STATE_BACKUP;
18829            }
18830        }
18831
18832        boolean mayBeTop = false;
18833
18834        for (int is = app.services.size()-1;
18835                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18836                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18837                        || procState > ActivityManager.PROCESS_STATE_TOP);
18838                is--) {
18839            ServiceRecord s = app.services.valueAt(is);
18840            if (s.startRequested) {
18841                app.hasStartedServices = true;
18842                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18843                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18844                }
18845                if (app.hasShownUi && app != mHomeProcess) {
18846                    // If this process has shown some UI, let it immediately
18847                    // go to the LRU list because it may be pretty heavy with
18848                    // UI stuff.  We'll tag it with a label just to help
18849                    // debug and understand what is going on.
18850                    if (adj > ProcessList.SERVICE_ADJ) {
18851                        app.adjType = "cch-started-ui-services";
18852                    }
18853                } else {
18854                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18855                        // This service has seen some activity within
18856                        // recent memory, so we will keep its process ahead
18857                        // of the background processes.
18858                        if (adj > ProcessList.SERVICE_ADJ) {
18859                            adj = ProcessList.SERVICE_ADJ;
18860                            app.adjType = "started-services";
18861                            app.cached = false;
18862                        }
18863                    }
18864                    // If we have let the service slide into the background
18865                    // state, still have some text describing what it is doing
18866                    // even though the service no longer has an impact.
18867                    if (adj > ProcessList.SERVICE_ADJ) {
18868                        app.adjType = "cch-started-services";
18869                    }
18870                }
18871            }
18872            for (int conni = s.connections.size()-1;
18873                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18874                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18875                            || procState > ActivityManager.PROCESS_STATE_TOP);
18876                    conni--) {
18877                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18878                for (int i = 0;
18879                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18880                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18881                                || procState > ActivityManager.PROCESS_STATE_TOP);
18882                        i++) {
18883                    // XXX should compute this based on the max of
18884                    // all connected clients.
18885                    ConnectionRecord cr = clist.get(i);
18886                    if (cr.binding.client == app) {
18887                        // Binding to ourself is not interesting.
18888                        continue;
18889                    }
18890                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18891                        ProcessRecord client = cr.binding.client;
18892                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18893                                TOP_APP, doingAll, now);
18894                        int clientProcState = client.curProcState;
18895                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18896                            // If the other app is cached for any reason, for purposes here
18897                            // we are going to consider it empty.  The specific cached state
18898                            // doesn't propagate except under certain conditions.
18899                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18900                        }
18901                        String adjType = null;
18902                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18903                            // Not doing bind OOM management, so treat
18904                            // this guy more like a started service.
18905                            if (app.hasShownUi && app != mHomeProcess) {
18906                                // If this process has shown some UI, let it immediately
18907                                // go to the LRU list because it may be pretty heavy with
18908                                // UI stuff.  We'll tag it with a label just to help
18909                                // debug and understand what is going on.
18910                                if (adj > clientAdj) {
18911                                    adjType = "cch-bound-ui-services";
18912                                }
18913                                app.cached = false;
18914                                clientAdj = adj;
18915                                clientProcState = procState;
18916                            } else {
18917                                if (now >= (s.lastActivity
18918                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18919                                    // This service has not seen activity within
18920                                    // recent memory, so allow it to drop to the
18921                                    // LRU list if there is no other reason to keep
18922                                    // it around.  We'll also tag it with a label just
18923                                    // to help debug and undertand what is going on.
18924                                    if (adj > clientAdj) {
18925                                        adjType = "cch-bound-services";
18926                                    }
18927                                    clientAdj = adj;
18928                                }
18929                            }
18930                        }
18931                        if (adj > clientAdj) {
18932                            // If this process has recently shown UI, and
18933                            // the process that is binding to it is less
18934                            // important than being visible, then we don't
18935                            // care about the binding as much as we care
18936                            // about letting this process get into the LRU
18937                            // list to be killed and restarted if needed for
18938                            // memory.
18939                            if (app.hasShownUi && app != mHomeProcess
18940                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18941                                adjType = "cch-bound-ui-services";
18942                            } else {
18943                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18944                                        |Context.BIND_IMPORTANT)) != 0) {
18945                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18946                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18947                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18948                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18949                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18950                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18951                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18952                                    adj = clientAdj;
18953                                } else {
18954                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18955                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18956                                    }
18957                                }
18958                                if (!client.cached) {
18959                                    app.cached = false;
18960                                }
18961                                adjType = "service";
18962                            }
18963                        }
18964                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18965                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18966                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18967                            }
18968                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18969                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18970                                    // Special handling of clients who are in the top state.
18971                                    // We *may* want to consider this process to be in the
18972                                    // top state as well, but only if there is not another
18973                                    // reason for it to be running.  Being on the top is a
18974                                    // special state, meaning you are specifically running
18975                                    // for the current top app.  If the process is already
18976                                    // running in the background for some other reason, it
18977                                    // is more important to continue considering it to be
18978                                    // in the background state.
18979                                    mayBeTop = true;
18980                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18981                                } else {
18982                                    // Special handling for above-top states (persistent
18983                                    // processes).  These should not bring the current process
18984                                    // into the top state, since they are not on top.  Instead
18985                                    // give them the best state after that.
18986                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18987                                        clientProcState =
18988                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18989                                    } else if (mWakefulness
18990                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18991                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18992                                                    != 0) {
18993                                        clientProcState =
18994                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18995                                    } else {
18996                                        clientProcState =
18997                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18998                                    }
18999                                }
19000                            }
19001                        } else {
19002                            if (clientProcState <
19003                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19004                                clientProcState =
19005                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19006                            }
19007                        }
19008                        if (procState > clientProcState) {
19009                            procState = clientProcState;
19010                        }
19011                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19012                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19013                            app.pendingUiClean = true;
19014                        }
19015                        if (adjType != null) {
19016                            app.adjType = adjType;
19017                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19018                                    .REASON_SERVICE_IN_USE;
19019                            app.adjSource = cr.binding.client;
19020                            app.adjSourceProcState = clientProcState;
19021                            app.adjTarget = s.name;
19022                        }
19023                    }
19024                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19025                        app.treatLikeActivity = true;
19026                    }
19027                    final ActivityRecord a = cr.activity;
19028                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19029                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19030                                (a.visible || a.state == ActivityState.RESUMED
19031                                 || a.state == ActivityState.PAUSING)) {
19032                            adj = ProcessList.FOREGROUND_APP_ADJ;
19033                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19034                                schedGroup = Process.THREAD_GROUP_DEFAULT;
19035                            }
19036                            app.cached = false;
19037                            app.adjType = "service";
19038                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19039                                    .REASON_SERVICE_IN_USE;
19040                            app.adjSource = a;
19041                            app.adjSourceProcState = procState;
19042                            app.adjTarget = s.name;
19043                        }
19044                    }
19045                }
19046            }
19047        }
19048
19049        for (int provi = app.pubProviders.size()-1;
19050                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19051                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
19052                        || procState > ActivityManager.PROCESS_STATE_TOP);
19053                provi--) {
19054            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19055            for (int i = cpr.connections.size()-1;
19056                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19057                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
19058                            || procState > ActivityManager.PROCESS_STATE_TOP);
19059                    i--) {
19060                ContentProviderConnection conn = cpr.connections.get(i);
19061                ProcessRecord client = conn.client;
19062                if (client == app) {
19063                    // Being our own client is not interesting.
19064                    continue;
19065                }
19066                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19067                int clientProcState = client.curProcState;
19068                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19069                    // If the other app is cached for any reason, for purposes here
19070                    // we are going to consider it empty.
19071                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19072                }
19073                if (adj > clientAdj) {
19074                    if (app.hasShownUi && app != mHomeProcess
19075                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19076                        app.adjType = "cch-ui-provider";
19077                    } else {
19078                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19079                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19080                        app.adjType = "provider";
19081                    }
19082                    app.cached &= client.cached;
19083                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19084                            .REASON_PROVIDER_IN_USE;
19085                    app.adjSource = client;
19086                    app.adjSourceProcState = clientProcState;
19087                    app.adjTarget = cpr.name;
19088                }
19089                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19090                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19091                        // Special handling of clients who are in the top state.
19092                        // We *may* want to consider this process to be in the
19093                        // top state as well, but only if there is not another
19094                        // reason for it to be running.  Being on the top is a
19095                        // special state, meaning you are specifically running
19096                        // for the current top app.  If the process is already
19097                        // running in the background for some other reason, it
19098                        // is more important to continue considering it to be
19099                        // in the background state.
19100                        mayBeTop = true;
19101                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19102                    } else {
19103                        // Special handling for above-top states (persistent
19104                        // processes).  These should not bring the current process
19105                        // into the top state, since they are not on top.  Instead
19106                        // give them the best state after that.
19107                        clientProcState =
19108                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19109                    }
19110                }
19111                if (procState > clientProcState) {
19112                    procState = clientProcState;
19113                }
19114                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
19115                    schedGroup = Process.THREAD_GROUP_DEFAULT;
19116                }
19117            }
19118            // If the provider has external (non-framework) process
19119            // dependencies, ensure that its adjustment is at least
19120            // FOREGROUND_APP_ADJ.
19121            if (cpr.hasExternalProcessHandles()) {
19122                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19123                    adj = ProcessList.FOREGROUND_APP_ADJ;
19124                    schedGroup = Process.THREAD_GROUP_DEFAULT;
19125                    app.cached = false;
19126                    app.adjType = "provider";
19127                    app.adjTarget = cpr.name;
19128                }
19129                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19130                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19131                }
19132            }
19133        }
19134
19135        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19136            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19137                adj = ProcessList.PREVIOUS_APP_ADJ;
19138                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19139                app.cached = false;
19140                app.adjType = "provider";
19141            }
19142            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19143                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19144            }
19145        }
19146
19147        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19148            // A client of one of our services or providers is in the top state.  We
19149            // *may* want to be in the top state, but not if we are already running in
19150            // the background for some other reason.  For the decision here, we are going
19151            // to pick out a few specific states that we want to remain in when a client
19152            // is top (states that tend to be longer-term) and otherwise allow it to go
19153            // to the top state.
19154            switch (procState) {
19155                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19156                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19157                case ActivityManager.PROCESS_STATE_SERVICE:
19158                    // These all are longer-term states, so pull them up to the top
19159                    // of the background states, but not all the way to the top state.
19160                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19161                    break;
19162                default:
19163                    // Otherwise, top is a better choice, so take it.
19164                    procState = ActivityManager.PROCESS_STATE_TOP;
19165                    break;
19166            }
19167        }
19168
19169        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19170            if (app.hasClientActivities) {
19171                // This is a cached process, but with client activities.  Mark it so.
19172                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19173                app.adjType = "cch-client-act";
19174            } else if (app.treatLikeActivity) {
19175                // This is a cached process, but somebody wants us to treat it like it has
19176                // an activity, okay!
19177                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19178                app.adjType = "cch-as-act";
19179            }
19180        }
19181
19182        if (adj == ProcessList.SERVICE_ADJ) {
19183            if (doingAll) {
19184                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19185                mNewNumServiceProcs++;
19186                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19187                if (!app.serviceb) {
19188                    // This service isn't far enough down on the LRU list to
19189                    // normally be a B service, but if we are low on RAM and it
19190                    // is large we want to force it down since we would prefer to
19191                    // keep launcher over it.
19192                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19193                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19194                        app.serviceHighRam = true;
19195                        app.serviceb = true;
19196                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19197                    } else {
19198                        mNewNumAServiceProcs++;
19199                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19200                    }
19201                } else {
19202                    app.serviceHighRam = false;
19203                }
19204            }
19205            if (app.serviceb) {
19206                adj = ProcessList.SERVICE_B_ADJ;
19207            }
19208        }
19209
19210        app.curRawAdj = adj;
19211
19212        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19213        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19214        if (adj > app.maxAdj) {
19215            adj = app.maxAdj;
19216            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19217                schedGroup = Process.THREAD_GROUP_DEFAULT;
19218            }
19219        }
19220
19221        // Do final modification to adj.  Everything we do between here and applying
19222        // the final setAdj must be done in this function, because we will also use
19223        // it when computing the final cached adj later.  Note that we don't need to
19224        // worry about this for max adj above, since max adj will always be used to
19225        // keep it out of the cached vaues.
19226        app.curAdj = app.modifyRawOomAdj(adj);
19227        app.curSchedGroup = schedGroup;
19228        app.curProcState = procState;
19229        app.foregroundActivities = foregroundActivities;
19230
19231        return app.curRawAdj;
19232    }
19233
19234    /**
19235     * Record new PSS sample for a process.
19236     */
19237    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19238            long now) {
19239        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19240                swapPss * 1024);
19241        proc.lastPssTime = now;
19242        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19243        if (DEBUG_PSS) Slog.d(TAG_PSS,
19244                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19245                + " state=" + ProcessList.makeProcStateString(procState));
19246        if (proc.initialIdlePss == 0) {
19247            proc.initialIdlePss = pss;
19248        }
19249        proc.lastPss = pss;
19250        proc.lastSwapPss = swapPss;
19251        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19252            proc.lastCachedPss = pss;
19253            proc.lastCachedSwapPss = swapPss;
19254        }
19255
19256        final SparseArray<Pair<Long, String>> watchUids
19257                = mMemWatchProcesses.getMap().get(proc.processName);
19258        Long check = null;
19259        if (watchUids != null) {
19260            Pair<Long, String> val = watchUids.get(proc.uid);
19261            if (val == null) {
19262                val = watchUids.get(0);
19263            }
19264            if (val != null) {
19265                check = val.first;
19266            }
19267        }
19268        if (check != null) {
19269            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19270                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19271                if (!isDebuggable) {
19272                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19273                        isDebuggable = true;
19274                    }
19275                }
19276                if (isDebuggable) {
19277                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19278                    final ProcessRecord myProc = proc;
19279                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19280                    mMemWatchDumpProcName = proc.processName;
19281                    mMemWatchDumpFile = heapdumpFile.toString();
19282                    mMemWatchDumpPid = proc.pid;
19283                    mMemWatchDumpUid = proc.uid;
19284                    BackgroundThread.getHandler().post(new Runnable() {
19285                        @Override
19286                        public void run() {
19287                            revokeUriPermission(ActivityThread.currentActivityThread()
19288                                            .getApplicationThread(),
19289                                    DumpHeapActivity.JAVA_URI,
19290                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19291                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19292                                    UserHandle.myUserId());
19293                            ParcelFileDescriptor fd = null;
19294                            try {
19295                                heapdumpFile.delete();
19296                                fd = ParcelFileDescriptor.open(heapdumpFile,
19297                                        ParcelFileDescriptor.MODE_CREATE |
19298                                                ParcelFileDescriptor.MODE_TRUNCATE |
19299                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19300                                                ParcelFileDescriptor.MODE_APPEND);
19301                                IApplicationThread thread = myProc.thread;
19302                                if (thread != null) {
19303                                    try {
19304                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19305                                                "Requesting dump heap from "
19306                                                + myProc + " to " + heapdumpFile);
19307                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19308                                    } catch (RemoteException e) {
19309                                    }
19310                                }
19311                            } catch (FileNotFoundException e) {
19312                                e.printStackTrace();
19313                            } finally {
19314                                if (fd != null) {
19315                                    try {
19316                                        fd.close();
19317                                    } catch (IOException e) {
19318                                    }
19319                                }
19320                            }
19321                        }
19322                    });
19323                } else {
19324                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19325                            + ", but debugging not enabled");
19326                }
19327            }
19328        }
19329    }
19330
19331    /**
19332     * Schedule PSS collection of a process.
19333     */
19334    void requestPssLocked(ProcessRecord proc, int procState) {
19335        if (mPendingPssProcesses.contains(proc)) {
19336            return;
19337        }
19338        if (mPendingPssProcesses.size() == 0) {
19339            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19340        }
19341        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19342        proc.pssProcState = procState;
19343        mPendingPssProcesses.add(proc);
19344    }
19345
19346    /**
19347     * Schedule PSS collection of all processes.
19348     */
19349    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19350        if (!always) {
19351            if (now < (mLastFullPssTime +
19352                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19353                return;
19354            }
19355        }
19356        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19357        mLastFullPssTime = now;
19358        mFullPssPending = true;
19359        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19360        mPendingPssProcesses.clear();
19361        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19362            ProcessRecord app = mLruProcesses.get(i);
19363            if (app.thread == null
19364                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19365                continue;
19366            }
19367            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19368                app.pssProcState = app.setProcState;
19369                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19370                        mTestPssMode, isSleeping(), now);
19371                mPendingPssProcesses.add(app);
19372            }
19373        }
19374        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19375    }
19376
19377    public void setTestPssMode(boolean enabled) {
19378        synchronized (this) {
19379            mTestPssMode = enabled;
19380            if (enabled) {
19381                // Whenever we enable the mode, we want to take a snapshot all of current
19382                // process mem use.
19383                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19384            }
19385        }
19386    }
19387
19388    /**
19389     * Ask a given process to GC right now.
19390     */
19391    final void performAppGcLocked(ProcessRecord app) {
19392        try {
19393            app.lastRequestedGc = SystemClock.uptimeMillis();
19394            if (app.thread != null) {
19395                if (app.reportLowMemory) {
19396                    app.reportLowMemory = false;
19397                    app.thread.scheduleLowMemory();
19398                } else {
19399                    app.thread.processInBackground();
19400                }
19401            }
19402        } catch (Exception e) {
19403            // whatever.
19404        }
19405    }
19406
19407    /**
19408     * Returns true if things are idle enough to perform GCs.
19409     */
19410    private final boolean canGcNowLocked() {
19411        boolean processingBroadcasts = false;
19412        for (BroadcastQueue q : mBroadcastQueues) {
19413            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19414                processingBroadcasts = true;
19415            }
19416        }
19417        return !processingBroadcasts
19418                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19419    }
19420
19421    /**
19422     * Perform GCs on all processes that are waiting for it, but only
19423     * if things are idle.
19424     */
19425    final void performAppGcsLocked() {
19426        final int N = mProcessesToGc.size();
19427        if (N <= 0) {
19428            return;
19429        }
19430        if (canGcNowLocked()) {
19431            while (mProcessesToGc.size() > 0) {
19432                ProcessRecord proc = mProcessesToGc.remove(0);
19433                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19434                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19435                            <= SystemClock.uptimeMillis()) {
19436                        // To avoid spamming the system, we will GC processes one
19437                        // at a time, waiting a few seconds between each.
19438                        performAppGcLocked(proc);
19439                        scheduleAppGcsLocked();
19440                        return;
19441                    } else {
19442                        // It hasn't been long enough since we last GCed this
19443                        // process...  put it in the list to wait for its time.
19444                        addProcessToGcListLocked(proc);
19445                        break;
19446                    }
19447                }
19448            }
19449
19450            scheduleAppGcsLocked();
19451        }
19452    }
19453
19454    /**
19455     * If all looks good, perform GCs on all processes waiting for them.
19456     */
19457    final void performAppGcsIfAppropriateLocked() {
19458        if (canGcNowLocked()) {
19459            performAppGcsLocked();
19460            return;
19461        }
19462        // Still not idle, wait some more.
19463        scheduleAppGcsLocked();
19464    }
19465
19466    /**
19467     * Schedule the execution of all pending app GCs.
19468     */
19469    final void scheduleAppGcsLocked() {
19470        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19471
19472        if (mProcessesToGc.size() > 0) {
19473            // Schedule a GC for the time to the next process.
19474            ProcessRecord proc = mProcessesToGc.get(0);
19475            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19476
19477            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19478            long now = SystemClock.uptimeMillis();
19479            if (when < (now+GC_TIMEOUT)) {
19480                when = now + GC_TIMEOUT;
19481            }
19482            mHandler.sendMessageAtTime(msg, when);
19483        }
19484    }
19485
19486    /**
19487     * Add a process to the array of processes waiting to be GCed.  Keeps the
19488     * list in sorted order by the last GC time.  The process can't already be
19489     * on the list.
19490     */
19491    final void addProcessToGcListLocked(ProcessRecord proc) {
19492        boolean added = false;
19493        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19494            if (mProcessesToGc.get(i).lastRequestedGc <
19495                    proc.lastRequestedGc) {
19496                added = true;
19497                mProcessesToGc.add(i+1, proc);
19498                break;
19499            }
19500        }
19501        if (!added) {
19502            mProcessesToGc.add(0, proc);
19503        }
19504    }
19505
19506    /**
19507     * Set up to ask a process to GC itself.  This will either do it
19508     * immediately, or put it on the list of processes to gc the next
19509     * time things are idle.
19510     */
19511    final void scheduleAppGcLocked(ProcessRecord app) {
19512        long now = SystemClock.uptimeMillis();
19513        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19514            return;
19515        }
19516        if (!mProcessesToGc.contains(app)) {
19517            addProcessToGcListLocked(app);
19518            scheduleAppGcsLocked();
19519        }
19520    }
19521
19522    final void checkExcessivePowerUsageLocked(boolean doKills) {
19523        updateCpuStatsNow();
19524
19525        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19526        boolean doWakeKills = doKills;
19527        boolean doCpuKills = doKills;
19528        if (mLastPowerCheckRealtime == 0) {
19529            doWakeKills = false;
19530        }
19531        if (mLastPowerCheckUptime == 0) {
19532            doCpuKills = false;
19533        }
19534        if (stats.isScreenOn()) {
19535            doWakeKills = false;
19536        }
19537        final long curRealtime = SystemClock.elapsedRealtime();
19538        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19539        final long curUptime = SystemClock.uptimeMillis();
19540        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19541        mLastPowerCheckRealtime = curRealtime;
19542        mLastPowerCheckUptime = curUptime;
19543        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19544            doWakeKills = false;
19545        }
19546        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19547            doCpuKills = false;
19548        }
19549        int i = mLruProcesses.size();
19550        while (i > 0) {
19551            i--;
19552            ProcessRecord app = mLruProcesses.get(i);
19553            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19554                long wtime;
19555                synchronized (stats) {
19556                    wtime = stats.getProcessWakeTime(app.info.uid,
19557                            app.pid, curRealtime);
19558                }
19559                long wtimeUsed = wtime - app.lastWakeTime;
19560                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19561                if (DEBUG_POWER) {
19562                    StringBuilder sb = new StringBuilder(128);
19563                    sb.append("Wake for ");
19564                    app.toShortString(sb);
19565                    sb.append(": over ");
19566                    TimeUtils.formatDuration(realtimeSince, sb);
19567                    sb.append(" used ");
19568                    TimeUtils.formatDuration(wtimeUsed, sb);
19569                    sb.append(" (");
19570                    sb.append((wtimeUsed*100)/realtimeSince);
19571                    sb.append("%)");
19572                    Slog.i(TAG_POWER, sb.toString());
19573                    sb.setLength(0);
19574                    sb.append("CPU for ");
19575                    app.toShortString(sb);
19576                    sb.append(": over ");
19577                    TimeUtils.formatDuration(uptimeSince, sb);
19578                    sb.append(" used ");
19579                    TimeUtils.formatDuration(cputimeUsed, sb);
19580                    sb.append(" (");
19581                    sb.append((cputimeUsed*100)/uptimeSince);
19582                    sb.append("%)");
19583                    Slog.i(TAG_POWER, sb.toString());
19584                }
19585                // If a process has held a wake lock for more
19586                // than 50% of the time during this period,
19587                // that sounds bad.  Kill!
19588                if (doWakeKills && realtimeSince > 0
19589                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19590                    synchronized (stats) {
19591                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19592                                realtimeSince, wtimeUsed);
19593                    }
19594                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19595                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19596                } else if (doCpuKills && uptimeSince > 0
19597                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19598                    synchronized (stats) {
19599                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19600                                uptimeSince, cputimeUsed);
19601                    }
19602                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19603                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19604                } else {
19605                    app.lastWakeTime = wtime;
19606                    app.lastCpuTime = app.curCpuTime;
19607                }
19608            }
19609        }
19610    }
19611
19612    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19613            long nowElapsed) {
19614        boolean success = true;
19615
19616        if (app.curRawAdj != app.setRawAdj) {
19617            app.setRawAdj = app.curRawAdj;
19618        }
19619
19620        int changes = 0;
19621
19622        if (app.curAdj != app.setAdj) {
19623            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19624            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19625                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19626                    + app.adjType);
19627            app.setAdj = app.curAdj;
19628        }
19629
19630        if (app.setSchedGroup != app.curSchedGroup) {
19631            app.setSchedGroup = app.curSchedGroup;
19632            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19633                    "Setting process group of " + app.processName
19634                    + " to " + app.curSchedGroup);
19635            if (app.waitingToKill != null && app.curReceiver == null
19636                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19637                app.kill(app.waitingToKill, true);
19638                success = false;
19639            } else {
19640                if (true) {
19641                    long oldId = Binder.clearCallingIdentity();
19642                    try {
19643                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19644                    } catch (Exception e) {
19645                        Slog.w(TAG, "Failed setting process group of " + app.pid
19646                                + " to " + app.curSchedGroup);
19647                        e.printStackTrace();
19648                    } finally {
19649                        Binder.restoreCallingIdentity(oldId);
19650                    }
19651                } else {
19652                    if (app.thread != null) {
19653                        try {
19654                            app.thread.setSchedulingGroup(app.curSchedGroup);
19655                        } catch (RemoteException e) {
19656                        }
19657                    }
19658                }
19659            }
19660        }
19661        if (app.repForegroundActivities != app.foregroundActivities) {
19662            app.repForegroundActivities = app.foregroundActivities;
19663            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19664        }
19665        if (app.repProcState != app.curProcState) {
19666            app.repProcState = app.curProcState;
19667            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19668            if (app.thread != null) {
19669                try {
19670                    if (false) {
19671                        //RuntimeException h = new RuntimeException("here");
19672                        Slog.i(TAG, "Sending new process state " + app.repProcState
19673                                + " to " + app /*, h*/);
19674                    }
19675                    app.thread.setProcessState(app.repProcState);
19676                } catch (RemoteException e) {
19677                }
19678            }
19679        }
19680        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19681                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19682            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19683                // Experimental code to more aggressively collect pss while
19684                // running test...  the problem is that this tends to collect
19685                // the data right when a process is transitioning between process
19686                // states, which well tend to give noisy data.
19687                long start = SystemClock.uptimeMillis();
19688                long pss = Debug.getPss(app.pid, mTmpLong, null);
19689                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19690                mPendingPssProcesses.remove(app);
19691                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19692                        + " to " + app.curProcState + ": "
19693                        + (SystemClock.uptimeMillis()-start) + "ms");
19694            }
19695            app.lastStateTime = now;
19696            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19697                    mTestPssMode, isSleeping(), now);
19698            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19699                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19700                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19701                    + (app.nextPssTime-now) + ": " + app);
19702        } else {
19703            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19704                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19705                    mTestPssMode)))) {
19706                requestPssLocked(app, app.setProcState);
19707                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19708                        mTestPssMode, isSleeping(), now);
19709            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19710                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19711        }
19712        if (app.setProcState != app.curProcState) {
19713            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19714                    "Proc state change of " + app.processName
19715                            + " to " + app.curProcState);
19716            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19717            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19718            if (setImportant && !curImportant) {
19719                // This app is no longer something we consider important enough to allow to
19720                // use arbitrary amounts of battery power.  Note
19721                // its current wake lock time to later know to kill it if
19722                // it is not behaving well.
19723                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19724                synchronized (stats) {
19725                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19726                            app.pid, nowElapsed);
19727                }
19728                app.lastCpuTime = app.curCpuTime;
19729
19730            }
19731            // Inform UsageStats of important process state change
19732            // Must be called before updating setProcState
19733            maybeUpdateUsageStatsLocked(app, nowElapsed);
19734
19735            app.setProcState = app.curProcState;
19736            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19737                app.notCachedSinceIdle = false;
19738            }
19739            if (!doingAll) {
19740                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19741            } else {
19742                app.procStateChanged = true;
19743            }
19744        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19745                > USAGE_STATS_INTERACTION_INTERVAL) {
19746            // For apps that sit around for a long time in the interactive state, we need
19747            // to report this at least once a day so they don't go idle.
19748            maybeUpdateUsageStatsLocked(app, nowElapsed);
19749        }
19750
19751        if (changes != 0) {
19752            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19753                    "Changes in " + app + ": " + changes);
19754            int i = mPendingProcessChanges.size()-1;
19755            ProcessChangeItem item = null;
19756            while (i >= 0) {
19757                item = mPendingProcessChanges.get(i);
19758                if (item.pid == app.pid) {
19759                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19760                            "Re-using existing item: " + item);
19761                    break;
19762                }
19763                i--;
19764            }
19765            if (i < 0) {
19766                // No existing item in pending changes; need a new one.
19767                final int NA = mAvailProcessChanges.size();
19768                if (NA > 0) {
19769                    item = mAvailProcessChanges.remove(NA-1);
19770                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19771                            "Retrieving available item: " + item);
19772                } else {
19773                    item = new ProcessChangeItem();
19774                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19775                            "Allocating new item: " + item);
19776                }
19777                item.changes = 0;
19778                item.pid = app.pid;
19779                item.uid = app.info.uid;
19780                if (mPendingProcessChanges.size() == 0) {
19781                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19782                            "*** Enqueueing dispatch processes changed!");
19783                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19784                }
19785                mPendingProcessChanges.add(item);
19786            }
19787            item.changes |= changes;
19788            item.processState = app.repProcState;
19789            item.foregroundActivities = app.repForegroundActivities;
19790            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19791                    "Item " + Integer.toHexString(System.identityHashCode(item))
19792                    + " " + app.toShortString() + ": changes=" + item.changes
19793                    + " procState=" + item.processState
19794                    + " foreground=" + item.foregroundActivities
19795                    + " type=" + app.adjType + " source=" + app.adjSource
19796                    + " target=" + app.adjTarget);
19797        }
19798
19799        return success;
19800    }
19801
19802    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19803        final UidRecord.ChangeItem pendingChange;
19804        if (uidRec == null || uidRec.pendingChange == null) {
19805            if (mPendingUidChanges.size() == 0) {
19806                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19807                        "*** Enqueueing dispatch uid changed!");
19808                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19809            }
19810            final int NA = mAvailUidChanges.size();
19811            if (NA > 0) {
19812                pendingChange = mAvailUidChanges.remove(NA-1);
19813                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19814                        "Retrieving available item: " + pendingChange);
19815            } else {
19816                pendingChange = new UidRecord.ChangeItem();
19817                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19818                        "Allocating new item: " + pendingChange);
19819            }
19820            if (uidRec != null) {
19821                uidRec.pendingChange = pendingChange;
19822                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19823                    // If this uid is going away, and we haven't yet reported it is gone,
19824                    // then do so now.
19825                    change = UidRecord.CHANGE_GONE_IDLE;
19826                }
19827            } else if (uid < 0) {
19828                throw new IllegalArgumentException("No UidRecord or uid");
19829            }
19830            pendingChange.uidRecord = uidRec;
19831            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19832            mPendingUidChanges.add(pendingChange);
19833        } else {
19834            pendingChange = uidRec.pendingChange;
19835            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19836                change = UidRecord.CHANGE_GONE_IDLE;
19837            }
19838        }
19839        pendingChange.change = change;
19840        pendingChange.processState = uidRec != null
19841                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19842    }
19843
19844    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19845            String authority) {
19846        if (app == null) return;
19847        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19848            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19849            if (userState == null) return;
19850            final long now = SystemClock.elapsedRealtime();
19851            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19852            if (lastReported == null || lastReported < now - 60 * 1000L) {
19853                mUsageStatsService.reportContentProviderUsage(
19854                        authority, providerPkgName, app.userId);
19855                userState.mProviderLastReportedFg.put(authority, now);
19856            }
19857        }
19858    }
19859
19860    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19861        if (DEBUG_USAGE_STATS) {
19862            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19863                    + "] state changes: old = " + app.setProcState + ", new = "
19864                    + app.curProcState);
19865        }
19866        if (mUsageStatsService == null) {
19867            return;
19868        }
19869        boolean isInteraction;
19870        // To avoid some abuse patterns, we are going to be careful about what we consider
19871        // to be an app interaction.  Being the top activity doesn't count while the display
19872        // is sleeping, nor do short foreground services.
19873        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19874            isInteraction = true;
19875            app.fgInteractionTime = 0;
19876        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19877            if (app.fgInteractionTime == 0) {
19878                app.fgInteractionTime = nowElapsed;
19879                isInteraction = false;
19880            } else {
19881                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19882            }
19883        } else {
19884            isInteraction = app.curProcState
19885                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19886            app.fgInteractionTime = 0;
19887        }
19888        if (isInteraction && (!app.reportedInteraction
19889                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19890            app.interactionEventTime = nowElapsed;
19891            String[] packages = app.getPackageList();
19892            if (packages != null) {
19893                for (int i = 0; i < packages.length; i++) {
19894                    mUsageStatsService.reportEvent(packages[i], app.userId,
19895                            UsageEvents.Event.SYSTEM_INTERACTION);
19896                }
19897            }
19898        }
19899        app.reportedInteraction = isInteraction;
19900        if (!isInteraction) {
19901            app.interactionEventTime = 0;
19902        }
19903    }
19904
19905    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19906        if (proc.thread != null) {
19907            if (proc.baseProcessTracker != null) {
19908                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19909            }
19910        }
19911    }
19912
19913    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19914            ProcessRecord TOP_APP, boolean doingAll, long now) {
19915        if (app.thread == null) {
19916            return false;
19917        }
19918
19919        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19920
19921        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19922    }
19923
19924    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19925            boolean oomAdj) {
19926        if (isForeground != proc.foregroundServices) {
19927            proc.foregroundServices = isForeground;
19928            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19929                    proc.info.uid);
19930            if (isForeground) {
19931                if (curProcs == null) {
19932                    curProcs = new ArrayList<ProcessRecord>();
19933                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19934                }
19935                if (!curProcs.contains(proc)) {
19936                    curProcs.add(proc);
19937                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19938                            proc.info.packageName, proc.info.uid);
19939                }
19940            } else {
19941                if (curProcs != null) {
19942                    if (curProcs.remove(proc)) {
19943                        mBatteryStatsService.noteEvent(
19944                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19945                                proc.info.packageName, proc.info.uid);
19946                        if (curProcs.size() <= 0) {
19947                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19948                        }
19949                    }
19950                }
19951            }
19952            if (oomAdj) {
19953                updateOomAdjLocked();
19954            }
19955        }
19956    }
19957
19958    private final ActivityRecord resumedAppLocked() {
19959        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19960        String pkg;
19961        int uid;
19962        if (act != null) {
19963            pkg = act.packageName;
19964            uid = act.info.applicationInfo.uid;
19965        } else {
19966            pkg = null;
19967            uid = -1;
19968        }
19969        // Has the UID or resumed package name changed?
19970        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19971                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19972            if (mCurResumedPackage != null) {
19973                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19974                        mCurResumedPackage, mCurResumedUid);
19975            }
19976            mCurResumedPackage = pkg;
19977            mCurResumedUid = uid;
19978            if (mCurResumedPackage != null) {
19979                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19980                        mCurResumedPackage, mCurResumedUid);
19981            }
19982        }
19983        return act;
19984    }
19985
19986    final boolean updateOomAdjLocked(ProcessRecord app) {
19987        final ActivityRecord TOP_ACT = resumedAppLocked();
19988        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19989        final boolean wasCached = app.cached;
19990
19991        mAdjSeq++;
19992
19993        // This is the desired cached adjusment we want to tell it to use.
19994        // If our app is currently cached, we know it, and that is it.  Otherwise,
19995        // we don't know it yet, and it needs to now be cached we will then
19996        // need to do a complete oom adj.
19997        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19998                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19999        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20000                SystemClock.uptimeMillis());
20001        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20002            // Changed to/from cached state, so apps after it in the LRU
20003            // list may also be changed.
20004            updateOomAdjLocked();
20005        }
20006        return success;
20007    }
20008
20009    final void updateOomAdjLocked() {
20010        final ActivityRecord TOP_ACT = resumedAppLocked();
20011        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20012        final long now = SystemClock.uptimeMillis();
20013        final long nowElapsed = SystemClock.elapsedRealtime();
20014        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20015        final int N = mLruProcesses.size();
20016
20017        if (false) {
20018            RuntimeException e = new RuntimeException();
20019            e.fillInStackTrace();
20020            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20021        }
20022
20023        // Reset state in all uid records.
20024        for (int i=mActiveUids.size()-1; i>=0; i--) {
20025            final UidRecord uidRec = mActiveUids.valueAt(i);
20026            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20027                    "Starting update of " + uidRec);
20028            uidRec.reset();
20029        }
20030
20031        mStackSupervisor.rankTaskLayersIfNeeded();
20032
20033        mAdjSeq++;
20034        mNewNumServiceProcs = 0;
20035        mNewNumAServiceProcs = 0;
20036
20037        final int emptyProcessLimit;
20038        final int cachedProcessLimit;
20039        if (mProcessLimit <= 0) {
20040            emptyProcessLimit = cachedProcessLimit = 0;
20041        } else if (mProcessLimit == 1) {
20042            emptyProcessLimit = 1;
20043            cachedProcessLimit = 0;
20044        } else {
20045            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20046            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20047        }
20048
20049        // Let's determine how many processes we have running vs.
20050        // how many slots we have for background processes; we may want
20051        // to put multiple processes in a slot of there are enough of
20052        // them.
20053        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20054                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20055        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20056        if (numEmptyProcs > cachedProcessLimit) {
20057            // If there are more empty processes than our limit on cached
20058            // processes, then use the cached process limit for the factor.
20059            // This ensures that the really old empty processes get pushed
20060            // down to the bottom, so if we are running low on memory we will
20061            // have a better chance at keeping around more cached processes
20062            // instead of a gazillion empty processes.
20063            numEmptyProcs = cachedProcessLimit;
20064        }
20065        int emptyFactor = numEmptyProcs/numSlots;
20066        if (emptyFactor < 1) emptyFactor = 1;
20067        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20068        if (cachedFactor < 1) cachedFactor = 1;
20069        int stepCached = 0;
20070        int stepEmpty = 0;
20071        int numCached = 0;
20072        int numEmpty = 0;
20073        int numTrimming = 0;
20074
20075        mNumNonCachedProcs = 0;
20076        mNumCachedHiddenProcs = 0;
20077
20078        // First update the OOM adjustment for each of the
20079        // application processes based on their current state.
20080        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20081        int nextCachedAdj = curCachedAdj+1;
20082        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20083        int nextEmptyAdj = curEmptyAdj+2;
20084        for (int i=N-1; i>=0; i--) {
20085            ProcessRecord app = mLruProcesses.get(i);
20086            if (!app.killedByAm && app.thread != null) {
20087                app.procStateChanged = false;
20088                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20089
20090                // If we haven't yet assigned the final cached adj
20091                // to the process, do that now.
20092                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20093                    switch (app.curProcState) {
20094                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20095                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20096                            // This process is a cached process holding activities...
20097                            // assign it the next cached value for that type, and then
20098                            // step that cached level.
20099                            app.curRawAdj = curCachedAdj;
20100                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20101                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20102                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20103                                    + ")");
20104                            if (curCachedAdj != nextCachedAdj) {
20105                                stepCached++;
20106                                if (stepCached >= cachedFactor) {
20107                                    stepCached = 0;
20108                                    curCachedAdj = nextCachedAdj;
20109                                    nextCachedAdj += 2;
20110                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20111                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20112                                    }
20113                                }
20114                            }
20115                            break;
20116                        default:
20117                            // For everything else, assign next empty cached process
20118                            // level and bump that up.  Note that this means that
20119                            // long-running services that have dropped down to the
20120                            // cached level will be treated as empty (since their process
20121                            // state is still as a service), which is what we want.
20122                            app.curRawAdj = curEmptyAdj;
20123                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20124                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20125                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20126                                    + ")");
20127                            if (curEmptyAdj != nextEmptyAdj) {
20128                                stepEmpty++;
20129                                if (stepEmpty >= emptyFactor) {
20130                                    stepEmpty = 0;
20131                                    curEmptyAdj = nextEmptyAdj;
20132                                    nextEmptyAdj += 2;
20133                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20134                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20135                                    }
20136                                }
20137                            }
20138                            break;
20139                    }
20140                }
20141
20142                applyOomAdjLocked(app, true, now, nowElapsed);
20143
20144                // Count the number of process types.
20145                switch (app.curProcState) {
20146                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20147                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20148                        mNumCachedHiddenProcs++;
20149                        numCached++;
20150                        if (numCached > cachedProcessLimit) {
20151                            app.kill("cached #" + numCached, true);
20152                        }
20153                        break;
20154                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20155                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20156                                && app.lastActivityTime < oldTime) {
20157                            app.kill("empty for "
20158                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20159                                    / 1000) + "s", true);
20160                        } else {
20161                            numEmpty++;
20162                            if (numEmpty > emptyProcessLimit) {
20163                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20164                            }
20165                        }
20166                        break;
20167                    default:
20168                        mNumNonCachedProcs++;
20169                        break;
20170                }
20171
20172                if (app.isolated && app.services.size() <= 0) {
20173                    // If this is an isolated process, and there are no
20174                    // services running in it, then the process is no longer
20175                    // needed.  We agressively kill these because we can by
20176                    // definition not re-use the same process again, and it is
20177                    // good to avoid having whatever code was running in them
20178                    // left sitting around after no longer needed.
20179                    app.kill("isolated not needed", true);
20180                } else {
20181                    // Keeping this process, update its uid.
20182                    final UidRecord uidRec = app.uidRecord;
20183                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20184                        uidRec.curProcState = app.curProcState;
20185                    }
20186                }
20187
20188                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20189                        && !app.killedByAm) {
20190                    numTrimming++;
20191                }
20192            }
20193        }
20194
20195        mNumServiceProcs = mNewNumServiceProcs;
20196
20197        // Now determine the memory trimming level of background processes.
20198        // Unfortunately we need to start at the back of the list to do this
20199        // properly.  We only do this if the number of background apps we
20200        // are managing to keep around is less than half the maximum we desire;
20201        // if we are keeping a good number around, we'll let them use whatever
20202        // memory they want.
20203        final int numCachedAndEmpty = numCached + numEmpty;
20204        int memFactor;
20205        if (numCached <= ProcessList.TRIM_CACHED_APPS
20206                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20207            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20208                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20209            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20210                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20211            } else {
20212                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20213            }
20214        } else {
20215            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20216        }
20217        // We always allow the memory level to go up (better).  We only allow it to go
20218        // down if we are in a state where that is allowed, *and* the total number of processes
20219        // has gone down since last time.
20220        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20221                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20222                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20223        if (memFactor > mLastMemoryLevel) {
20224            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20225                memFactor = mLastMemoryLevel;
20226                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20227            }
20228        }
20229        mLastMemoryLevel = memFactor;
20230        mLastNumProcesses = mLruProcesses.size();
20231        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20232        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20233        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20234            if (mLowRamStartTime == 0) {
20235                mLowRamStartTime = now;
20236            }
20237            int step = 0;
20238            int fgTrimLevel;
20239            switch (memFactor) {
20240                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20241                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20242                    break;
20243                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20244                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20245                    break;
20246                default:
20247                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20248                    break;
20249            }
20250            int factor = numTrimming/3;
20251            int minFactor = 2;
20252            if (mHomeProcess != null) minFactor++;
20253            if (mPreviousProcess != null) minFactor++;
20254            if (factor < minFactor) factor = minFactor;
20255            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20256            for (int i=N-1; i>=0; i--) {
20257                ProcessRecord app = mLruProcesses.get(i);
20258                if (allChanged || app.procStateChanged) {
20259                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20260                    app.procStateChanged = false;
20261                }
20262                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20263                        && !app.killedByAm) {
20264                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20265                        try {
20266                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20267                                    "Trimming memory of " + app.processName + " to " + curLevel);
20268                            app.thread.scheduleTrimMemory(curLevel);
20269                        } catch (RemoteException e) {
20270                        }
20271                        if (false) {
20272                            // For now we won't do this; our memory trimming seems
20273                            // to be good enough at this point that destroying
20274                            // activities causes more harm than good.
20275                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20276                                    && app != mHomeProcess && app != mPreviousProcess) {
20277                                // Need to do this on its own message because the stack may not
20278                                // be in a consistent state at this point.
20279                                // For these apps we will also finish their activities
20280                                // to help them free memory.
20281                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20282                            }
20283                        }
20284                    }
20285                    app.trimMemoryLevel = curLevel;
20286                    step++;
20287                    if (step >= factor) {
20288                        step = 0;
20289                        switch (curLevel) {
20290                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20291                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20292                                break;
20293                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20294                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20295                                break;
20296                        }
20297                    }
20298                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20299                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20300                            && app.thread != null) {
20301                        try {
20302                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20303                                    "Trimming memory of heavy-weight " + app.processName
20304                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20305                            app.thread.scheduleTrimMemory(
20306                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20307                        } catch (RemoteException e) {
20308                        }
20309                    }
20310                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20311                } else {
20312                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20313                            || app.systemNoUi) && app.pendingUiClean) {
20314                        // If this application is now in the background and it
20315                        // had done UI, then give it the special trim level to
20316                        // have it free UI resources.
20317                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20318                        if (app.trimMemoryLevel < level && app.thread != null) {
20319                            try {
20320                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20321                                        "Trimming memory of bg-ui " + app.processName
20322                                        + " to " + level);
20323                                app.thread.scheduleTrimMemory(level);
20324                            } catch (RemoteException e) {
20325                            }
20326                        }
20327                        app.pendingUiClean = false;
20328                    }
20329                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20330                        try {
20331                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20332                                    "Trimming memory of fg " + app.processName
20333                                    + " to " + fgTrimLevel);
20334                            app.thread.scheduleTrimMemory(fgTrimLevel);
20335                        } catch (RemoteException e) {
20336                        }
20337                    }
20338                    app.trimMemoryLevel = fgTrimLevel;
20339                }
20340            }
20341        } else {
20342            if (mLowRamStartTime != 0) {
20343                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20344                mLowRamStartTime = 0;
20345            }
20346            for (int i=N-1; i>=0; i--) {
20347                ProcessRecord app = mLruProcesses.get(i);
20348                if (allChanged || app.procStateChanged) {
20349                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20350                    app.procStateChanged = false;
20351                }
20352                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20353                        || app.systemNoUi) && app.pendingUiClean) {
20354                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20355                            && app.thread != null) {
20356                        try {
20357                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20358                                    "Trimming memory of ui hidden " + app.processName
20359                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20360                            app.thread.scheduleTrimMemory(
20361                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20362                        } catch (RemoteException e) {
20363                        }
20364                    }
20365                    app.pendingUiClean = false;
20366                }
20367                app.trimMemoryLevel = 0;
20368            }
20369        }
20370
20371        if (mAlwaysFinishActivities) {
20372            // Need to do this on its own message because the stack may not
20373            // be in a consistent state at this point.
20374            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20375        }
20376
20377        if (allChanged) {
20378            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20379        }
20380
20381        // Update from any uid changes.
20382        for (int i=mActiveUids.size()-1; i>=0; i--) {
20383            final UidRecord uidRec = mActiveUids.valueAt(i);
20384            int uidChange = UidRecord.CHANGE_PROCSTATE;
20385            if (uidRec.setProcState != uidRec.curProcState) {
20386                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20387                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20388                        + " to " + uidRec.curProcState);
20389                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20390                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20391                        uidRec.lastBackgroundTime = nowElapsed;
20392                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20393                            // Note: the background settle time is in elapsed realtime, while
20394                            // the handler time base is uptime.  All this means is that we may
20395                            // stop background uids later than we had intended, but that only
20396                            // happens because the device was sleeping so we are okay anyway.
20397                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20398                        }
20399                    }
20400                } else {
20401                    if (uidRec.idle) {
20402                        uidChange = UidRecord.CHANGE_ACTIVE;
20403                        uidRec.idle = false;
20404                    }
20405                    uidRec.lastBackgroundTime = 0;
20406                }
20407                uidRec.setProcState = uidRec.curProcState;
20408                enqueueUidChangeLocked(uidRec, -1, uidChange);
20409                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20410            }
20411        }
20412
20413        if (mProcessStats.shouldWriteNowLocked(now)) {
20414            mHandler.post(new Runnable() {
20415                @Override public void run() {
20416                    synchronized (ActivityManagerService.this) {
20417                        mProcessStats.writeStateAsyncLocked();
20418                    }
20419                }
20420            });
20421        }
20422
20423        if (DEBUG_OOM_ADJ) {
20424            final long duration = SystemClock.uptimeMillis() - now;
20425            if (false) {
20426                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20427                        new RuntimeException("here").fillInStackTrace());
20428            } else {
20429                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20430            }
20431        }
20432    }
20433
20434    final void idleUids() {
20435        synchronized (this) {
20436            final long nowElapsed = SystemClock.elapsedRealtime();
20437            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20438            long nextTime = 0;
20439            for (int i=mActiveUids.size()-1; i>=0; i--) {
20440                final UidRecord uidRec = mActiveUids.valueAt(i);
20441                final long bgTime = uidRec.lastBackgroundTime;
20442                if (bgTime > 0 && !uidRec.idle) {
20443                    if (bgTime <= maxBgTime) {
20444                        uidRec.idle = true;
20445                        doStopUidLocked(uidRec.uid, uidRec);
20446                    } else {
20447                        if (nextTime == 0 || nextTime > bgTime) {
20448                            nextTime = bgTime;
20449                        }
20450                    }
20451                }
20452            }
20453            if (nextTime > 0) {
20454                mHandler.removeMessages(IDLE_UIDS_MSG);
20455                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20456                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20457            }
20458        }
20459    }
20460
20461    final void runInBackgroundDisabled(int uid) {
20462        synchronized (this) {
20463            UidRecord uidRec = mActiveUids.get(uid);
20464            if (uidRec != null) {
20465                // This uid is actually running...  should it be considered background now?
20466                if (uidRec.idle) {
20467                    doStopUidLocked(uidRec.uid, uidRec);
20468                }
20469            } else {
20470                // This uid isn't actually running...  still send a report about it being "stopped".
20471                doStopUidLocked(uid, null);
20472            }
20473        }
20474    }
20475
20476    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20477        mServices.stopInBackgroundLocked(uid);
20478        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20479    }
20480
20481    final void trimApplications() {
20482        synchronized (this) {
20483            int i;
20484
20485            // First remove any unused application processes whose package
20486            // has been removed.
20487            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20488                final ProcessRecord app = mRemovedProcesses.get(i);
20489                if (app.activities.size() == 0
20490                        && app.curReceiver == null && app.services.size() == 0) {
20491                    Slog.i(
20492                        TAG, "Exiting empty application process "
20493                        + app.processName + " ("
20494                        + (app.thread != null ? app.thread.asBinder() : null)
20495                        + ")\n");
20496                    if (app.pid > 0 && app.pid != MY_PID) {
20497                        app.kill("empty", false);
20498                    } else {
20499                        try {
20500                            app.thread.scheduleExit();
20501                        } catch (Exception e) {
20502                            // Ignore exceptions.
20503                        }
20504                    }
20505                    cleanUpApplicationRecordLocked(app, false, true, -1);
20506                    mRemovedProcesses.remove(i);
20507
20508                    if (app.persistent) {
20509                        addAppLocked(app.info, false, null /* ABI override */);
20510                    }
20511                }
20512            }
20513
20514            // Now update the oom adj for all processes.
20515            updateOomAdjLocked();
20516        }
20517    }
20518
20519    /** This method sends the specified signal to each of the persistent apps */
20520    public void signalPersistentProcesses(int sig) throws RemoteException {
20521        if (sig != Process.SIGNAL_USR1) {
20522            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20523        }
20524
20525        synchronized (this) {
20526            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20527                    != PackageManager.PERMISSION_GRANTED) {
20528                throw new SecurityException("Requires permission "
20529                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20530            }
20531
20532            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20533                ProcessRecord r = mLruProcesses.get(i);
20534                if (r.thread != null && r.persistent) {
20535                    Process.sendSignal(r.pid, sig);
20536                }
20537            }
20538        }
20539    }
20540
20541    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20542        if (proc == null || proc == mProfileProc) {
20543            proc = mProfileProc;
20544            profileType = mProfileType;
20545            clearProfilerLocked();
20546        }
20547        if (proc == null) {
20548            return;
20549        }
20550        try {
20551            proc.thread.profilerControl(false, null, profileType);
20552        } catch (RemoteException e) {
20553            throw new IllegalStateException("Process disappeared");
20554        }
20555    }
20556
20557    private void clearProfilerLocked() {
20558        if (mProfileFd != null) {
20559            try {
20560                mProfileFd.close();
20561            } catch (IOException e) {
20562            }
20563        }
20564        mProfileApp = null;
20565        mProfileProc = null;
20566        mProfileFile = null;
20567        mProfileType = 0;
20568        mAutoStopProfiler = false;
20569        mSamplingInterval = 0;
20570    }
20571
20572    public boolean profileControl(String process, int userId, boolean start,
20573            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20574
20575        try {
20576            synchronized (this) {
20577                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20578                // its own permission.
20579                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20580                        != PackageManager.PERMISSION_GRANTED) {
20581                    throw new SecurityException("Requires permission "
20582                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20583                }
20584
20585                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20586                    throw new IllegalArgumentException("null profile info or fd");
20587                }
20588
20589                ProcessRecord proc = null;
20590                if (process != null) {
20591                    proc = findProcessLocked(process, userId, "profileControl");
20592                }
20593
20594                if (start && (proc == null || proc.thread == null)) {
20595                    throw new IllegalArgumentException("Unknown process: " + process);
20596                }
20597
20598                if (start) {
20599                    stopProfilerLocked(null, 0);
20600                    setProfileApp(proc.info, proc.processName, profilerInfo);
20601                    mProfileProc = proc;
20602                    mProfileType = profileType;
20603                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20604                    try {
20605                        fd = fd.dup();
20606                    } catch (IOException e) {
20607                        fd = null;
20608                    }
20609                    profilerInfo.profileFd = fd;
20610                    proc.thread.profilerControl(start, profilerInfo, profileType);
20611                    fd = null;
20612                    mProfileFd = null;
20613                } else {
20614                    stopProfilerLocked(proc, profileType);
20615                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20616                        try {
20617                            profilerInfo.profileFd.close();
20618                        } catch (IOException e) {
20619                        }
20620                    }
20621                }
20622
20623                return true;
20624            }
20625        } catch (RemoteException e) {
20626            throw new IllegalStateException("Process disappeared");
20627        } finally {
20628            if (profilerInfo != null && profilerInfo.profileFd != null) {
20629                try {
20630                    profilerInfo.profileFd.close();
20631                } catch (IOException e) {
20632                }
20633            }
20634        }
20635    }
20636
20637    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20638        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20639                userId, true, ALLOW_FULL_ONLY, callName, null);
20640        ProcessRecord proc = null;
20641        try {
20642            int pid = Integer.parseInt(process);
20643            synchronized (mPidsSelfLocked) {
20644                proc = mPidsSelfLocked.get(pid);
20645            }
20646        } catch (NumberFormatException e) {
20647        }
20648
20649        if (proc == null) {
20650            ArrayMap<String, SparseArray<ProcessRecord>> all
20651                    = mProcessNames.getMap();
20652            SparseArray<ProcessRecord> procs = all.get(process);
20653            if (procs != null && procs.size() > 0) {
20654                proc = procs.valueAt(0);
20655                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20656                    for (int i=1; i<procs.size(); i++) {
20657                        ProcessRecord thisProc = procs.valueAt(i);
20658                        if (thisProc.userId == userId) {
20659                            proc = thisProc;
20660                            break;
20661                        }
20662                    }
20663                }
20664            }
20665        }
20666
20667        return proc;
20668    }
20669
20670    public boolean dumpHeap(String process, int userId, boolean managed,
20671            String path, ParcelFileDescriptor fd) throws RemoteException {
20672
20673        try {
20674            synchronized (this) {
20675                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20676                // its own permission (same as profileControl).
20677                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20678                        != PackageManager.PERMISSION_GRANTED) {
20679                    throw new SecurityException("Requires permission "
20680                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20681                }
20682
20683                if (fd == null) {
20684                    throw new IllegalArgumentException("null fd");
20685                }
20686
20687                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20688                if (proc == null || proc.thread == null) {
20689                    throw new IllegalArgumentException("Unknown process: " + process);
20690                }
20691
20692                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20693                if (!isDebuggable) {
20694                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20695                        throw new SecurityException("Process not debuggable: " + proc);
20696                    }
20697                }
20698
20699                proc.thread.dumpHeap(managed, path, fd);
20700                fd = null;
20701                return true;
20702            }
20703        } catch (RemoteException e) {
20704            throw new IllegalStateException("Process disappeared");
20705        } finally {
20706            if (fd != null) {
20707                try {
20708                    fd.close();
20709                } catch (IOException e) {
20710                }
20711            }
20712        }
20713    }
20714
20715    @Override
20716    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20717            String reportPackage) {
20718        if (processName != null) {
20719            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20720                    "setDumpHeapDebugLimit()");
20721        } else {
20722            synchronized (mPidsSelfLocked) {
20723                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20724                if (proc == null) {
20725                    throw new SecurityException("No process found for calling pid "
20726                            + Binder.getCallingPid());
20727                }
20728                if (!Build.IS_DEBUGGABLE
20729                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20730                    throw new SecurityException("Not running a debuggable build");
20731                }
20732                processName = proc.processName;
20733                uid = proc.uid;
20734                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20735                    throw new SecurityException("Package " + reportPackage + " is not running in "
20736                            + proc);
20737                }
20738            }
20739        }
20740        synchronized (this) {
20741            if (maxMemSize > 0) {
20742                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20743            } else {
20744                if (uid != 0) {
20745                    mMemWatchProcesses.remove(processName, uid);
20746                } else {
20747                    mMemWatchProcesses.getMap().remove(processName);
20748                }
20749            }
20750        }
20751    }
20752
20753    @Override
20754    public void dumpHeapFinished(String path) {
20755        synchronized (this) {
20756            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20757                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20758                        + " does not match last pid " + mMemWatchDumpPid);
20759                return;
20760            }
20761            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20762                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20763                        + " does not match last path " + mMemWatchDumpFile);
20764                return;
20765            }
20766            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20767            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20768        }
20769    }
20770
20771    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20772    public void monitor() {
20773        synchronized (this) { }
20774    }
20775
20776    void onCoreSettingsChange(Bundle settings) {
20777        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20778            ProcessRecord processRecord = mLruProcesses.get(i);
20779            try {
20780                if (processRecord.thread != null) {
20781                    processRecord.thread.setCoreSettings(settings);
20782                }
20783            } catch (RemoteException re) {
20784                /* ignore */
20785            }
20786        }
20787    }
20788
20789    // Multi-user methods
20790
20791    /**
20792     * Start user, if its not already running, but don't bring it to foreground.
20793     */
20794    @Override
20795    public boolean startUserInBackground(final int userId) {
20796        return mUserController.startUser(userId, /* foreground */ false);
20797    }
20798
20799    @Override
20800    public boolean unlockUser(int userId, byte[] token) {
20801        return mUserController.unlockUser(userId, token);
20802    }
20803
20804    @Override
20805    public boolean switchUser(final int targetUserId) {
20806        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20807        UserInfo currentUserInfo;
20808        UserInfo targetUserInfo;
20809        synchronized (this) {
20810            int currentUserId = mUserController.getCurrentUserIdLocked();
20811            currentUserInfo = mUserController.getUserInfo(currentUserId);
20812            targetUserInfo = mUserController.getUserInfo(targetUserId);
20813            if (targetUserInfo == null) {
20814                Slog.w(TAG, "No user info for user #" + targetUserId);
20815                return false;
20816            }
20817            if (targetUserInfo.isManagedProfile()) {
20818                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20819                return false;
20820            }
20821            mUserController.setTargetUserIdLocked(targetUserId);
20822        }
20823        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20824        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20825        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20826        return true;
20827    }
20828
20829    void scheduleStartProfilesLocked() {
20830        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20831            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20832                    DateUtils.SECOND_IN_MILLIS);
20833        }
20834    }
20835
20836    @Override
20837    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20838        return mUserController.stopUser(userId, force, callback);
20839    }
20840
20841    void onUserRemovedLocked(int userId) {
20842        mRecentTasks.removeTasksForUserLocked(userId);
20843    }
20844
20845    @Override
20846    public UserInfo getCurrentUser() {
20847        return mUserController.getCurrentUser();
20848    }
20849
20850    @Override
20851    public boolean isUserRunning(int userId, int flags) {
20852        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20853                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20854            String msg = "Permission Denial: isUserRunning() from pid="
20855                    + Binder.getCallingPid()
20856                    + ", uid=" + Binder.getCallingUid()
20857                    + " requires " + INTERACT_ACROSS_USERS;
20858            Slog.w(TAG, msg);
20859            throw new SecurityException(msg);
20860        }
20861        synchronized (this) {
20862            return mUserController.isUserRunningLocked(userId, flags);
20863        }
20864    }
20865
20866    @Override
20867    public int[] getRunningUserIds() {
20868        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20869                != PackageManager.PERMISSION_GRANTED) {
20870            String msg = "Permission Denial: isUserRunning() from pid="
20871                    + Binder.getCallingPid()
20872                    + ", uid=" + Binder.getCallingUid()
20873                    + " requires " + INTERACT_ACROSS_USERS;
20874            Slog.w(TAG, msg);
20875            throw new SecurityException(msg);
20876        }
20877        synchronized (this) {
20878            return mUserController.getStartedUserArrayLocked();
20879        }
20880    }
20881
20882    @Override
20883    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20884        mUserController.registerUserSwitchObserver(observer);
20885    }
20886
20887    @Override
20888    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20889        mUserController.unregisterUserSwitchObserver(observer);
20890    }
20891
20892    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20893        if (info == null) return null;
20894        ApplicationInfo newInfo = new ApplicationInfo(info);
20895        newInfo.initForUser(userId);
20896        return newInfo;
20897    }
20898
20899    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20900        if (aInfo == null
20901                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20902            return aInfo;
20903        }
20904
20905        ActivityInfo info = new ActivityInfo(aInfo);
20906        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20907        return info;
20908    }
20909
20910    private boolean processSanityChecksLocked(ProcessRecord process) {
20911        if (process == null || process.thread == null) {
20912            return false;
20913        }
20914
20915        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20916        if (!isDebuggable) {
20917            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20918                return false;
20919            }
20920        }
20921
20922        return true;
20923    }
20924
20925    public boolean startBinderTracking() throws RemoteException {
20926        synchronized (this) {
20927            mBinderTransactionTrackingEnabled = true;
20928            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20929            // permission (same as profileControl).
20930            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20931                    != PackageManager.PERMISSION_GRANTED) {
20932                throw new SecurityException("Requires permission "
20933                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20934            }
20935
20936            for (int i = 0; i < mLruProcesses.size(); i++) {
20937                ProcessRecord process = mLruProcesses.get(i);
20938                if (!processSanityChecksLocked(process)) {
20939                    continue;
20940                }
20941                try {
20942                    process.thread.startBinderTracking();
20943                } catch (RemoteException e) {
20944                    Log.v(TAG, "Process disappared");
20945                }
20946            }
20947            return true;
20948        }
20949    }
20950
20951    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20952        try {
20953            synchronized (this) {
20954                mBinderTransactionTrackingEnabled = false;
20955                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20956                // permission (same as profileControl).
20957                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20958                        != PackageManager.PERMISSION_GRANTED) {
20959                    throw new SecurityException("Requires permission "
20960                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20961                }
20962
20963                if (fd == null) {
20964                    throw new IllegalArgumentException("null fd");
20965                }
20966
20967                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20968                pw.println("Binder transaction traces for all processes.\n");
20969                for (ProcessRecord process : mLruProcesses) {
20970                    if (!processSanityChecksLocked(process)) {
20971                        continue;
20972                    }
20973
20974                    pw.println("Traces for process: " + process.processName);
20975                    pw.flush();
20976                    try {
20977                        TransferPipe tp = new TransferPipe();
20978                        try {
20979                            process.thread.stopBinderTrackingAndDump(
20980                                    tp.getWriteFd().getFileDescriptor());
20981                            tp.go(fd.getFileDescriptor());
20982                        } finally {
20983                            tp.kill();
20984                        }
20985                    } catch (IOException e) {
20986                        pw.println("Failure while dumping IPC traces from " + process +
20987                                ".  Exception: " + e);
20988                        pw.flush();
20989                    } catch (RemoteException e) {
20990                        pw.println("Got a RemoteException while dumping IPC traces from " +
20991                                process + ".  Exception: " + e);
20992                        pw.flush();
20993                    }
20994                }
20995                fd = null;
20996                return true;
20997            }
20998        } finally {
20999            if (fd != null) {
21000                try {
21001                    fd.close();
21002                } catch (IOException e) {
21003                }
21004            }
21005        }
21006    }
21007
21008    void stopReportingCrashesLocked(ProcessRecord proc) {
21009        if (mAppsNotReportingCrashes == null) {
21010            mAppsNotReportingCrashes = new ArraySet<>();
21011        }
21012        mAppsNotReportingCrashes.add(proc.info.packageName);
21013    }
21014
21015    private final class LocalService extends ActivityManagerInternal {
21016        @Override
21017        public void onWakefulnessChanged(int wakefulness) {
21018            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21019        }
21020
21021        @Override
21022        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21023                String processName, String abiOverride, int uid, Runnable crashHandler) {
21024            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21025                    processName, abiOverride, uid, crashHandler);
21026        }
21027
21028        @Override
21029        public SleepToken acquireSleepToken(String tag) {
21030            Preconditions.checkNotNull(tag);
21031
21032            synchronized (ActivityManagerService.this) {
21033                SleepTokenImpl token = new SleepTokenImpl(tag);
21034                mSleepTokens.add(token);
21035                updateSleepIfNeededLocked();
21036                return token;
21037            }
21038        }
21039
21040        @Override
21041        public ComponentName getHomeActivityForUser(int userId) {
21042            synchronized (ActivityManagerService.this) {
21043                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21044                return homeActivity == null ? null : homeActivity.realActivity;
21045            }
21046        }
21047
21048        @Override
21049        public void onUserRemoved(int userId) {
21050            synchronized (ActivityManagerService.this) {
21051                ActivityManagerService.this.onUserRemovedLocked(userId);
21052            }
21053        }
21054    }
21055
21056    private final class SleepTokenImpl extends SleepToken {
21057        private final String mTag;
21058        private final long mAcquireTime;
21059
21060        public SleepTokenImpl(String tag) {
21061            mTag = tag;
21062            mAcquireTime = SystemClock.uptimeMillis();
21063        }
21064
21065        @Override
21066        public void release() {
21067            synchronized (ActivityManagerService.this) {
21068                if (mSleepTokens.remove(this)) {
21069                    updateSleepIfNeededLocked();
21070                }
21071            }
21072        }
21073
21074        @Override
21075        public String toString() {
21076            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21077        }
21078    }
21079
21080    /**
21081     * An implementation of IAppTask, that allows an app to manage its own tasks via
21082     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21083     * only the process that calls getAppTasks() can call the AppTask methods.
21084     */
21085    class AppTaskImpl extends IAppTask.Stub {
21086        private int mTaskId;
21087        private int mCallingUid;
21088
21089        public AppTaskImpl(int taskId, int callingUid) {
21090            mTaskId = taskId;
21091            mCallingUid = callingUid;
21092        }
21093
21094        private void checkCaller() {
21095            if (mCallingUid != Binder.getCallingUid()) {
21096                throw new SecurityException("Caller " + mCallingUid
21097                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21098            }
21099        }
21100
21101        @Override
21102        public void finishAndRemoveTask() {
21103            checkCaller();
21104
21105            synchronized (ActivityManagerService.this) {
21106                long origId = Binder.clearCallingIdentity();
21107                try {
21108                    // We remove the task from recents to preserve backwards
21109                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21110                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21111                    }
21112                } finally {
21113                    Binder.restoreCallingIdentity(origId);
21114                }
21115            }
21116        }
21117
21118        @Override
21119        public ActivityManager.RecentTaskInfo getTaskInfo() {
21120            checkCaller();
21121
21122            synchronized (ActivityManagerService.this) {
21123                long origId = Binder.clearCallingIdentity();
21124                try {
21125                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21126                    if (tr == null) {
21127                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21128                    }
21129                    return createRecentTaskInfoFromTaskRecord(tr);
21130                } finally {
21131                    Binder.restoreCallingIdentity(origId);
21132                }
21133            }
21134        }
21135
21136        @Override
21137        public void moveToFront() {
21138            checkCaller();
21139            // Will bring task to front if it already has a root activity.
21140            startActivityFromRecentsInner(mTaskId, null);
21141        }
21142
21143        @Override
21144        public int startActivity(IBinder whoThread, String callingPackage,
21145                Intent intent, String resolvedType, Bundle bOptions) {
21146            checkCaller();
21147
21148            int callingUser = UserHandle.getCallingUserId();
21149            TaskRecord tr;
21150            IApplicationThread appThread;
21151            synchronized (ActivityManagerService.this) {
21152                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21153                if (tr == null) {
21154                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21155                }
21156                appThread = ApplicationThreadNative.asInterface(whoThread);
21157                if (appThread == null) {
21158                    throw new IllegalArgumentException("Bad app thread " + appThread);
21159                }
21160            }
21161            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21162                    resolvedType, null, null, null, null, 0, 0, null, null,
21163                    null, bOptions, false, callingUser, null, tr);
21164        }
21165
21166        @Override
21167        public void setExcludeFromRecents(boolean exclude) {
21168            checkCaller();
21169
21170            synchronized (ActivityManagerService.this) {
21171                long origId = Binder.clearCallingIdentity();
21172                try {
21173                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21174                    if (tr == null) {
21175                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21176                    }
21177                    Intent intent = tr.getBaseIntent();
21178                    if (exclude) {
21179                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21180                    } else {
21181                        intent.setFlags(intent.getFlags()
21182                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21183                    }
21184                } finally {
21185                    Binder.restoreCallingIdentity(origId);
21186                }
21187            }
21188        }
21189    }
21190
21191    /**
21192     * Kill processes for the user with id userId and that depend on the package named packageName
21193     */
21194    @Override
21195    public void killPackageDependents(String packageName, int userId) {
21196        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21197        if (packageName == null) {
21198            throw new NullPointerException("Cannot kill the dependents of a package without its name.");
21199        }
21200
21201        long callingId = Binder.clearCallingIdentity();
21202        IPackageManager pm = AppGlobals.getPackageManager();
21203        int pkgUid = -1;
21204        try {
21205            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21206        } catch (RemoteException e) {
21207        }
21208        if (pkgUid == -1) {
21209            throw new IllegalArgumentException("Cannot kill dependents of non-existing package " + packageName);
21210        }
21211        try {
21212            synchronized(this) {
21213                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21214                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, false,
21215                        "dep: " + packageName);
21216            }
21217        } finally {
21218            Binder.restoreCallingIdentity(callingId);
21219        }
21220    }
21221}
21222